#define true 1
#define false 0

chan swapin = [1] of {int};
chan swapout = [1] of {int};

bool ain,bin;

inline swap(in,out,k){
  in!k;
  out?k;
}

proctype A()
{
   int key;

   key = true;
   do
    :: key ->
accept: swap(swapin, swapout, key);
    :: !key -> break;
   od;
progress:
   ain=true;
   assert(bin==false);
   ain=false;
   swap(swapin, swapout, key);
}

proctype B()
{
   int key;

   key = true;
   do
    :: key ->
accept: swap(swapin,swapout,key);
       !key -> break;
   od;
progress:

   bin=true;
   assert(ain==false);
   bin=false;
   swap(swapin,swapout,key);
}

inline klswap(k,l){
  int tmp;
  tmp = k;
  k = l;
  l = tmp;
}

proctype dijkstra(){
int key,lock;

   lock = false;
end:
   do
     :: swapin ? key->
         klswap(key,lock);
         swapout ! key;
   od;
}  

init
{
  atomic{
    run A(); 
    run B();
    run swapproc();
  }
}
