/* IF process returns 0 it's run statement blocked???
    What is the return value of the process??? */

/* Generated from the TRMEvent class */
typedef TRMEvent {
  byte source 
};

/* Generated from the TWEvent class */
typedef TWEvent {
  bool isRequest;
  byte source 
};

typedef TextUpdateEvent {
  byte source
};

/* Generated from the TRM class */
typedef Array {
  bool row[2] = true
};

Array column[2];
bool C[2]=false;
bool T[2]=false;
bool N[2]=true;

/* Generated from TextWriters */
bool notify_1 = false;
bool notify_2 = false;

/* Generated from TextResource (for assertion) */
bool assert_4 =false;

inline receiveTRMEvent_1(ev) {atomic{notify_1=true;}}
inline receiveTRMEvent_2(ev) {atomic{notify_2=true;}}


inline TWEventAction_3(pos, req) {
  if 
    :: (req==true) ->
      atomic {
        assert(N[pos] && !C[pos] && !T[pos]);
        N[pos] = false; T[pos] = true;
        byte ind=2;
        do
          :: (ind==0) -> break;
          :: else -> 
            ind=ind-1;
            if 
              :: (pos!=ind && T[ind]) -> column[pos].row[ind] = false; 
              :: else -> skip;
            fi;  
        od;  
      }
    :: else -> atomic {
       assert(C[pos] && !N[pos] && !T[pos]);
       C[pos] = false; N[pos] = true;
    }
  fi; 
}

inline receiveTWEvent_3(event) {
  if 
    :: (event.source==1) -> TWEventAction_3(0,event.isRequest); 
    :: (event.source==2) -> TWEventAction_3(1,event.isRequest); 
    :: else -> assert(0);
  fi;  
}

/** Generated from the TextResource */
inline receiveTextUpdateEvent_4(ev) {
  assert_4 = !assert_4;
  /* asserts that there is no two concurrent instances of the proctype */
  assert(assert_4); 
  assert_4 = !assert_4;
}


active proctype run_3() {
 TRMEvent event;
 event.source=3;
 byte twid = 0;
 LOOP:
     atomic {
       (!C[0] && !C[1]) ->
         if
           :: (T[0] && (N[1] || column[0].row[1])) -> 
              T[0]=false;C[0]=true; column[1].row[0]=true;
              twid=1;
           :: (T[1] && (N[0] || column[1].row[0])) -> 
              T[1]=false;C[1]=true; column[0].row[1]=true;
              twid=2;
           :: else -> twid=0;
         fi;   
     }  
     if 
       :: (twid==1) -> receiveTRMEvent_1(event);
       :: (twid==2) -> receiveTRMEvent_2(event);
       :: else -> skip;
     fi;  
     goto LOOP
}

/* Generated from TW1 */
active proctype run_1() {
 TWEvent requestEvent,releaseEvent;
 requestEvent.source=1;
 requestEvent.isRequest = true;
 releaseEvent.source=1;
 releaseEvent.isRequest = false;
 TextUpdateEvent textEvent;
 textEvent.source=1;

 LOOP:
     receiveTWEvent_3(requestEvent);
     atomic {(notify_1==true) -> notify_1=false;}
     receiveTextUpdateEvent_4(textEvent);
     receiveTWEvent_3(releaseEvent);
     goto LOOP
}


/* Generated from TW2 */
active proctype run_2() {
 TWEvent requestEvent,releaseEvent;
 requestEvent.source=2;
 requestEvent.isRequest = true;
 releaseEvent.source=2;
 releaseEvent.isRequest = false;
 TextUpdateEvent textEvent;
 textEvent.source=2;

 LOOP:
     receiveTWEvent_3(requestEvent);
     atomic {(notify_2==true) -> notify_2=false;}
     receiveTextUpdateEvent_4(textEvent);
     receiveTWEvent_3(releaseEvent); 
     goto LOOP
}

