#define true 1
#define false 0
bool lock;
chan Aswapin = [1] of {int,int};
chan Aswapout = [1] of {int,int};
chan Bswapin = [1] of {int,int};
chan Bswapout = [1] of {int,int};

bool ain,bin;

proctype A()
{
   int key;

   key = true;
   do
    :: key ->
accept: Aswapin! key,lock;
         Aswapout ? key,lock;
    :: !key -> break;
   od;
progress:
   ain=true;
   assert(bin==false);
   ain=false;
   lock=false;
}

proctype B()
{
   int key;

   key = true;
   do
    :: key ->
accept: Bswapin ! key,lock;
               Bswapout ? key,lock;
       !key -> break;
   od;
progress:

   bin=true;
   assert(ain==false);
   bin=false;
   lock=false;
}


proctype swap(){
int key;
end:
   do
     :: Aswapin ? key,lock ->
         Aswapout ! lock,key;
     :: Bswapin ? key,lock ->
         Bswapout ! lock,key
   od;
}  

init
{
  lock = false;
  atomic{
    run A(); 
    run B();
    run swap();
  }
}
