# 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)};

reachingDefs1 := 
	({[0,*,1,*,*]} union {[1,*,0,*,*]} 
		union {[2,*,0,*,*]}
		union {[3,*,0,*,*]}
		union {[4,*,1,*,*]}
		union {[5,*,0,*,*]});
# Transition relation encoding dekker's algorithm for mutual exclusion
T1:= {[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 =1 & turn'=turn & c1'=c1 & pc1'=0 & c2'=c2 & pc2'=pc2) or
  (pc1=5 &           turn'=2    & c1'=1  & pc1'=0 & c2'=c2 & pc2'=pc2)} 
	\ reachingDefs1;

reachingDefs2 := 
	({[*,0,*,1,*]} union {[*,1,*,0,*]} 
		union {[*,2,*,0,*]}
		union {[*,3,*,0,*]}
		union {[*,4,*,1,*]}
		union {[*,5,*,0,*]});
T1;
T2:= {[pc1,pc2,c1,c2,turn] -> [pc1',pc2',c1',c2',turn']:
  (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 =2 & turn'=turn & c2'=c2 & pc2'=0 & c1'=c1 & pc1'=pc1) or
  (pc2=5 &           turn'=1    & c2'=1  & pc2'=0 & c1'=c1 & pc1'=pc1)}
	\ reachingDefs2;
T2;

Trans := Inverse (T1 Union T2);
Trans;

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

#1
  Reach := Reach union Trans(Reach);
  Reach;
#2
  Reach := Reach union Trans(Reach);
  Reach;
#3
  Reach := Reach union Trans(Reach);
  Reach;
#4
  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 Theta;

#QED
