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.

213 lines
11 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #ifdef STORM_HAVE_MSAT
  4. #include "mathsat.h"
  5. #include "src/adapters/MathsatExpressionAdapter.h"
  6. #include "src/settings/SettingsManager.h"
  7. TEST(MathsatExpressionAdapter, StormToMathsatBasic) {
  8. msat_config config = msat_create_config();
  9. msat_env env = msat_create_env(config);
  10. ASSERT_FALSE(MSAT_ERROR_ENV(env));
  11. msat_destroy_config(config);
  12. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  13. storm::adapters::MathsatExpressionAdapter adapter(*manager, env);
  14. storm::expressions::Expression exprTrue = manager->boolean(true);
  15. msat_term msatTrue = msat_make_true(env);
  16. msat_term conjecture;
  17. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, msatTrue, adapter.translateExpression(exprTrue))));
  18. msat_assert_formula(env, conjecture);
  19. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  20. msat_reset_env(env);
  21. storm::expressions::Expression exprFalse = manager->boolean(false);
  22. msat_term msatFalse = msat_make_false(env);
  23. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprFalse), msatFalse)));
  24. msat_assert_formula(env, conjecture);
  25. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  26. msat_reset_env(env);
  27. storm::expressions::Variable x = manager->declareBooleanVariable("x");
  28. storm::expressions::Variable y = manager->declareBooleanVariable("y");
  29. storm::expressions::Expression exprConjunction = x && y;
  30. msat_term msatConjunction = msat_make_and(env, msat_make_constant(env, msat_declare_function(env, "x", msat_get_bool_type(env))), msat_make_constant(env, msat_declare_function(env, "y", msat_get_bool_type(env))));
  31. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprConjunction), msatConjunction)));
  32. msat_assert_formula(env, conjecture);
  33. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  34. msat_reset_env(env);
  35. storm::expressions::Expression exprNor = !(x || y);
  36. msat_term msatNor = msat_make_not(env, msat_make_or(env, msat_make_constant(env, msat_declare_function(env, "x", msat_get_bool_type(env))), msat_make_constant(env, msat_declare_function(env, "y", msat_get_bool_type(env)))));
  37. ASSERT_NO_THROW(adapter.translateExpression(exprNor)); // Variables already created in adapter.
  38. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprNor), msatNor)));
  39. msat_assert_formula(env, conjecture);
  40. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  41. msat_reset_env(env);
  42. }
  43. TEST(MathsatExpressionAdapter, StormToMathsatInteger) {
  44. msat_config config = msat_create_config();
  45. msat_env env = msat_create_env(config);
  46. ASSERT_FALSE(MSAT_ERROR_ENV(env));
  47. msat_destroy_config(config);
  48. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  49. storm::adapters::MathsatExpressionAdapter adapter(*manager, env);
  50. storm::expressions::Variable x = manager->declareIntegerVariable("x");
  51. storm::expressions::Variable y = manager->declareIntegerVariable("y");
  52. storm::expressions::Expression exprAdd = x + y < -y;
  53. msat_decl xDecl = msat_declare_function(env, "x", msat_get_integer_type(env));
  54. msat_term xVar = msat_make_constant(env, xDecl);
  55. msat_decl yDecl = msat_declare_function(env, "y", msat_get_integer_type(env));
  56. msat_term yVar = msat_make_constant(env, yDecl);
  57. msat_term minusY = msat_make_times(env, msat_make_number(env, "-1"), yVar);
  58. msat_term msatAdd = msat_make_plus(env, xVar, yVar);
  59. msat_term msatLess = msat_make_and(env, msat_make_leq(env, msatAdd, minusY), msat_make_not(env, msat_make_equal(env, msatAdd, minusY)));
  60. msat_term conjecture;
  61. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprAdd), msatLess)));
  62. msat_assert_formula(env, conjecture);
  63. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  64. msat_reset_env(env);
  65. storm::expressions::Expression exprMult = !(x * y == y);
  66. msat_term msatTimes = msat_make_times(env, xVar, yVar);
  67. msat_term msatNotEqual = msat_make_not(env, msat_make_equal(env, msatTimes, yVar));
  68. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprMult), msatNotEqual)));
  69. msat_assert_formula(env, conjecture);
  70. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  71. msat_reset_env(env);
  72. }
  73. TEST(MathsatExpressionAdapter, StormToMathsatReal) {
  74. msat_config config = msat_create_config();
  75. msat_env env = msat_create_env(config);
  76. ASSERT_FALSE(MSAT_ERROR_ENV(env));
  77. msat_destroy_config(config);
  78. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  79. storm::adapters::MathsatExpressionAdapter adapter(*manager, env);
  80. storm::expressions::Variable x = manager->declareRationalVariable("x");
  81. storm::expressions::Variable y = manager->declareRationalVariable("y");
  82. storm::expressions::Expression exprAdd = x + y < -y;
  83. msat_decl xDecl = msat_declare_function(env, "x", msat_get_rational_type(env));
  84. msat_term xVar = msat_make_constant(env, xDecl);
  85. msat_decl yDecl = msat_declare_function(env, "y", msat_get_rational_type(env));
  86. msat_term yVar = msat_make_constant(env, yDecl);
  87. msat_term minusY = msat_make_times(env, msat_make_number(env, "-1"), yVar);
  88. msat_term msatAdd = msat_make_plus(env, xVar, yVar);
  89. msat_term msatLess = msat_make_and(env, msat_make_leq(env, msatAdd, minusY), msat_make_not(env, msat_make_equal(env, msatAdd, minusY)));
  90. msat_term conjecture;
  91. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprAdd), msatLess)));
  92. msat_assert_formula(env, conjecture);
  93. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  94. msat_reset_env(env);
  95. storm::expressions::Expression exprMult = !(x * y == y);
  96. msat_term msatTimes = msat_make_times(env, xVar, yVar);
  97. msat_term msatNotEqual = msat_make_not(env, msat_make_equal(env, msatTimes, yVar));
  98. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprMult), msatNotEqual)));
  99. msat_assert_formula(env, conjecture);
  100. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  101. msat_reset_env(env);
  102. }
  103. TEST(MathsatExpressionAdapter, StormToMathsatFloorCeil) {
  104. msat_config config = msat_create_config();
  105. msat_env env = msat_create_env(config);
  106. ASSERT_FALSE(MSAT_ERROR_ENV(env));
  107. msat_destroy_config(config);
  108. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  109. storm::adapters::MathsatExpressionAdapter adapter(*manager, env);
  110. storm::expressions::Variable d = manager->declareRationalVariable("d");
  111. storm::expressions::Variable i = manager->declareIntegerVariable("i");
  112. storm::expressions::Expression exprFloor = storm::expressions::floor(d) == i && d > manager->rational(4.1) && d < manager->rational(4.991);
  113. msat_decl iDecl = msat_declare_function(env, "i", msat_get_integer_type(env));
  114. msat_term iVar = msat_make_constant(env, iDecl);
  115. msat_term msatEqualsFour = msat_make_equal(env, msat_make_number(env, "4"), iVar);
  116. msat_term conjecture;
  117. msat_term translatedExpr = adapter.translateExpression(exprFloor);
  118. msat_term msatIff = msat_make_iff(env, translatedExpr, msatEqualsFour);
  119. ASSERT_NO_THROW(conjecture = msat_make_not(env, msatIff));
  120. msat_assert_formula(env, conjecture);
  121. // It is not logically equivalent, so this should be satisfiable.
  122. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_SAT);
  123. msat_reset_env(env);
  124. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_or(env, msat_make_not(env, adapter.translateExpression(exprFloor)), msatEqualsFour)));
  125. msat_assert_formula(env, conjecture);
  126. // However, the left part implies the right one, which is why this should be unsatisfiable.
  127. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_UNSAT);
  128. msat_reset_env(env);
  129. storm::expressions::Expression exprCeil = storm::expressions::ceil(d) == i && d > manager->rational(4.1) && d < manager->rational(4.991);
  130. msat_term msatEqualsFive = msat_make_equal(env, msat_make_number(env, "5"), iVar);
  131. ASSERT_NO_THROW(conjecture = msat_make_not(env, msat_make_iff(env, adapter.translateExpression(exprFloor), msatEqualsFive)));
  132. msat_assert_formula(env, conjecture);
  133. // It is not logically equivalent, so this should be satisfiable.
  134. ASSERT_TRUE(msat_solve(env) == msat_result::MSAT_SAT);
  135. msat_reset_env(env);
  136. ASSERT_NO_THROW(conjecture = msat_make_or(env, msat_make_not(env, adapter.translateExpression(exprFloor)), msatEqualsFive));
  137. msat_assert_formula(env, conjecture);
  138. msat_reset_env(env);
  139. }
  140. TEST(MathsatExpressionAdapter, MathsatToStormBasic) {
  141. msat_config config = msat_create_config();
  142. msat_env env = msat_create_env(config);
  143. ASSERT_FALSE(MSAT_ERROR_ENV(env));
  144. msat_destroy_config(config);
  145. unsigned args = 2;
  146. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  147. manager->declareBooleanVariable("x");
  148. manager->declareBooleanVariable("y");
  149. storm::adapters::MathsatExpressionAdapter adapter(*manager, env);
  150. msat_term msatTrue = msat_make_true(env);
  151. storm::expressions::Expression exprTrue;
  152. ASSERT_NO_THROW(exprTrue = adapter.translateExpression(msatTrue));
  153. ASSERT_TRUE(exprTrue.isTrue());
  154. msat_term msatFalse = msat_make_false(env);
  155. storm::expressions::Expression exprFalse;
  156. ASSERT_NO_THROW(exprTrue = adapter.translateExpression(msatFalse));
  157. ASSERT_TRUE(exprTrue.isFalse());
  158. msat_decl xDecl = msat_declare_function(env, "x", msat_get_bool_type(env));
  159. msat_term x = msat_make_constant(env, xDecl);
  160. msat_decl yDecl = msat_declare_function(env, "y", msat_get_bool_type(env));
  161. msat_term y = msat_make_constant(env, yDecl);
  162. msat_term msatConjunction = msat_make_and(env, x, y);
  163. storm::expressions::Expression exprConjunction;
  164. ASSERT_NO_THROW(exprConjunction = adapter.translateExpression(msatConjunction));
  165. ASSERT_EQ(storm::expressions::OperatorType::And, exprConjunction.getOperator());
  166. ASSERT_TRUE(exprConjunction.getOperand(0).isVariable());
  167. ASSERT_EQ("x", exprConjunction.getOperand(0).getIdentifier());
  168. ASSERT_TRUE(exprConjunction.getOperand(1).isVariable());
  169. ASSERT_EQ("y", exprConjunction.getOperand(1).getIdentifier());
  170. msat_term msatNor = msat_make_not(env, msat_make_or(env, x, y));
  171. storm::expressions::Expression exprNor;
  172. ASSERT_NO_THROW(exprNor = adapter.translateExpression(msatNor));
  173. ASSERT_EQ(storm::expressions::OperatorType::Not, exprNor.getOperator());
  174. ASSERT_EQ(storm::expressions::OperatorType::Or, exprNor.getOperand(0).getOperator());
  175. ASSERT_TRUE(exprNor.getOperand(0).getOperand(0).isVariable());
  176. ASSERT_EQ("x", exprNor.getOperand(0).getOperand(0).getIdentifier());
  177. ASSERT_TRUE(exprNor.getOperand(0).getOperand(1).isVariable());
  178. ASSERT_EQ("y", exprNor.getOperand(0).getOperand(1).getIdentifier());
  179. }
  180. #endif