kframework / k-legacy

The K tools (deprecated, see README)

Home Page:http://kframework.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"Over matching" behavior of ... in cells with multiplicity="*"

dfava opened this issue · comments

The rewrite rule below will not fire unless the ... between select ... selBranch is the same between both of the goRoutine cells.

In other words, the ... with the comment FIRST needed to match ... with the comment THIRD, and the ... with the comment SECOND needed to match ... with the comment FOURTH.

  rule <goroutine> // Sender
         <id> _ </id>
         <k> selAux(.K) => selClear ~> Ts[$unit/Zs] ... </k>
         <select>
           ...    // FIRST
           <selBranch> (let Zs:Id = channel(Ref:Int) <- V:Val in Ts:Term):LetChan </selBranch>
           ...    // SECOND
         </select>
         <sigma>
           <HB> HMapS:Map => mergeHB( HMapS, HMapR ) </HB>
           <S>  SSetS:Set => SSetS SSetR </S>
         </sigma>
       </goroutine>
       <goroutine> // Receiver
         <id> _ </id>
         <k> selAux(.K) => selClear ~> Tr[V/Zr] ... </k>
         <select>
           ...   // THIRD
           <selBranch> (let Zr:Id = <- channel(Ref:Int) in Tr:Term):LetChan </selBranch>
           ...   // FOURTH
         </select>
         <sigma>
           <HB> HMapR:Map => mergeHB( HMapS, HMapR ) </HB>
           <S>  SSetR:Set => SSetS SSetR </S>
         </sigma>
       </goroutine>
       <chan>
         <ref> Ref:Int </ref>
         <type> _ </type>
         <forward> .List </forward>
         <backward> .List </backward>
       </chan>

The work-around was to change the rewrite rule to the rule below, where the <select> ... ... </select> was removed from the receive's goroutine as follows:

  rule <goroutine> // Sender
         <id> _ </id>
         <k> selAux(.K) => selClear ~> Ts[$unit/Zs] ... </k>
         <select>
           ...
           <selBranch> (let Zs:Id = channel(Ref:Int) <- V:Val in Ts:Term):LetChan </selBranch>
           ...
         </select>
         <sigma>
           <HB> HMapS:Map => mergeHB( HMapS, HMapR ) </HB>
           <S>  SSetS:Set => SSetS SSetR </S>
         </sigma>
       </goroutine>
       <goroutine> // Receiver
         <id> _ </id>
         <k> selAux(.K) => selClear ~> Tr[V/Zr] ... </k>
         <selBranch> (let Zr:Id = <- channel(Ref:Int) in Tr:Term):LetChan </selBranch>
         <sigma>
           <HB> HMapR:Map => mergeHB( HMapS, HMapR ) </HB>
           <S>  SSetR:Set => SSetS SSetR </S>
         </sigma>
       </goroutine>
       <chan>
         <ref> Ref:Int </ref>
         <type> _ </type>
         <forward> .List </forward>
         <backward> .List </backward>
       </chan>

To reproduce:

git clone https://github.com/dfava/mmgo.git
cd mmgo
git checkout 8e518b71f89b4b2f8f152c56da99a4d17fb31e27
cd src/k/mmgo-dw
kompile mmgo.k
krun ../../mmgo/tests/sel_sel_sync.mmgo
krun ../../mmgo/tests/sel_sel_sync_bizarre.mmgo

The krun ../../mmgo/tests/sel_sel_sync.mmgo shows the bug, and the command krun ../../mmgo/tests/sel_sel_sync_bizarre.mmgo shows how the bug does not manifest if the contents of ... are made to match between the goroutines.

The configuration is in ./mmgo/src/k/mmgo/mmgo-common.k and the rewrite rule in question is the last rewrite rule in the file ./mmgo/src/k/mmgo/mmgo-select.k.

It reproduces on https://github.com/kframework/k.git on the top of the tree; which, at the time of filing the bug corresponds to commit 41dd07936bd92c2b9982e82653aaa23d79f8164c.

Background

In case it is helpful, here is some background about the rewrite rules:
I'm implementing a guarded command language with message passing.

select {
  { let G1 in T1 }
  ...
  { let Gn in Tn }
  { default }
}

The guards Gi try to send or receive a message on/from a channel.
If no guard Gi can fire (perhaps it tries to send on a channel that is full, or receive on a channel that is empty), then the default branch is taken.

I create a selBranch cell inside a select cell for each branch { let Gi in Ti } in the select statement.

The rule I'm implementing is synchronous communication between two threads. The rule reduces by combining 1) a branch of a select statement in one thread and 2) a branch of a select statement in a different thread.