1#include "storm-config.h"
17class SparseDoubleRestartEnvironment {
19 static const bool isExact =
false;
20 typedef double ValueType;
21 typedef storm::models::sparse::Mdp<ValueType> ModelType;
22 static storm::Environment createEnvironment() {
23 storm::Environment env;
31class SparseDoubleBisectionEnvironment {
33 static const bool isExact =
false;
34 typedef double ValueType;
35 typedef storm::models::sparse::Mdp<ValueType> ModelType;
36 static storm::Environment createEnvironment() {
37 storm::Environment env;
43class SparseDoubleBisectionAdvancedEnvironment {
45 static const bool isExact =
false;
46 typedef double ValueType;
47 typedef storm::models::sparse::Mdp<ValueType> ModelType;
48 static storm::Environment createEnvironment() {
49 storm::Environment env;
55class SparseDoubleBisectionPtEnvironment {
57 static const bool isExact =
false;
58 typedef double ValueType;
59 typedef storm::models::sparse::Mdp<ValueType> ModelType;
60 static storm::Environment createEnvironment() {
61 storm::Environment env;
67class SparseDoubleBisectionAdvancedPtEnvironment {
69 static const bool isExact =
false;
70 typedef double ValueType;
71 typedef storm::models::sparse::Mdp<ValueType> ModelType;
72 static storm::Environment createEnvironment() {
73 storm::Environment env;
79class SparseDoublePiEnvironment {
81 static const bool isExact =
false;
82 typedef double ValueType;
83 typedef storm::models::sparse::Mdp<ValueType> ModelType;
84 static storm::Environment createEnvironment() {
85 storm::Environment env;
91class SparseRationalNumberRestartEnvironment {
93 static const bool isExact =
true;
94 typedef storm::RationalNumber ValueType;
95 typedef storm::models::sparse::Mdp<ValueType> ModelType;
96 static storm::Environment createEnvironment() {
97 storm::Environment env;
105class SparseRationalNumberBisectionEnvironment {
107 static const bool isExact =
true;
108 typedef storm::RationalNumber ValueType;
109 typedef storm::models::sparse::Mdp<ValueType> ModelType;
110 static storm::Environment createEnvironment() {
111 storm::Environment env;
117class SparseRationalNumberBisectionAdvancedEnvironment {
119 static const bool isExact =
true;
120 typedef storm::RationalNumber ValueType;
121 typedef storm::models::sparse::Mdp<ValueType> ModelType;
122 static storm::Environment createEnvironment() {
123 storm::Environment env;
129class SparseRationalNumberBisectionPtEnvironment {
131 static const bool isExact =
true;
132 typedef storm::RationalNumber ValueType;
133 typedef storm::models::sparse::Mdp<ValueType> ModelType;
134 static storm::Environment createEnvironment() {
135 storm::Environment env;
141class SparseRationalNumberBisectionAdvancedPtEnvironment {
143 static const bool isExact =
true;
144 typedef storm::RationalNumber ValueType;
145 typedef storm::models::sparse::Mdp<ValueType> ModelType;
146 static storm::Environment createEnvironment() {
147 storm::Environment env;
153class SparseRationalNumberPiEnvironment {
155 static const bool isExact =
true;
156 typedef storm::RationalNumber ValueType;
157 typedef storm::models::sparse::Mdp<ValueType> ModelType;
158 static storm::Environment createEnvironment() {
159 storm::Environment env;
165template<
typename TestType>
166class ConditionalMdpPrctlModelCheckerTest :
public ::testing::Test {
168 typedef typename TestType::ValueType ValueType;
169 typedef typename storm::models::sparse::Mdp<ValueType> SparseModelType;
171 ConditionalMdpPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
173 void SetUp()
override {
175 GTEST_SKIP() <<
"Z3 not available.";
179 storm::Environment
const& env()
const {
182 ValueType
parseNumber(std::string
const& input)
const {
185 ValueType precision()
const {
188 bool isSparseModel()
const {
189 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
192 std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> buildModelFormulas(
193 storm::prism::Program
const& inputProgram, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
194 std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
201 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
202 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
203 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
204 for (
auto const& f : formulas) {
205 result.emplace_back(*f,
true);
211 storm::Environment _environment;
214typedef ::testing::Types<SparseDoubleRestartEnvironment, SparseDoubleBisectionEnvironment, SparseDoubleBisectionAdvancedEnvironment,
215 SparseDoubleBisectionPtEnvironment, SparseDoubleBisectionAdvancedPtEnvironment, SparseDoublePiEnvironment,
216 SparseRationalNumberRestartEnvironment, SparseRationalNumberBisectionEnvironment, SparseRationalNumberBisectionAdvancedEnvironment,
217 SparseRationalNumberBisectionPtEnvironment, SparseRationalNumberBisectionAdvancedPtEnvironment, SparseRationalNumberPiEnvironment>
222TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, two_dice) {
223 typedef typename TestFixture::ValueType
ValueType;
225 std::string
const formulasString =
226 "Pmax=? [F \"twelve\" || F d1=6];"
227 "Pmin=? [F \"twelve\" || F d1=6];"
228 "Pmax=? [F \"seven\" || F d2=4];"
229 "Pmin=? [F \"seven\" || F d2=4];"
230 "Pmax=? [F \"two\" || F d2=2];"
231 "Pmin=? [F \"two\" || F d2=2];"
232 "Pmax=? [F d1=6 || F \"twelve\"];"
233 "Pmin=? [F d1=6 || F \"twelve\"];";
236 auto modelFormulas = this->buildModelFormulas(program, formulasString);
237 auto model = std::move(modelFormulas.first);
238 auto tasks = this->getTasks(modelFormulas.second);
239 EXPECT_EQ(169ul, model->getNumberOfStates());
240 EXPECT_EQ(436ul, model->getNumberOfTransitions());
242 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
245 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
246 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
247 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
248 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
249 result = checker.check(this->env(), tasks[2])->template asExplicitQuantitativeCheckResult<ValueType>();
250 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
251 result = checker.check(this->env(), tasks[3])->template asExplicitQuantitativeCheckResult<ValueType>();
252 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
253 result = checker.check(this->env(), tasks[4])->template asExplicitQuantitativeCheckResult<ValueType>();
254 EXPECT_NEAR(this->
parseNumber(
"0"), result[*mdp->getInitialStates().begin()], this->precision());
255 result = checker.check(this->env(), tasks[5])->template asExplicitQuantitativeCheckResult<ValueType>();
256 EXPECT_NEAR(this->
parseNumber(
"0"), result[*mdp->getInitialStates().begin()], this->precision());
259 if constexpr (!std::is_same_v<TypeParam, SparseDoubleBisectionAdvancedPtEnvironment>) {
260 result = checker.check(this->env(), tasks[6])->template asExplicitQuantitativeCheckResult<ValueType>();
261 EXPECT_NEAR(this->
parseNumber(
"1"), result[*mdp->getInitialStates().begin()], this->precision());
264 result = checker.check(this->env(), tasks[7])->template asExplicitQuantitativeCheckResult<ValueType>();
265 EXPECT_NEAR(this->
parseNumber(
"1"), result[*mdp->getInitialStates().begin()], this->precision());
268TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, consensus) {
269 typedef typename TestFixture::ValueType
ValueType;
271 std::string
const formulasString =
272 "Pmax=? [F \"all_coins_equal_0\" & \"finished\" || F \"agree\" & \"finished\"];"
273 "Pmin=? [F \"all_coins_equal_0\" & \"finished\" || F \"agree\" & \"finished\"];"
274 "Pmax=? [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
275 "Pmin=? [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
276 "P<=560/953 [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
277 "P<562/953 [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
278 "P>393/953 [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
279 "P>=391/953 [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];";
282 auto modelFormulas = this->buildModelFormulas(program, formulasString);
283 auto model = std::move(modelFormulas.first);
284 auto tasks = this->getTasks(modelFormulas.second);
285 EXPECT_EQ(272ul, model->getNumberOfStates());
286 EXPECT_EQ(492ul, model->getNumberOfTransitions());
288 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
291 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
292 EXPECT_NEAR(this->
parseNumber(
"561/953"), result[*mdp->getInitialStates().begin()], this->precision());
293 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
294 EXPECT_NEAR(this->
parseNumber(
"392/953"), result[*mdp->getInitialStates().begin()], this->precision());
295 result = checker.check(this->env(), tasks[2])->template asExplicitQuantitativeCheckResult<ValueType>();
296 EXPECT_NEAR(this->
parseNumber(
"561/953"), result[*mdp->getInitialStates().begin()], this->precision());
297 result = checker.check(this->env(), tasks[3])->template asExplicitQuantitativeCheckResult<ValueType>();
298 EXPECT_NEAR(this->
parseNumber(
"392/953"), result[*mdp->getInitialStates().begin()], this->precision());
299 auto qualResult = checker.check(this->env(), tasks[4])->template asExplicitQualitativeCheckResult<ValueType>();
300 EXPECT_FALSE(qualResult[*mdp->getInitialStates().begin()]);
301 qualResult = checker.check(this->env(), tasks[5])->template asExplicitQualitativeCheckResult<ValueType>();
302 EXPECT_TRUE(qualResult[*mdp->getInitialStates().begin()]);
303 qualResult = checker.check(this->env(), tasks[6])->template asExplicitQualitativeCheckResult<ValueType>();
304 EXPECT_FALSE(qualResult[*mdp->getInitialStates().begin()]);
305 qualResult = checker.check(this->env(), tasks[7])->template asExplicitQualitativeCheckResult<ValueType>();
306 EXPECT_TRUE(qualResult[*mdp->getInitialStates().begin()]);
309TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, simple) {
310 typedef typename TestFixture::ValueType
ValueType;
312 std::string
const programAsString = R
"(mdp
315 [] x=0 -> 0.7 : (x'=1) + 0.3 : (x'=2);
316 [] x=1 -> 1 : (x'=1);
317 [] x=2 -> 1 : (x'=1);
321 std::string const formulasString =
322 "Pmin=? [F x=2 || F x=1];"
323 "Pmax=? [F x=2 || F x=1];";
326 auto modelFormulas = this->buildModelFormulas(program, formulasString);
327 auto model = std::move(modelFormulas.first);
328 auto tasks = this->getTasks(modelFormulas.second);
329 EXPECT_EQ(3ul, model->getNumberOfStates());
330 EXPECT_EQ(4ul, model->getNumberOfTransitions());
332 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
335 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
336 EXPECT_NEAR(this->
parseNumber(
"3/10"), result[*mdp->getInitialStates().begin()], this->precision());
337 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
338 EXPECT_NEAR(this->
parseNumber(
"3/10"), result[*mdp->getInitialStates().begin()], this->precision());
void setAlgorithm(ConditionalAlgorithmSetting value)
void setPrecision(storm::RationalNumber const &value, bool setFromDefault)
ModelCheckerEnvironment & modelchecker()
ConditionalModelCheckerEnvironment & conditional()
static storm::prism::Program parseFromString(std::string const &input, std::string const &filename, bool prismCompatability=false)
Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM synt...
static storm::prism::Program parse(std::string const &filename, bool prismCompatability=false)
Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
std::vector< storm::jani::Property > parsePropertiesForPrismProgram(std::string const &inputString, storm::prism::Program const &program, boost::optional< std::set< std::string > > const &propertyFilter)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
SFTBDDChecker::ValueType ValueType
NumberType parseNumber(std::string const &value)
Parse number from string.
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
TargetType convertNumber(SourceType const &number)
@ BisectionPolicyTracking
@ BisectionAdvancedPolicyTracking
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes