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.
157 lines
4.3 KiB
157 lines
4.3 KiB
// Modest version of http://www.prismmodelchecker.org/casestudies/consensus_prism.php
|
|
// Command line: mcsta.exe consensus-6.modest -S Memory --nochainopt --bounded-alg StateElimination -E "K=2"
|
|
|
|
action done;
|
|
|
|
// constants
|
|
const int N = 6;
|
|
const int K = 4;
|
|
const int range = 2 * (K + 1) * N;
|
|
const int counter_init = (K + 1) * N;
|
|
const int left = N;
|
|
const int right = 2 * (K + 1) * N - N;
|
|
|
|
// shared coin
|
|
int(0..range) counter = counter_init;
|
|
reward coin_flips;
|
|
|
|
property C1 = P(<> (fin1 == 1 && fin2 == 1 && fin3 == 1 && fin4 == 1 && fin5 == 1 && fin6 == 1)) >= 1;
|
|
property C2 = Pmin(<> (fin1 == 1 && fin2 == 1 && fin3 == 1 && fin4 == 1 && fin5 == 1 && fin6 == 1 && coin1 == 1 && coin2 == 1 && coin3 == 1 && coin4 == 1 && coin5 == 1 && coin6 == 1));
|
|
|
|
int(0..1) fin1, fin2, fin3, fin4, fin5, fin6;
|
|
int(0..1) coin1, coin2, coin3, coin4, coin5, coin6;
|
|
|
|
process Tourist1()
|
|
{
|
|
process Flip() { palt { :1: {= coin1 = 0, coin_flips++ =} :1: {= coin1 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin1 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin1 == 1 && counter < range) {= counter++, coin1 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin1 = 0, fin1 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin1 = 1, fin1 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist1()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
process Tourist2()
|
|
{
|
|
process Flip() { palt { :1: {= coin2 = 0, coin_flips++ =} :1: {= coin2 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin2 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin2 == 1 && counter < range) {= counter++, coin2 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin2 = 0, fin2 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin2 = 1, fin2 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist2()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
process Tourist3()
|
|
{
|
|
process Flip() { palt { :1: {= coin3 = 0, coin_flips++ =} :1: {= coin3 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin3 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin3 == 1 && counter < range) {= counter++, coin3 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin3 = 0, fin3 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin3 = 1, fin3 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist3()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
process Tourist4()
|
|
{
|
|
process Flip() { palt { :1: {= coin4 = 0, coin_flips++ =} :1: {= coin4 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin4 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin4 == 1 && counter < range) {= counter++, coin4 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin4 = 0, fin4 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin4 = 1, fin4 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist4()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
process Tourist5()
|
|
{
|
|
process Flip() { palt { :1: {= coin5 = 0, coin_flips++ =} :1: {= coin5 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin5 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin5 == 1 && counter < range) {= counter++, coin5 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin5 = 0, fin5 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin5 = 1, fin5 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist5()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
process Tourist6()
|
|
{
|
|
process Flip() { palt { :1: {= coin6 = 0, coin_flips++ =} :1: {= coin6 = 1, coin_flips++ =} }; Write() }
|
|
process Write() {
|
|
alt {
|
|
:: when(coin6 == 0 && counter > 0) {= counter-- =}; Check()
|
|
:: when(coin6 == 1 && counter < range) {= counter++, coin6 = 0 =}; Check()
|
|
}
|
|
}
|
|
process Check() {
|
|
alt {
|
|
:: when(counter <= left) {= coin6 = 0, fin6 = 1 =}; Finished()
|
|
:: when(counter >= right) {= coin6 = 1, fin6 = 1 =}; Finished()
|
|
:: when(counter > left && counter < right) Tourist6()
|
|
}
|
|
}
|
|
process Finished() { done; Finished() }
|
|
|
|
Flip()
|
|
}
|
|
|
|
par {
|
|
:: Tourist1()
|
|
:: Tourist2()
|
|
:: Tourist3()
|
|
:: Tourist4()
|
|
:: Tourist5()
|
|
:: Tourist6()
|
|
}
|