198 lines
10 KiB

  1. #include <io/file.h>
  2. #include "test/storm_gtest.h"
  3. #include "storm-config.h"
  4. #include "storm/api/builder.h"
  5. #include "storm-parsers/api/model_descriptions.h"
  6. #include "storm/api/properties.h"
  7. #include "storm-parsers/api/properties.h"
  8. #include "storm/models/sparse/Smg.h"
  9. #include "storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
  10. #include "storm/modelchecker/results/QuantitativeCheckResult.h"
  11. #include "storm/modelchecker/results/QualitativeCheckResult.h"
  12. #include "storm/environment/solver/MinMaxSolverEnvironment.h"
  13. #include "storm/environment/solver/TopologicalSolverEnvironment.h"
  14. #include "storm/environment/solver/MultiplierEnvironment.h"
  15. #include "storm/settings/modules/CoreSettings.h"
  16. #include "storm/logic/Formulas.h"
  17. #include "storm/exceptions/UncheckedRequirementException.h"
  18. namespace {
  19. class DoubleViEnvironment {
  20. public:
  21. typedef double ValueType;
  22. static storm::Environment createEnvironment() {
  23. storm::Environment env;
  24. env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
  25. env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
  26. return env;
  27. }
  28. };
  29. template<typename TestType>
  30. class ShieldGenerationMdpPrctlModelCheckerTest : public ::testing::Test {
  31. public:
  32. typedef typename TestType::ValueType ValueType;
  33. ShieldGenerationMdpPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
  34. storm::Environment const& env() const { return _environment; }
  35. std::pair<std::shared_ptr<storm::models::sparse::Mdp<ValueType>>, std::vector<std::shared_ptr<storm::logic::Formula const>>> buildModelFormulas(std::string const& pathToPrismFile, std::string const& formulasAsString, std::string const& constantDefinitionString = "") const {
  36. std::pair<std::shared_ptr<storm::models::sparse::Mdp<ValueType>>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
  37. storm::prism::Program program = storm::api::parseProgram(pathToPrismFile);
  38. program = storm::utility::prism::preprocess(program, constantDefinitionString);
  39. result.second = storm::api::extractFormulasFromProperties(storm::api::parsePropertiesForPrismProgram(formulasAsString, program));
  40. result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<storm::models::sparse::Mdp<ValueType>>();
  41. return result;
  42. }
  43. std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) const {
  44. std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
  45. for (auto const& f : formulas) {
  46. result.emplace_back(*f);
  47. }
  48. return result;
  49. }
  50. ValueType parseNumber(std::string const& input) const { return storm::utility::convertNumber<ValueType>(input);}
  51. void convertShieldingFileToString(std::string filename, std::string &shieldingString) {
  52. filename += shieldEnding;
  53. std::ifstream resultFile(filename);
  54. std::stringstream resultBuffer;
  55. resultBuffer << resultFile.rdbuf();
  56. shieldingString = resultBuffer.str();
  57. }
  58. void getStringsToCompare(std::string filename, std::string &shieldingString, std::string &compareFileString) {
  59. this->convertShieldingFileToString(filename, shieldingString);
  60. std::string compareFileName = STORM_TEST_RESOURCES_DIR "/mdp-shields/" + filename;
  61. this->convertShieldingFileToString(compareFileName, compareFileString);
  62. filename += shieldEnding;
  63. std::remove(filename.c_str());
  64. }
  65. private:
  66. storm::Environment _environment;
  67. std::string shieldEnding = ".shield";
  68. };
  69. typedef ::testing::Types<
  70. DoubleViEnvironment
  71. > TestingTypes;
  72. TYPED_TEST_SUITE(ShieldGenerationMdpPrctlModelCheckerTest, TestingTypes,);
  73. TYPED_TEST(ShieldGenerationMdpPrctlModelCheckerTest, DieSelection) {
  74. typedef typename TestFixture::ValueType ValueType;
  75. // definition of shield file names
  76. std::vector<std::string> fileNames;
  77. fileNames.push_back("dieSelectionPreSafetylambda08Pmax");
  78. fileNames.push_back("dieSelectionPreSafetygamma08Pmax");
  79. fileNames.push_back("dieSelectionPreSafetylambda08Pmin");
  80. fileNames.push_back("dieSelectionPreSafetygamma08Pmin");
  81. fileNames.push_back("dieSelectionPostSafetylambda07Pmax");
  82. fileNames.push_back("dieSelectionPostSafetygamma07Pmax");
  83. fileNames.push_back("dieSelectionPostSafetylambda07Pmin");
  84. fileNames.push_back("dieSelectionPostSafetygamma07Pmin");
  85. // testing create shielding expressions
  86. std::string formulasString = "<" + fileNames[0] + ", PreSafety, lambda=0.8> Pmax=? [ F <5 \"done\" ]";
  87. formulasString += "; <" + fileNames[1] + ", PreSafety, gamma=0.8> Pmax=? [ F <5 \"done\" ]";
  88. formulasString += "; <" + fileNames[2] + ", PreSafety, lambda=0.8> Pmin=? [ F <5 \"done\" ]";
  89. formulasString += "; <" + fileNames[3] + ", PreSafety, gamma=0.8> Pmin=? [ F <5 \"done\" ]";
  90. formulasString += "; <" + fileNames[4] + ", PostSafety, lambda=0.7> Pmax=? [ F <6 \"two\" ]";
  91. formulasString += "; <" + fileNames[5] + ", PostSafety, gamma=0.7> Pmax=? [ F <6 \"two\" ]";
  92. formulasString += "; <" + fileNames[6] + ", PostSafety, lambda=0.7> Pmin=? [ F <6 \"two\" ]";
  93. formulasString += "; <" + fileNames[7] + ", PostSafety, gamma=0.7> Pmin=? [ F <6 \"two\" ]";
  94. auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR "/mdp/die_selection.nm", formulasString);
  95. auto mdp = std::move(modelFormulas.first);
  96. auto tasks = this->getTasks(modelFormulas.second);
  97. EXPECT_EQ(13ul, mdp->getNumberOfStates());
  98. EXPECT_EQ(43ul, mdp->getNumberOfTransitions());
  99. ASSERT_EQ(mdp->getType(), storm::models::ModelType::Mdp);
  100. EXPECT_EQ(25ull, mdp->getNumberOfChoices());
  101. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>> checker(*mdp);
  102. // definitions
  103. storm::logic::ShieldingType typePreSafety = storm::logic::ShieldingType::PreSafety;
  104. storm::logic::ShieldingType typePostSafety = storm::logic::ShieldingType::PostSafety;
  105. storm::logic::ShieldComparison comparisonRelative = storm::logic::ShieldComparison::Relative;
  106. storm::logic::ShieldComparison comparisonAbsolute = storm::logic::ShieldComparison::Absolute;
  107. double value08 = 0.8;
  108. double value07 = 0.7;
  109. std::string filename, shieldingString, compareFileString;
  110. // shielding results
  111. filename = fileNames[0];
  112. auto preSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePreSafety, filename, comparisonRelative, value08));
  113. tasks[0].setShieldingExpression(preSafetyShieldingExpression);
  114. EXPECT_TRUE(tasks[0].isShieldingTask());
  115. auto result = checker.check(this->env(), tasks[0]);
  116. this->getStringsToCompare(filename, shieldingString, compareFileString);
  117. EXPECT_EQ(shieldingString, compareFileString);
  118. filename = fileNames[1];
  119. preSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePreSafety, filename, comparisonAbsolute, value08));
  120. tasks[1].setShieldingExpression(preSafetyShieldingExpression);
  121. EXPECT_TRUE(tasks[1].isShieldingTask());
  122. result = checker.check(this->env(), tasks[1]);
  123. this->getStringsToCompare(filename, shieldingString, compareFileString);
  124. EXPECT_EQ(shieldingString, compareFileString);
  125. filename = fileNames[2];
  126. preSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePreSafety, filename, comparisonRelative, value08));
  127. tasks[2].setShieldingExpression(preSafetyShieldingExpression);
  128. EXPECT_TRUE(tasks[2].isShieldingTask());
  129. result = checker.check(this->env(), tasks[2]);
  130. this->getStringsToCompare(filename, shieldingString, compareFileString);
  131. EXPECT_EQ(shieldingString, compareFileString);
  132. filename = fileNames[3];
  133. preSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePreSafety, filename, comparisonAbsolute, value08));
  134. tasks[3].setShieldingExpression(preSafetyShieldingExpression);
  135. EXPECT_TRUE(tasks[3].isShieldingTask());
  136. result = checker.check(this->env(), tasks[3]);
  137. this->getStringsToCompare(filename, shieldingString, compareFileString);
  138. EXPECT_EQ(shieldingString, compareFileString);
  139. filename = fileNames[4];
  140. auto postSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePostSafety, filename, comparisonRelative, value07));
  141. tasks[4].setShieldingExpression(postSafetyShieldingExpression);
  142. EXPECT_TRUE(tasks[4].isShieldingTask());
  143. result = checker.check(this->env(), tasks[4]);
  144. this->getStringsToCompare(filename, shieldingString, compareFileString);
  145. EXPECT_EQ(shieldingString, compareFileString);
  146. filename = fileNames[5];
  147. postSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePostSafety, filename, comparisonAbsolute, value07));
  148. tasks[5].setShieldingExpression(postSafetyShieldingExpression);
  149. EXPECT_TRUE(tasks[5].isShieldingTask());
  150. result = checker.check(this->env(), tasks[5]);
  151. this->getStringsToCompare(filename, shieldingString, compareFileString);
  152. EXPECT_EQ(shieldingString, compareFileString);
  153. filename = fileNames[6];
  154. postSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePostSafety, filename, comparisonRelative, value07));
  155. tasks[6].setShieldingExpression(postSafetyShieldingExpression);
  156. EXPECT_TRUE(tasks[6].isShieldingTask());
  157. result = checker.check(this->env(), tasks[6]);
  158. this->getStringsToCompare(filename, shieldingString, compareFileString);
  159. EXPECT_EQ(shieldingString, compareFileString);
  160. filename = fileNames[7];
  161. postSafetyShieldingExpression = std::shared_ptr<storm::logic::ShieldExpression>(new storm::logic::ShieldExpression(typePostSafety, filename, comparisonAbsolute, value07));
  162. tasks[7].setShieldingExpression(postSafetyShieldingExpression);
  163. EXPECT_TRUE(tasks[7].isShieldingTask());
  164. result = checker.check(this->env(), tasks[7]);
  165. this->getStringsToCompare(filename, shieldingString, compareFileString);
  166. EXPECT_EQ(shieldingString, compareFileString);
  167. }
  168. // TODO: create more test cases (files)
  169. }