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.

225 lines
11 KiB

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