pomdp
observables
	coin1, coin4, m, s1, s2, s3, s4, guess, correct, agree1, agree2, agree3, agree4
endobservables
const int p1=1;
const int p2=2;
const int p3=3;
const int p4=4;
module master
	
	m : [0..1]; 
	pay : [1..4]; 
	
	
	[] m=0 -> 1/3 : (m'=1) & (pay'=1) + 1/3 : (m'=1) & (pay'=2) + 1/3 : (m'=1) & (pay'=3);
	
	
	
	
	
	
	
	
endmodule
module crypt1
	
	coin1 : [0..2]; 
	s1 : [0..1]; 
	agree1 : [0..1]; 
	
	
	[flip] m=1 & coin1=0 -> 0.5 : (coin1'=1) + 0.5 : (coin1'=2);
	
	
	
	[choose1] s1=0 & coin1>0 & coin2>0 & coin1=coin2 & (pay!=p1) -> (s1'=1) & (agree1'=1);
	[choose1] s1=0 & coin1>0 & coin2>0 & !(coin1=coin2) & (pay!=p1) -> (s1'=1);
	
	[choose1] s1=0 & coin1>0 & coin2>0 & coin1=coin2 & (pay=p1) -> (s1'=1);
	[choose1] s1=0 & coin1>0 & coin2>0 & !(coin1=coin2) & (pay=p1) -> (s1'=1) & (agree1'=1);
	
	[done] s1=1 -> true;
endmodule
module crypt2 =crypt1[coin1=coin2, s1=s2, p1=p2, agree1=agree2, coin2=coin3, choose1=choose2 ] endmodule
module crypt3 =crypt1[coin1=coin3, s1=s3, p1=p3, agree1=agree3, coin2=coin4, choose1=choose3 ] endmodule
module crypt4
	
	coin4 : [0..2];
	s4 : [0..2];
	agree4 : [0..1];
	guess : [0..3];
	correct : [0..1];
	
	
	[flip] m=1 & coin4=0 -> 0.5 : (coin4'=1) + 0.5 : (coin4'=2);
	
	
	
	[choose4] s4=0 & coin4>0 & coin1>0 & coin4=coin1 -> (s4'=1) & (agree4'=1);
	[choose4] s4=0 & coin4>0 & coin1>0 & !(coin4=coin1) -> (s4'=1);
	
	[choose4] s4=0 & coin4>0 & coin1>0 & coin4=coin1 & (pay=p4) -> (s4'=1);
	[choose4] s4=0 & coin4>0 & coin1>0 & !(coin4=coin1) & (pay=p4) -> (s4'=1) & (agree4'=1);
	
	
	[done] s4=1 -> (s4'=2);
	[guess1] s4=2 & guess=0 -> (guess'=1);
	[guess2] s4=2 & guess=0 -> (guess'=2);
	[guess3] s4=2 & guess=0 -> (guess'=3);
	
	
	[check] s4=2 & guess>0 & guess=pay -> (correct'=1);
	[check] s4=2 & guess>0 & !(guess=pay) -> true;
endmodule