/*
OR - 2019
Adapted by Jovian HERSEMEULE - 2020
*/
const int NAB = 3;
const int NBA = 3;
const int N = 6;
typedef int[0,NAB-1] id_tAB;
typedef int[0,NBA-1] id_tBA;
int ab=0, ba=0;
chan libAB[NAB], libBA[NBA], requestAB[NAB], requestBA[NBA];
urgent chan accesAB[NAB], accesBA[NBA];
TrainBAconst id_tBA idclock x;ABABSafeTrainABconst id_tAB idclock x;SafeABABCTRLid_tAB list[N+1];
int[0,N] len;
// Put an element at the end of the queue
void enqueue(id_tAB element)
{
list[len++] = element;
}
// Remove the front element of the queue
void dequeue()
{
int i = 0;
len -= 1;
while (i < len)
{
list[i] = list[i + 1];
i++;
}
list[i] = 0;
}
// Returns the front element of the queue
id_tAB front()
{
return list[0];
}
// Returns the last element of the queue
id_tAB tail()
{
return list[len - 1];
}FreeOnlyABOnlyBARequestFromBRequestFromAsystem TrainAB, TrainBA, CTRL;
E<> TrainBA(1).BAE<> TrainBA(2).BA
A[] forall (i : id_tBA) forall (j : id_tAB) TrainBA(i).BA && TrainAB(j).AB imply i == j
TrainBA(1).B --> TrainBA(1).BA
A<> TrainBA(1).BA
A[] not deadlockE<> TrainBA(1).BA & TrainBA(2).BA