1#include "storm-config.h"
15class SparseDoubleRestartEnvironment {
17 static const bool isExact =
false;
28class SparseDoubleBisectionEnvironment {
30 static const bool isExact =
false;
40class SparseDoubleBisectionAdvancedEnvironment {
42 static const bool isExact =
false;
52class SparseDoublePiEnvironment {
54 static const bool isExact =
false;
64class SparseRationalNumberRestartEnvironment {
66 static const bool isExact =
true;
77class SparseRationalNumberBisectionEnvironment {
79 static const bool isExact =
true;
89class SparseRationalNumberBisectionAdvancedEnvironment {
91 static const bool isExact =
true;
101class SparseRationalNumberPiEnvironment {
103 static const bool isExact =
true;
113template<
typename TestType>
114class ConditionalMdpPrctlModelCheckerTest :
public ::testing::Test {
116 typedef typename TestType::ValueType
ValueType;
119 ConditionalMdpPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
121 void SetUp()
override {
123 GTEST_SKIP() <<
"Z3 not available.";
131 return storm::utility::convertNumber<ValueType>(input);
136 bool isSparseModel()
const {
137 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
140 std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> buildModelFormulas(
141 storm::prism::Program const& inputProgram, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
142 std::pair<std::shared_ptr<SparseModelType>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
145 result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<SparseModelType>();
149 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
150 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
151 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
152 for (
auto const& f : formulas) {
153 result.emplace_back(*f,
true);
162typedef ::testing::Types<SparseDoubleRestartEnvironment, SparseDoubleBisectionEnvironment, SparseDoubleBisectionAdvancedEnvironment, SparseDoublePiEnvironment,
163 SparseRationalNumberRestartEnvironment, SparseRationalNumberBisectionEnvironment, SparseRationalNumberBisectionAdvancedEnvironment,
164 SparseRationalNumberPiEnvironment>
169TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, two_dice) {
170 typedef typename TestFixture::ValueType
ValueType;
172 std::string
const formulasString =
173 "Pmax=? [F \"twelve\" || F d1=6];"
174 "Pmin=? [F \"twelve\" || F d1=6];"
175 "Pmax=? [F \"seven\" || F d2=4];"
176 "Pmin=? [F \"seven\" || F d2=4];"
177 "Pmax=? [F \"two\" || F d2=2];"
178 "Pmin=? [F \"two\" || F d2=2];"
179 "Pmax=? [F d1=6 || F \"twelve\"];"
180 "Pmin=? [F d1=6 || F \"twelve\"];";
183 auto modelFormulas = this->buildModelFormulas(program, formulasString);
184 auto model = std::move(modelFormulas.first);
185 auto tasks = this->getTasks(modelFormulas.second);
186 EXPECT_EQ(169ul, model->getNumberOfStates());
187 EXPECT_EQ(436ul, model->getNumberOfTransitions());
189 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
192 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
193 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
194 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
195 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
196 result = checker.check(this->env(), tasks[2])->template asExplicitQuantitativeCheckResult<ValueType>();
197 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
198 result = checker.check(this->env(), tasks[3])->template asExplicitQuantitativeCheckResult<ValueType>();
199 EXPECT_NEAR(this->
parseNumber(
"1/6"), result[*mdp->getInitialStates().begin()], this->precision());
200 result = checker.check(this->env(), tasks[4])->template asExplicitQuantitativeCheckResult<ValueType>();
201 EXPECT_NEAR(this->
parseNumber(
"0"), result[*mdp->getInitialStates().begin()], this->precision());
202 result = checker.check(this->env(), tasks[5])->template asExplicitQuantitativeCheckResult<ValueType>();
203 EXPECT_NEAR(this->
parseNumber(
"0"), result[*mdp->getInitialStates().begin()], this->precision());
204 result = checker.check(this->env(), tasks[6])->template asExplicitQuantitativeCheckResult<ValueType>();
205 EXPECT_NEAR(this->
parseNumber(
"1"), result[*mdp->getInitialStates().begin()], this->precision());
206 result = checker.check(this->env(), tasks[7])->template asExplicitQuantitativeCheckResult<ValueType>();
207 EXPECT_NEAR(this->
parseNumber(
"1"), result[*mdp->getInitialStates().begin()], this->precision());
210TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, consensus) {
211 typedef typename TestFixture::ValueType
ValueType;
213 std::string
const formulasString =
214 "Pmax=? [F \"all_coins_equal_0\" & \"finished\" || F \"agree\" & \"finished\"];"
215 "Pmin=? [F \"all_coins_equal_0\" & \"finished\" || F \"agree\" & \"finished\"];"
216 "Pmax=? [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];"
217 "Pmin=? [F \"all_coins_equal_1\" & \"finished\" || F \"agree\" & \"finished\"];";
220 auto modelFormulas = this->buildModelFormulas(program, formulasString);
221 auto model = std::move(modelFormulas.first);
222 auto tasks = this->getTasks(modelFormulas.second);
223 EXPECT_EQ(272ul, model->getNumberOfStates());
224 EXPECT_EQ(492ul, model->getNumberOfTransitions());
226 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
229 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
230 EXPECT_NEAR(this->
parseNumber(
"561/953"), result[*mdp->getInitialStates().begin()], this->precision());
231 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
232 EXPECT_NEAR(this->
parseNumber(
"392/953"), result[*mdp->getInitialStates().begin()], this->precision());
233 result = checker.check(this->env(), tasks[2])->template asExplicitQuantitativeCheckResult<ValueType>();
234 EXPECT_NEAR(this->
parseNumber(
"561/953"), result[*mdp->getInitialStates().begin()], this->precision());
235 result = checker.check(this->env(), tasks[3])->template asExplicitQuantitativeCheckResult<ValueType>();
236 EXPECT_NEAR(this->
parseNumber(
"392/953"), result[*mdp->getInitialStates().begin()], this->precision());
239TYPED_TEST(ConditionalMdpPrctlModelCheckerTest, simple) {
240 typedef typename TestFixture::ValueType
ValueType;
242 std::string
const programAsString = R
"(mdp
245 [] x=0 -> 0.7 : (x'=1) + 0.3 : (x'=2);
246 [] x=1 -> 1 : (x'=1);
247 [] x=2 -> 1 : (x'=1);
251 std::string const formulasString =
252 "Pmin=? [F x=2 || F x=1];"
253 "Pmax=? [F x=2 || F x=1];";
256 auto modelFormulas = this->buildModelFormulas(program, formulasString);
257 auto model = std::move(modelFormulas.first);
258 auto tasks = this->getTasks(modelFormulas.second);
259 EXPECT_EQ(3ul, model->getNumberOfStates());
260 EXPECT_EQ(4ul, model->getNumberOfTransitions());
262 auto mdp = model->template as<storm::models::sparse::Mdp<ValueType>>();
265 auto result = checker.check(this->env(), tasks[0])->template asExplicitQuantitativeCheckResult<ValueType>();
266 EXPECT_NEAR(this->
parseNumber(
"3/10"), result[*mdp->getInitialStates().begin()], this->precision());
267 result = checker.check(this->env(), tasks[1])->template asExplicitQuantitativeCheckResult<ValueType>();
268 EXPECT_NEAR(this->
parseNumber(
"3/10"), result[*mdp->getInitialStates().begin()], this->precision());
SolverEnvironment & solver()
ModelCheckerEnvironment & modelchecker()
void setPrecision(storm::RationalNumber value)
void setConditionalAlgorithmSetting(ConditionalAlgorithmSetting value)
MinMaxSolverEnvironment & minMax()
This class represents a (discrete-time) Markov decision process.
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::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)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes