diff --git a/examples/mdp/consensus/coin.pctl b/examples/mdp/consensus/coin.pctl new file mode 100644 index 000000000..52a308559 --- /dev/null +++ b/examples/mdp/consensus/coin.pctl @@ -0,0 +1,20 @@ +// C1 (with probability 1, all N processes finish the protocol) +Pmin=? [ F "finished" ] + +// C2 (minimum probability that the protocol finishes with all coins equal to v) (v=1,2) +// Results are same for v=1 and v=2 by symmetry +// Analytic bound is (K-1)/(2*K) +Pmin=? [ F "finished"&"all_coins_equal_0" ] +Pmin=? [ F "finished"&"all_coins_equal_1" ] + +// Max probability of finishing protocol with coins not all equal +Pmax=? [ F "finished"&!"agree" ] + +// Min/max probability of finishing within k steps +Pmin=? [ F<=k "finished" ] +Pmax=? [ F<=k "finished" ] + +// Min/max expected steps to finish +Rmin=? [ F "finished" ] +Rmax=? [ F "finished" ] + diff --git a/src/storm.cpp b/src/storm.cpp index 42de54751..6714e7930 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -360,6 +360,75 @@ void testCheckingAsynchLeader(storm::models::Mdp& mdp) { delete mc; } +void testCheckingConsensus(storm::models::Mdp& mdp) { + storm::formula::Ap* finishedFormula = new storm::formula::Ap("finished"); + storm::formula::Eventually* eventuallyFormula = new storm::formula::Eventually(finishedFormula); + storm::formula::ProbabilisticNoBoundOperator* probFormula = new storm::formula::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + storm::modelChecker::GmmxxMdpPrctlModelChecker* mc = new storm::modelChecker::GmmxxMdpPrctlModelChecker(mdp); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + storm::formula::Ap* allCoinsEqual0Formula = new storm::formula::Ap("all_coins_equal_0"); + storm::formula::And* conjunctionFormula = new storm::formula::And(finishedFormula, allCoinsEqual0Formula); + eventuallyFormula = new storm::formula::Eventually(conjunctionFormula); + probFormula = new storm::formula::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + storm::formula::Ap* allCoinsEqual1Formula = new storm::formula::Ap("all_coins_equal_1"); + conjunctionFormula = new storm::formula::And(finishedFormula, allCoinsEqual1Formula); + eventuallyFormula = new storm::formula::Eventually(conjunctionFormula); + probFormula = new storm::formula::ProbabilisticNoBoundOperator(eventuallyFormula, true); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + storm::formula::Ap* agree = new storm::formula::Ap("agree"); + storm::formula::Not* notAgree = new storm::formula::Not(agree); + conjunctionFormula = new storm::formula::And(finishedFormula, notAgree); + eventuallyFormula = new storm::formula::Eventually(conjunctionFormula); + probFormula = new storm::formula::ProbabilisticNoBoundOperator(eventuallyFormula, false); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + storm::formula::BoundedEventually* boundedEventuallyFormula = new storm::formula::BoundedEventually(finishedFormula, 50); + probFormula = new storm::formula::ProbabilisticNoBoundOperator(boundedEventuallyFormula, true); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + boundedEventuallyFormula = new storm::formula::BoundedEventually(finishedFormula, 50); + probFormula = new storm::formula::ProbabilisticNoBoundOperator(boundedEventuallyFormula, false); + + mc->check(*probFormula); + delete probFormula; + + finishedFormula = new storm::formula::Ap("finished"); + storm::formula::ReachabilityReward* reachabilityRewardFormula = new storm::formula::ReachabilityReward(finishedFormula); + storm::formula::RewardNoBoundOperator* rewardFormula = new storm::formula::RewardNoBoundOperator(reachabilityRewardFormula, true); + + mc->check(*rewardFormula); + delete rewardFormula; + + finishedFormula = new storm::formula::Ap("finished"); + reachabilityRewardFormula = new storm::formula::ReachabilityReward(finishedFormula); + rewardFormula = new storm::formula::RewardNoBoundOperator(reachabilityRewardFormula, false); + + mc->check(*rewardFormula); + delete rewardFormula; + + delete mc; +} + /*! * Simple testing procedure. */ @@ -380,6 +449,7 @@ void testChecking() { // testCheckingDice(*mdp); // testCheckingAsynchLeader(*mdp); + // testCheckingConsensus(*mdp); } else { std::cout << "Input is neither a DTMC nor an MDP." << std::endl; }