# A predicate to specify the "mutual exclusion" requirement
nProp := {[pc1,pc2,c1,c2,turn]: pc1=5 & pc2=5};

# A predicate characterising the initial state
Theta:={[pc1,pc2,c1,c2,turn]: (pc1=0 & pc2=0 & c1=1 & c2=1 & turn=1)};

# Transition relation encoding dekker's algorithm for mutual exclusion
T:={[pc1,pc2,c1,c2,turn] -> [pc1',pc2',c1',c2',turn']:
  (pc1=0 &           turn'=turn & c1'=0  & pc1'=1 & c2'=c2 & pc2'=pc2) or
  (pc1=1 & c2   =0 & turn'=turn & c1'=c1 & pc1'=2 & c2'=c2 & pc2'=pc2) or
  (pc1=1 & c2   =1 & turn'=turn & c1'=c1 & pc1'=5 & c2'=c2 & pc2'=pc2) or
  (pc1=2 & turn =1 & turn'=turn & c1'=c1 & pc1'=1 & c2'=c2 & pc2'=pc2) or
  (pc1=2 & turn =2 & turn'=turn & c1'=c1 & pc1'=3 & c2'=c2 & pc2'=pc2) or
  (pc1=3 &           turn'=turn & c1'=1  & pc1'=4 & c2'=c2 & pc2'=pc2) or
  (pc1=4 & turn =2 & turn'=turn & c1'=c1 & pc1'=4 & c2'=c2 & pc2'=pc2) or
  (pc1=4 & turn =1 & turn'=turn & c1'=c1 & pc1'=0 & c2'=c2 & pc2'=pc2) or
  (pc1=5 &           turn'=2    & c1'=1  & pc1'=0 & c2'=c2 & pc2'=pc2) or

  (pc2=0 &           turn'=turn & c2'=0  & pc2'=1 & c1'=c1 & pc1'=pc1) or
  (pc2=1 & c1   =0 & turn'=turn & c2'=c2 & pc2'=2 & c1'=c1 & pc1'=pc1) or
  (pc2=1 & c1   =1 & turn'=turn & c2'=c2 & pc2'=5 & c1'=c1 & pc1'=pc1) or
  (pc2=2 & turn =2 & turn'=turn & c2'=c2 & pc2'=1 & c1'=c1 & pc1'=pc1) or
  (pc2=2 & turn =1 & turn'=turn & c2'=c2 & pc2'=3 & c1'=c1 & pc1'=pc1) or
  (pc2=3 &           turn'=turn & c2'=1  & pc2'=4 & c1'=c1 & pc1'=pc1) or
  (pc2=4 & turn =1 & turn'=turn & c2'=c2 & pc2'=4 & c1'=c1 & pc1'=pc1) or
  (pc2=4 & turn =2 & turn'=turn & c2'=c2 & pc2'=0 & c1'=c1 & pc1'=pc1) or
  (pc2=5 &           turn'=1    & c2'=1  & pc2'=0 & c1'=c1 & pc1'=pc1)};

T;
Trans := PairwiseCheck T;
Trans;

# Reach is the set of reachable states; initially set it to Theta
  Reach := Theta;
  Reach;

#1
  Reach := Reach union Trans(Reach);
  Reach;
#2
  Reach := PairwiseCheck (Reach union Trans(Reach));
  Reach;

#3
  Reach := PairwiseCheck(Reach union Trans(Reach));
  Reach;
#4
  Reach := PairwiseCheck(Reach union Trans(Reach));
  Reach;
#5
  Reach := Reach union Trans(Reach);
  Reach;
#6
  Reach := Reach union Trans(Reach);
  Reach;
#7
  Reach := Reach union Trans(Reach);
  Reach;
#8
  Reach := Reach union Trans(Reach);
  Reach;
#9
  Reach := Reach union Trans(Reach);
  Reach;
#10
  Reach := Reach union Trans(Reach);
  Reach;
#11
  Reach := Reach union Trans(Reach);
  Reach;
#12
  Reach := Reach union Trans(Reach);
  Reach;
#13
  Reach := Reach union Trans(Reach);
  Reach;
#14
  Reach := Reach union Trans(Reach);
  Reach;
#15
  Reach := Reach union Trans(Reach);
  Reach;

# Proof that we have hit a fixed point
  Trans(Reach) - Reach;

# Shows that the property is not violated in any reachable state
Reach intersection nProp;

#QED
