228 lines
10 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #include "src/solver/Z3SmtSolver.h"
  4. #include "src/settings/Settings.h"
  5. TEST(Z3SmtSolver, CheckSat) {
  6. #ifdef STORM_HAVE_Z3
  7. storm::solver::Z3SmtSolver s;
  8. storm::solver::Z3SmtSolver::CheckResult result;
  9. storm::expressions::Expression exprDeMorgan = !(storm::expressions::Expression::createBooleanVariable("x") && storm::expressions::Expression::createBooleanVariable("y")).iff((!storm::expressions::Expression::createBooleanVariable("x") || !storm::expressions::Expression::createBooleanVariable("y")));
  10. ASSERT_NO_THROW(s.assertExpression(exprDeMorgan));
  11. ASSERT_NO_THROW(result = s.check());
  12. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  13. ASSERT_NO_THROW(s.reset());
  14. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  15. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  16. storm::expressions::Expression c = storm::expressions::Expression::createIntegerVariable("c");
  17. storm::expressions::Expression exprFormula = a >= storm::expressions::Expression::createIntegerLiteral(0)
  18. && a < storm::expressions::Expression::createIntegerLiteral(5)
  19. && b > storm::expressions::Expression::createIntegerLiteral(7)
  20. && c == (a * b)
  21. && b + a > c;
  22. ASSERT_NO_THROW(s.assertExpression(exprFormula));
  23. ASSERT_NO_THROW(result = s.check());
  24. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  25. ASSERT_NO_THROW(s.reset());
  26. #else
  27. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  28. #endif
  29. }
  30. TEST(Z3SmtSolver, CheckUnsat) {
  31. #ifdef STORM_HAVE_Z3
  32. storm::solver::Z3SmtSolver s;
  33. storm::solver::Z3SmtSolver::CheckResult result;
  34. storm::expressions::Expression exprDeMorgan = !(storm::expressions::Expression::createBooleanVariable("x") && storm::expressions::Expression::createBooleanVariable("y")).iff( (!storm::expressions::Expression::createBooleanVariable("x") || !storm::expressions::Expression::createBooleanVariable("y")));
  35. ASSERT_NO_THROW(s.assertExpression(!exprDeMorgan));
  36. ASSERT_NO_THROW(result = s.check());
  37. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  38. ASSERT_NO_THROW(s.reset());
  39. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  40. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  41. storm::expressions::Expression c = storm::expressions::Expression::createIntegerVariable("c");
  42. storm::expressions::Expression exprFormula = a >= storm::expressions::Expression::createIntegerLiteral(2)
  43. && a < storm::expressions::Expression::createIntegerLiteral(5)
  44. && b > storm::expressions::Expression::createIntegerLiteral(7)
  45. && c == (a * b)
  46. && b + a > c;
  47. ASSERT_NO_THROW(s.assertExpression(exprFormula));
  48. ASSERT_NO_THROW(result = s.check());
  49. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  50. #else
  51. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  52. #endif
  53. }
  54. TEST(Z3SmtSolver, Backtracking) {
  55. #ifdef STORM_HAVE_Z3
  56. storm::solver::Z3SmtSolver s;
  57. storm::solver::Z3SmtSolver::CheckResult result;
  58. storm::expressions::Expression expr1 = storm::expressions::Expression::createTrue();
  59. storm::expressions::Expression expr2 = storm::expressions::Expression::createFalse();
  60. storm::expressions::Expression expr3 = storm::expressions::Expression::createFalse();
  61. ASSERT_NO_THROW(s.assertExpression(expr1));
  62. ASSERT_NO_THROW(result = s.check());
  63. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  64. ASSERT_NO_THROW(s.push());
  65. ASSERT_NO_THROW(s.assertExpression(expr2));
  66. ASSERT_NO_THROW(result = s.check());
  67. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  68. ASSERT_NO_THROW(s.pop());
  69. ASSERT_NO_THROW(result = s.check());
  70. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  71. ASSERT_NO_THROW(s.push());
  72. ASSERT_NO_THROW(s.assertExpression(expr2));
  73. ASSERT_NO_THROW(result = s.check());
  74. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  75. ASSERT_NO_THROW(s.push());
  76. ASSERT_NO_THROW(s.assertExpression(expr3));
  77. ASSERT_NO_THROW(result = s.check());
  78. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  79. ASSERT_NO_THROW(s.pop(2));
  80. ASSERT_NO_THROW(result = s.check());
  81. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  82. ASSERT_NO_THROW(s.reset());
  83. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  84. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  85. storm::expressions::Expression c = storm::expressions::Expression::createIntegerVariable("c");
  86. storm::expressions::Expression exprFormula = a >= storm::expressions::Expression::createIntegerLiteral(0)
  87. && a < storm::expressions::Expression::createIntegerLiteral(5)
  88. && b > storm::expressions::Expression::createIntegerLiteral(7)
  89. && c == (a * b)
  90. && b + a > c;
  91. storm::expressions::Expression exprFormula2 = a >= storm::expressions::Expression::createIntegerLiteral(2);
  92. ASSERT_NO_THROW(s.assertExpression(exprFormula));
  93. ASSERT_NO_THROW(result = s.check());
  94. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  95. ASSERT_NO_THROW(s.push());
  96. ASSERT_NO_THROW(s.assertExpression(exprFormula2));
  97. ASSERT_NO_THROW(result = s.check());
  98. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  99. ASSERT_NO_THROW(s.pop());
  100. ASSERT_NO_THROW(result = s.check());
  101. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  102. #else
  103. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  104. #endif
  105. }
  106. TEST(Z3SmtSolver, Assumptions) {
  107. #ifdef STORM_HAVE_Z3
  108. storm::solver::Z3SmtSolver s;
  109. storm::solver::Z3SmtSolver::CheckResult result;
  110. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  111. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  112. storm::expressions::Expression c = storm::expressions::Expression::createIntegerVariable("c");
  113. storm::expressions::Expression exprFormula = a >= storm::expressions::Expression::createIntegerLiteral(0)
  114. && a < storm::expressions::Expression::createIntegerLiteral(5)
  115. && b > storm::expressions::Expression::createIntegerLiteral(7)
  116. && c == (a * b)
  117. && b + a > c;
  118. storm::expressions::Expression f2 = storm::expressions::Expression::createBooleanVariable("f2");
  119. storm::expressions::Expression exprFormula2 = f2.implies(a >= storm::expressions::Expression::createIntegerLiteral(2));
  120. ASSERT_NO_THROW(s.assertExpression(exprFormula));
  121. ASSERT_NO_THROW(result = s.check());
  122. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  123. ASSERT_NO_THROW(s.assertExpression(exprFormula2));
  124. ASSERT_NO_THROW(result = s.check());
  125. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  126. ASSERT_NO_THROW(result = s.checkWithAssumptions({f2}));
  127. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::UNSAT);
  128. ASSERT_NO_THROW(result = s.check());
  129. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  130. ASSERT_NO_THROW(result = s.checkWithAssumptions({ !f2 }));
  131. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  132. #else
  133. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  134. #endif
  135. }
  136. TEST(Z3SmtSolver, GenerateModel) {
  137. #ifdef STORM_HAVE_Z3
  138. storm::solver::Z3SmtSolver s;
  139. storm::solver::Z3SmtSolver::CheckResult result;
  140. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  141. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  142. storm::expressions::Expression c = storm::expressions::Expression::createIntegerVariable("c");
  143. storm::expressions::Expression exprFormula = a > storm::expressions::Expression::createIntegerLiteral(0)
  144. && a < storm::expressions::Expression::createIntegerLiteral(5)
  145. && b > storm::expressions::Expression::createIntegerLiteral(7)
  146. && c == (a * b)
  147. && b + a > c;
  148. (s.assertExpression(exprFormula));
  149. (result = s.check());
  150. ASSERT_TRUE(result == storm::solver::SmtSolver::CheckResult::SAT);
  151. storm::expressions::SimpleValuation model;
  152. (model = s.getModel());
  153. int_fast64_t a_eval;
  154. (a_eval = model.getIntegerValue("a"));
  155. ASSERT_EQ(1, a_eval);
  156. #else
  157. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  158. #endif
  159. }
  160. TEST(Z3SmtSolver, AllSat) {
  161. #ifdef STORM_HAVE_Z3
  162. storm::solver::Z3SmtSolver s;
  163. storm::solver::Z3SmtSolver::CheckResult result;
  164. storm::expressions::Expression a = storm::expressions::Expression::createIntegerVariable("a");
  165. storm::expressions::Expression b = storm::expressions::Expression::createIntegerVariable("b");
  166. storm::expressions::Expression x = storm::expressions::Expression::createBooleanVariable("x");
  167. storm::expressions::Expression y = storm::expressions::Expression::createBooleanVariable("y");
  168. storm::expressions::Expression z = storm::expressions::Expression::createBooleanVariable("z");
  169. storm::expressions::Expression exprFormula1 = x.implies(a > storm::expressions::Expression::createIntegerLiteral(5));
  170. storm::expressions::Expression exprFormula2 = y.implies(a < storm::expressions::Expression::createIntegerLiteral(5));
  171. storm::expressions::Expression exprFormula3 = z.implies(b < storm::expressions::Expression::createIntegerLiteral(5));
  172. (s.assertExpression(exprFormula1));
  173. (s.assertExpression(exprFormula2));
  174. (s.assertExpression(exprFormula3));
  175. std::vector<storm::expressions::SimpleValuation> valuations = s.allSat({x,y});
  176. ASSERT_TRUE(valuations.size() == 3);
  177. for (int i = 0; i < valuations.size(); ++i) {
  178. ASSERT_EQ(valuations[i].getNumberOfIdentifiers(), 2);
  179. ASSERT_TRUE(valuations[i].containsBooleanIdentifier("x"));
  180. ASSERT_TRUE(valuations[i].containsBooleanIdentifier("y"));
  181. }
  182. for (int i = 0; i < valuations.size(); ++i) {
  183. ASSERT_FALSE(valuations[i].getBooleanValue("x") && valuations[i].getBooleanValue("y"));
  184. for (int j = i+1; j < valuations.size(); ++j) {
  185. ASSERT_TRUE((valuations[i].getBooleanValue("x") != valuations[j].getBooleanValue("x")) || (valuations[i].getBooleanValue("y") != valuations[j].getBooleanValue("y")));
  186. }
  187. }
  188. #else
  189. ASSERT_TRUE(false) << "StoRM built without Z3 support.";
  190. #endif
  191. }