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.

256 lines
17 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #ifdef STORM_HAVE_CARL
  4. #include "src/adapters/CarlAdapter.h"
  5. #include<carl/numbers/numbers.h>
  6. #include<carl/core/VariablePool.h>
  7. #include "src/settings/SettingsManager.h"
  8. #include "src/settings/modules/GeneralSettings.h"
  9. #include "utility/storm.h"
  10. #include "utility/ModelInstantiator.h"
  11. #include "src/models/sparse/Model.h"
  12. #include "src/models/sparse/Dtmc.h"
  13. #include "src/models/sparse/Mdp.h"
  14. TEST(ModelInstantiatorTest, BrpProb) {
  15. carl::VariablePool::getInstance().clear();
  16. std::string programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/brp16_2.pm";
  17. std::string formulaAsString = "P=? [F s=5 ]";
  18. // Program and formula
  19. storm::prism::Program program = storm::parseProgram(programFile);
  20. program.checkValidity();
  21. std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);
  22. ASSERT_TRUE(formulas.size()==1);
  23. // Parametric model
  24. storm::generator::NextStateGeneratorOptions options(*formulas.front());
  25. std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program, options).build()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
  26. storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::models::sparse::Dtmc<double>> modelInstantiator(*dtmc);
  27. EXPECT_FALSE(dtmc->hasRewardModel());
  28. {
  29. std::map<storm::RationalFunctionVariable, storm::RationalNumber> valuation;
  30. storm::RationalFunctionVariable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL");
  31. ASSERT_NE(pL, carl::Variable::NO_VARIABLE);
  32. storm::RationalFunctionVariable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK");
  33. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  34. valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(0.8)));
  35. valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.9)));
  36. storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation));
  37. ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices());
  38. for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){
  39. for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){
  40. auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin();
  41. for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){
  42. EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn());
  43. double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation));
  44. EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue());
  45. ++instantiatedEntry;
  46. }
  47. EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry);
  48. }
  49. }
  50. EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling());
  51. EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling());
  52. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated);
  53. std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]);
  54. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>();
  55. EXPECT_NEAR(0.2989278941, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  56. }
  57. {
  58. std::map<storm::RationalFunctionVariable, storm::RationalNumber> valuation;
  59. storm::RationalFunctionVariable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL");
  60. ASSERT_NE(pL, carl::Variable::NO_VARIABLE);
  61. storm::RationalFunctionVariable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK");
  62. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  63. valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(1.0)));
  64. valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(1.0)));
  65. storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation));
  66. ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices());
  67. for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){
  68. for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){
  69. auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin();
  70. for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){
  71. EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn());
  72. double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation));
  73. EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue());
  74. ++instantiatedEntry;
  75. }
  76. EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry);
  77. }
  78. }
  79. EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling());
  80. EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling());
  81. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated);
  82. std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]);
  83. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>();
  84. EXPECT_EQ(0.0 , quantitativeChkResult[*instantiated.getInitialStates().begin()]);
  85. }
  86. {
  87. std::map<storm::RationalFunctionVariable, storm::RationalNumber> valuation;
  88. storm::RationalFunctionVariable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL");
  89. ASSERT_NE(pL, carl::Variable::NO_VARIABLE);
  90. storm::RationalFunctionVariable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK");
  91. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  92. valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(1.0)));
  93. valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.9)));
  94. storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation));
  95. ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices());
  96. for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){
  97. for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){
  98. auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin();
  99. for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){
  100. EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn());
  101. double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation));
  102. EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue());
  103. ++instantiatedEntry;
  104. }
  105. EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry);
  106. }
  107. }
  108. EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling());
  109. EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling());
  110. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated);
  111. std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]);
  112. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>();
  113. EXPECT_NEAR(0.01588055832, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  114. }
  115. }
  116. TEST(ModelInstantiatorTest, Brp_Rew) {
  117. carl::VariablePool::getInstance().clear();
  118. std::string programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/brp16_2.pm";
  119. std::string formulaAsString = "R=? [F ((s=5) | (s=0&srep=3)) ]";
  120. // Program and formula
  121. storm::prism::Program program = storm::parseProgram(programFile);
  122. program.checkValidity();
  123. std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);
  124. ASSERT_TRUE(formulas.size()==1);
  125. // Parametric model
  126. storm::generator::NextStateGeneratorOptions options(*formulas.front());
  127. std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program, options).build()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
  128. storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::models::sparse::Dtmc<double>> modelInstantiator(*dtmc);
  129. {
  130. std::map<storm::RationalFunctionVariable, storm::RationalNumber> valuation;
  131. storm::RationalFunctionVariable const& pL = carl::VariablePool::getInstance().findVariableWithName("pL");
  132. ASSERT_NE(pL, carl::Variable::NO_VARIABLE);
  133. storm::RationalFunctionVariable const& pK = carl::VariablePool::getInstance().findVariableWithName("pK");
  134. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  135. storm::RationalFunctionVariable const& TOMsg = carl::VariablePool::getInstance().findVariableWithName("TOMsg");
  136. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  137. storm::RationalFunctionVariable const& TOAck = carl::VariablePool::getInstance().findVariableWithName("TOAck");
  138. ASSERT_NE(pK, carl::Variable::NO_VARIABLE);
  139. valuation.insert(std::make_pair(pL,carl::rationalize<storm::RationalNumber>(0.9)));
  140. valuation.insert(std::make_pair(pK,carl::rationalize<storm::RationalNumber>(0.3)));
  141. valuation.insert(std::make_pair(TOMsg,carl::rationalize<storm::RationalNumber>(0.3)));
  142. valuation.insert(std::make_pair(TOAck,carl::rationalize<storm::RationalNumber>(0.5)));
  143. storm::models::sparse::Dtmc<double> const& instantiated(modelInstantiator.instantiate(valuation));
  144. ASSERT_EQ(dtmc->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices());
  145. for(std::size_t rowGroup = 0; rowGroup < dtmc->getTransitionMatrix().getRowGroupCount(); ++rowGroup){
  146. for(std::size_t row = dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < dtmc->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){
  147. auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin();
  148. for(auto const& paramEntry : dtmc->getTransitionMatrix().getRow(row)){
  149. EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn());
  150. double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation));
  151. EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue());
  152. ++instantiatedEntry;
  153. }
  154. EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry);
  155. }
  156. }
  157. ASSERT_TRUE(instantiated.hasUniqueRewardModel());
  158. EXPECT_FALSE(instantiated.getUniqueRewardModel().hasStateRewards());
  159. EXPECT_FALSE(instantiated.getUniqueRewardModel().hasTransitionRewards());
  160. EXPECT_TRUE(instantiated.getUniqueRewardModel().hasStateActionRewards());
  161. ASSERT_TRUE(dtmc->getUniqueRewardModel().hasStateActionRewards());
  162. std::size_t stateActionEntries = dtmc->getUniqueRewardModel().getStateActionRewardVector().size();
  163. ASSERT_EQ(stateActionEntries, instantiated.getUniqueRewardModel().getStateActionRewardVector().size());
  164. for(std::size_t i =0; i<stateActionEntries; ++i){
  165. double evaluatedValue = carl::toDouble(dtmc->getUniqueRewardModel().getStateActionRewardVector()[i].evaluate(valuation));
  166. EXPECT_EQ(evaluatedValue, instantiated.getUniqueRewardModel().getStateActionRewardVector()[i]);
  167. }
  168. EXPECT_EQ(dtmc->getStateLabeling(), instantiated.getStateLabeling());
  169. EXPECT_EQ(dtmc->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling());
  170. storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> modelchecker(instantiated);
  171. std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]);
  172. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>();
  173. EXPECT_NEAR(1.308324495, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  174. }
  175. }
  176. TEST(ModelInstantiatorTest, Consensus) {
  177. carl::VariablePool::getInstance().clear();
  178. std::string programFile = STORM_CPP_TESTS_BASE_PATH "/functional/utility/coin2_2.pm";
  179. std::string formulaAsString = "Pmin=? [F \"finished\"&\"all_coins_equal_1\" ]";
  180. // Program and formula
  181. storm::prism::Program program = storm::parseProgram(programFile);
  182. program.checkValidity();
  183. std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);
  184. ASSERT_TRUE(formulas.size()==1);
  185. // Parametric model
  186. storm::generator::NextStateGeneratorOptions options(*formulas.front());
  187. std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> mdp = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program, options).build()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
  188. storm::utility::ModelInstantiator<storm::models::sparse::Mdp<storm::RationalFunction>, storm::models::sparse::Mdp<double>> modelInstantiator(*mdp);
  189. std::map<storm::RationalFunctionVariable, storm::RationalNumber> valuation;
  190. storm::RationalFunctionVariable const& p1 = carl::VariablePool::getInstance().findVariableWithName("p1");
  191. ASSERT_NE(p1, carl::Variable::NO_VARIABLE);
  192. storm::RationalFunctionVariable const& p2 = carl::VariablePool::getInstance().findVariableWithName("p2");
  193. ASSERT_NE(p2, carl::Variable::NO_VARIABLE);
  194. valuation.insert(std::make_pair(p1,carl::rationalize<storm::RationalNumber>(0.51)));
  195. valuation.insert(std::make_pair(p2,carl::rationalize<storm::RationalNumber>(0.49)));
  196. storm::models::sparse::Mdp<double> const& instantiated(modelInstantiator.instantiate(valuation));
  197. ASSERT_EQ(mdp->getTransitionMatrix().getRowGroupIndices(), instantiated.getTransitionMatrix().getRowGroupIndices());
  198. for(std::size_t rowGroup = 0; rowGroup < mdp->getTransitionMatrix().getRowGroupCount(); ++rowGroup){
  199. for(std::size_t row = mdp->getTransitionMatrix().getRowGroupIndices()[rowGroup]; row < mdp->getTransitionMatrix().getRowGroupIndices()[rowGroup+1]; ++row){
  200. auto instantiatedEntry = instantiated.getTransitionMatrix().getRow(row).begin();
  201. for(auto const& paramEntry : mdp->getTransitionMatrix().getRow(row)){
  202. EXPECT_EQ(paramEntry.getColumn(), instantiatedEntry->getColumn());
  203. double evaluatedValue = carl::toDouble(paramEntry.getValue().evaluate(valuation));
  204. EXPECT_EQ(evaluatedValue, instantiatedEntry->getValue());
  205. ++instantiatedEntry;
  206. }
  207. EXPECT_EQ(instantiated.getTransitionMatrix().getRow(row).end(),instantiatedEntry);
  208. }
  209. }
  210. EXPECT_EQ(mdp->getStateLabeling(), instantiated.getStateLabeling());
  211. EXPECT_EQ(mdp->getOptionalChoiceLabeling(), instantiated.getOptionalChoiceLabeling());
  212. storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> modelchecker(instantiated);
  213. std::unique_ptr<storm::modelchecker::CheckResult> chkResult = modelchecker.check(*formulas[0]);
  214. storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeChkResult = chkResult->asExplicitQuantitativeCheckResult<double>();
  215. EXPECT_NEAR(0.3526577219, quantitativeChkResult[*instantiated.getInitialStates().begin()], storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision());
  216. }
  217. #endif