/*
* For more details about this example, see
* "Automatic Verification of Real-Time Communicating Systems by Constraint Solving",
* by Wang Yi, Paul Pettersson and Mats Daniels. In Proceedings of the 7th International
* Conference on Formal Description Techniques, pages 223-238, North-Holland. 1994.
*/
const int N = 4; // # trains
typedef int[0,N-1] id_t;
const int P[N] = {1,2,3,4};
broadcast chan appr[N], stop[N], leave[N];
urgent broadcast chan go[N];
clock time;
Trainconst id_t idclock x;SafeStopCrossApprStartGateid_t list[N+1];
int[0,N] len;
id_t f;
// Put an element at the end of the queue
void enqueue(id_t element)
{
int tmp=0;
list[len++] = element;
if (len>0)
{
int i=len-1;
while (i>1 && P[list[i]]<P[list[i-1]])
{
tmp = list[i-1];
list[i-1] = list[i];
list[i] = tmp;
i--;
}
}
}
// 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_t front()
{
return list[0];
}
// Returns the last element of the queue
id_t tail()
{
return list[len - 1];
}StoppingOccFreesystem Train, Gate;
gantt {
Train(i:id_t): Train(i).Safe -> 1,
Train(i).Appr -> 2, Train(i).Stop -> 3, Train(i).Cross -> 4;
}E[ <= 100; 2000](max: sum(i:id_t) Train(i).Stop)
simulate 1 [<=1000] {Train(0).Cross, Train(5).Cross}
simulate 1 [<=1000] {Gate.len}
Pr[<=1000](<> time >= 100 and Gate.len < 3)
simulate 100 [<=1000] {Gate.len} : 1 : (time>=500 and Gate.len<3)
Pr[<=1000](<> time>=100 and Gate.len < 3) <= 0.25
E<> (time<=1000 and time>=100 and Gate.len<5)
Pr[ <= 100](<> Train(0).Cross)
Pr[ <= 100](<> Train(1).Cross)
Pr[ <= 100](<> Train(2).Cross)
Pr[ <= 10000](<> Train(3).Cross)
Pr[ <= 100](<> Train(4).Cross)
Pr[ <= 100](<> Train(5).Cross)
Pr[ <= 100](<> Train(0).Cross and (forall (i : id_t) i != 0 imply Train(i).Stop))
Pr[ <= 100](<> Train(1).Cross and (forall (i : id_t) i != 1 imply Train(i).Stop))
Pr[ <= 100](<> Train(2).Cross and (forall (i : id_t) i != 2 imply Train(i).Stop))
Pr[ <= 100](<> Train(3).Cross and (forall (i : id_t) i != 3 imply Train(i).Stop))
Pr[ <= 100](<> Train(4).Cross and (forall (i : id_t) i != 4 imply Train(i).Stop))
Pr[ <= 100](<> Train(5).Cross and (forall (i : id_t) i != 5 imply Train(i).Stop))
Pr[ <= 100](<> Train(1).Cross and (forall (i : id_t) i != 1 imply Train(i).Stop)) >=
Pr[ <= 100](<> Train(5).Cross and (forall (i : id_t) i != 5 imply Train(i).Stop))
Pr[# <= 20]([] forall (i : id_t) forall (j : id_t) Train(i).Cross && Train(j).Cross imply i == j) >= 0.98
===== Validation Properties:
E<> Gate.Occ
Gate can receive (and store in queue) msg's from approaching trains.
simulate 1 [<=1000] {Gate.len}
E<> Train(0).Cross
Train 0 can reach crossing.
E<> Train(1).Cross
Train 1 can reach crossing.
E<> Train(0).Cross and (forall (i : id_t) i != 0 imply Train(i).Stop)
Train 0 can cross bridge while the other trains are waiting to cross.
A[] forall (i : id_t) forall (j : id_t) Train(i).Cross && Train(j).Cross imply i == j
There is never more than one train crossing the bridge (at
any time instance).
A[] Gate.list[N] == 0
There can never be N elements in the queue (thus the array will not overflow).
Pr[ <= 100](<> Train(0).Cross and (forall (i : id_t) i != 0 imply Train(i).Stop))
===== Liveness Properties:
E[ <= 100; 2000](max: sum(i:id_t) Train(i).Stop)
Train(0).Appr --> Train(0).Cross
Whenever a train approaches the bridge, it will eventually cross.
Train(1).Appr --> Train(1).Cross
Train(2).Appr --> Train(2).Cross
Train(3).Appr --> Train(3).Cross
Train(4).Appr --> Train(4).Cross
Train(5).Appr --> Train(5).Cross