You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.1 KiB
100 lines
3.1 KiB
// dining cryptographers
|
|
// gxn 27/01/16
|
|
|
|
// pomdp model
|
|
pomdp
|
|
|
|
// observable variables (for crypt5)
|
|
// the announcements of all cryptographers
|
|
// only its own coin and the coin of its left neighbour
|
|
// if it guesses correctly (this is the target so needs to be observable)
|
|
// also local states of modules this only indicates:
|
|
// - if a cryptographer has announced
|
|
// - if the master has made its choice
|
|
observables
|
|
coin1, coin5, m, s1, s2, s3, s4, s5, guess, correct, agree1, agree2, agree3, agree4, agree5
|
|
endobservables
|
|
|
|
// constants used in renaming
|
|
const int p1=1;
|
|
const int p2=2;
|
|
const int p3=3;
|
|
const int p4=4;
|
|
const int p5=5;
|
|
|
|
module master
|
|
|
|
m : [0..1]; // local state (has chosen who pays)
|
|
pay : [1..4]; // who actually pays
|
|
|
|
// randomly choose who pays
|
|
[] m=0 -> 1/4 : (m'=1) & (pay'=1) + 1/4 : (m'=1) & (pay'=2) + 1/4 : (m'=1) & (pay'=3) + 1/4 : (m'=1) & (pay'=4);
|
|
|
|
// test cases
|
|
//[] m=0 -> (m'=1); // master pays
|
|
//[] m=0 -> (m'=1) & (pay'=1); // crypt 1 pays
|
|
//[] m=0 -> (m'=1) & (pay'=2); // crypt 2 pays
|
|
//[] m=0 -> (m'=1) & (pay'=3); // crypt 3 pays
|
|
//[] m=0 -> (m'=1) & (pay'=4); // crypt 4 pays
|
|
|
|
endmodule
|
|
|
|
module crypt1
|
|
|
|
coin1 : [0..2]; // value of coin
|
|
s1 : [0..1]; // local state (has announced yet)
|
|
agree1 : [0..1]; // agree or not
|
|
|
|
// flip coin and share values
|
|
[flip] m=1 & coin1=0 -> 0.5 : (coin1'=1) + 0.5 : (coin1'=2);
|
|
|
|
// make choice (once relevant coins have been flipped)
|
|
// does not pay
|
|
[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);
|
|
// pays
|
|
[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);
|
|
|
|
// when everyone has announced
|
|
[done] s1=1 -> true;
|
|
|
|
endmodule
|
|
|
|
// construct further cryptographers through renaming
|
|
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 =crypt1[coin1=coin4, s1=s4, p1=p4, agree1=agree4, coin2=coin5, choose1=choose4 ] endmodule
|
|
|
|
// the cryptographer that guesses who pays
|
|
module crypt5
|
|
|
|
coin5 : [0..2];
|
|
s5 : [0..2];
|
|
agree5 : [0..1];
|
|
guess : [0..3];
|
|
correct : [0..1];
|
|
|
|
// flip coin
|
|
[flip] m=1 & coin5=0 -> 0.5 : (coin5'=1) + 0.5 : (coin5'=2);
|
|
|
|
// make choice (once relevant coins have been flipped)
|
|
// assume does not pay
|
|
[choose5] s5=0 & coin5>0 & coin1>0 & coin5=coin1 -> (s5'=1) & (agree5'=1);
|
|
[choose5] s5=0 & coin5>0 & coin1>0 & !(coin5=coin1) -> (s5'=1);
|
|
// pays
|
|
[choose5] s5=0 & coin5>0 & coin1>0 & coin5=coin1 & (pay=p5) -> (s5'=1);
|
|
[choose5] s5=0 & coin5>0 & coin1>0 & !(coin5=coin1) & (pay=p5) -> (s5'=1) & (agree5'=1);
|
|
|
|
// after everyone has announced guess who payed
|
|
[done] s5=1 -> (s5'=2);
|
|
[guess1] s5=2 & guess=0 -> (guess'=1);
|
|
[guess2] s5=2 & guess=0 -> (guess'=2);
|
|
[guess3] s5=2 & guess=0 -> (guess'=3);
|
|
[guess4] s5=2 & guess=0 -> (guess'=4);
|
|
|
|
// check whether guessed correctly
|
|
[check] s5=2 & guess>0 & guess=pay -> (correct'=1);
|
|
[check] s5=2 & guess>0 & !(guess=pay) -> true;
|
|
|
|
endmodule
|