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.

370 lines
20 KiB

  1. #include <map>
  2. #include <string>
  3. #include "gtest/gtest.h"
  4. #include "src/storage/expressions/Expression.h"
  5. #include "src/storage/expressions/ExpressionManager.h"
  6. #include "src/storage/expressions/LinearityCheckVisitor.h"
  7. #include "src/storage/expressions/SimpleValuation.h"
  8. #include "src/exceptions/InvalidTypeException.h"
  9. TEST(Expression, FactoryMethodTest) {
  10. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  11. EXPECT_NO_THROW(manager->boolean(true));
  12. EXPECT_NO_THROW(manager->boolean(false));
  13. EXPECT_NO_THROW(manager->integer(3));
  14. EXPECT_NO_THROW(manager->rational(3.14));
  15. EXPECT_NO_THROW(manager->declareBooleanVariable("x"));
  16. EXPECT_NO_THROW(manager->declareIntegerVariable("y"));
  17. EXPECT_NO_THROW(manager->declareRationalVariable("z"));
  18. }
  19. TEST(Expression, AccessorTest) {
  20. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  21. storm::expressions::Expression trueExpression;
  22. storm::expressions::Expression falseExpression;
  23. storm::expressions::Expression threeExpression;
  24. storm::expressions::Expression piExpression;
  25. storm::expressions::Expression boolVarExpression;
  26. storm::expressions::Expression intVarExpression;
  27. storm::expressions::Expression rationalVarExpression;
  28. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  29. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  30. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  31. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  32. ASSERT_NO_THROW(boolVarExpression = manager->declareBooleanVariable("x"));
  33. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  34. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  35. EXPECT_TRUE(trueExpression.hasBooleanType());
  36. EXPECT_TRUE(trueExpression.isLiteral());
  37. EXPECT_TRUE(trueExpression.isTrue());
  38. EXPECT_FALSE(trueExpression.isFalse());
  39. EXPECT_TRUE(trueExpression.getVariables() == std::set<storm::expressions::Variable>());
  40. EXPECT_TRUE(falseExpression.hasBooleanType());
  41. EXPECT_TRUE(falseExpression.isLiteral());
  42. EXPECT_FALSE(falseExpression.isTrue());
  43. EXPECT_TRUE(falseExpression.isFalse());
  44. EXPECT_TRUE(falseExpression.getVariables() == std::set<storm::expressions::Variable>());
  45. EXPECT_TRUE(threeExpression.hasIntegerType());
  46. EXPECT_TRUE(threeExpression.isLiteral());
  47. EXPECT_FALSE(threeExpression.isTrue());
  48. EXPECT_FALSE(threeExpression.isFalse());
  49. EXPECT_TRUE(threeExpression.getVariables() == std::set<storm::expressions::Variable>());
  50. EXPECT_TRUE(piExpression.hasRationalType());
  51. EXPECT_TRUE(piExpression.isLiteral());
  52. EXPECT_FALSE(piExpression.isTrue());
  53. EXPECT_FALSE(piExpression.isFalse());
  54. EXPECT_TRUE(piExpression.getVariables() == std::set<storm::expressions::Variable>());
  55. EXPECT_TRUE(boolVarExpression.hasBooleanType());
  56. EXPECT_FALSE(boolVarExpression.isLiteral());
  57. EXPECT_FALSE(boolVarExpression.isTrue());
  58. EXPECT_FALSE(boolVarExpression.isFalse());
  59. EXPECT_TRUE(boolVarExpression.getVariables() == std::set<storm::expressions::Variable>({manager->getVariable("x")}));
  60. EXPECT_TRUE(intVarExpression.hasIntegerType());
  61. EXPECT_FALSE(intVarExpression.isLiteral());
  62. EXPECT_FALSE(intVarExpression.isTrue());
  63. EXPECT_FALSE(intVarExpression.isFalse());
  64. EXPECT_TRUE(intVarExpression.getVariables() == std::set<storm::expressions::Variable>({manager->getVariable("y")}));
  65. EXPECT_TRUE(rationalVarExpression.hasRationalType());
  66. EXPECT_FALSE(rationalVarExpression.isLiteral());
  67. EXPECT_FALSE(rationalVarExpression.isTrue());
  68. EXPECT_FALSE(rationalVarExpression.isFalse());
  69. EXPECT_TRUE(rationalVarExpression.getVariables() == std::set<storm::expressions::Variable>({manager->getVariable("z")}));
  70. }
  71. TEST(Expression, OperatorTest) {
  72. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  73. storm::expressions::Expression trueExpression;
  74. storm::expressions::Expression falseExpression;
  75. storm::expressions::Expression threeExpression;
  76. storm::expressions::Expression piExpression;
  77. storm::expressions::Expression boolVarExpression;
  78. storm::expressions::Expression intVarExpression;
  79. storm::expressions::Expression rationalVarExpression;
  80. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  81. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  82. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  83. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  84. ASSERT_NO_THROW(boolVarExpression = manager->declareBooleanVariable("x"));
  85. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  86. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  87. storm::expressions::Expression tempExpression;
  88. ASSERT_THROW(tempExpression = storm::expressions::ite(trueExpression, falseExpression, piExpression), storm::exceptions::InvalidTypeException);
  89. ASSERT_NO_THROW(tempExpression = storm::expressions::ite(boolVarExpression, threeExpression, rationalVarExpression));
  90. EXPECT_TRUE(tempExpression.hasRationalType());
  91. ASSERT_NO_THROW(tempExpression = storm::expressions::ite(boolVarExpression, threeExpression, intVarExpression));
  92. EXPECT_TRUE(tempExpression.hasIntegerType());
  93. ASSERT_NO_THROW(tempExpression = storm::expressions::ite(boolVarExpression, trueExpression, falseExpression));
  94. EXPECT_TRUE(tempExpression.hasBooleanType());
  95. ASSERT_THROW(tempExpression = trueExpression + piExpression, storm::exceptions::InvalidTypeException);
  96. ASSERT_NO_THROW(tempExpression = threeExpression + threeExpression);
  97. EXPECT_TRUE(tempExpression.hasIntegerType());
  98. ASSERT_NO_THROW(tempExpression = threeExpression + piExpression);
  99. EXPECT_TRUE(tempExpression.hasRationalType());
  100. ASSERT_NO_THROW(tempExpression = rationalVarExpression + rationalVarExpression);
  101. EXPECT_TRUE(tempExpression.hasRationalType());
  102. ASSERT_THROW(tempExpression = trueExpression - piExpression, storm::exceptions::InvalidTypeException);
  103. ASSERT_NO_THROW(tempExpression = threeExpression - threeExpression);
  104. EXPECT_TRUE(tempExpression.hasIntegerType());
  105. ASSERT_NO_THROW(tempExpression = threeExpression - piExpression);
  106. EXPECT_TRUE(tempExpression.hasRationalType());
  107. ASSERT_NO_THROW(tempExpression = rationalVarExpression - rationalVarExpression);
  108. EXPECT_TRUE(tempExpression.hasRationalType());
  109. ASSERT_THROW(tempExpression = -trueExpression, storm::exceptions::InvalidTypeException);
  110. ASSERT_NO_THROW(tempExpression = -threeExpression);
  111. EXPECT_TRUE(tempExpression.hasIntegerType());
  112. ASSERT_NO_THROW(tempExpression = -piExpression);
  113. EXPECT_TRUE(tempExpression.hasRationalType());
  114. ASSERT_NO_THROW(tempExpression = -rationalVarExpression);
  115. EXPECT_TRUE(tempExpression.hasRationalType());
  116. ASSERT_THROW(tempExpression = trueExpression * piExpression, storm::exceptions::InvalidTypeException);
  117. ASSERT_NO_THROW(tempExpression = threeExpression * threeExpression);
  118. EXPECT_TRUE(tempExpression.hasIntegerType());
  119. ASSERT_NO_THROW(tempExpression = threeExpression * piExpression);
  120. EXPECT_TRUE(tempExpression.hasRationalType());
  121. ASSERT_NO_THROW(tempExpression = intVarExpression * intVarExpression);
  122. EXPECT_TRUE(tempExpression.hasIntegerType());
  123. ASSERT_THROW(tempExpression = trueExpression / piExpression, storm::exceptions::InvalidTypeException);
  124. ASSERT_NO_THROW(tempExpression = threeExpression / threeExpression);
  125. EXPECT_TRUE(tempExpression.hasIntegerType());
  126. ASSERT_NO_THROW(tempExpression = threeExpression / piExpression);
  127. EXPECT_TRUE(tempExpression.hasRationalType());
  128. ASSERT_NO_THROW(tempExpression = rationalVarExpression / intVarExpression);
  129. EXPECT_TRUE(tempExpression.hasRationalType());
  130. ASSERT_THROW(tempExpression = trueExpression && piExpression, storm::exceptions::InvalidTypeException);
  131. ASSERT_NO_THROW(tempExpression = trueExpression && falseExpression);
  132. EXPECT_TRUE(tempExpression.hasBooleanType());
  133. ASSERT_NO_THROW(tempExpression = boolVarExpression && boolVarExpression);
  134. EXPECT_TRUE(tempExpression.hasBooleanType());
  135. ASSERT_THROW(tempExpression = trueExpression || piExpression, storm::exceptions::InvalidTypeException);
  136. ASSERT_NO_THROW(tempExpression = trueExpression || falseExpression);
  137. EXPECT_TRUE(tempExpression.hasBooleanType());
  138. ASSERT_NO_THROW(tempExpression = boolVarExpression || boolVarExpression);
  139. EXPECT_TRUE(tempExpression.hasBooleanType());
  140. ASSERT_THROW(tempExpression = !threeExpression, storm::exceptions::InvalidTypeException);
  141. ASSERT_NO_THROW(tempExpression = !trueExpression);
  142. EXPECT_TRUE(tempExpression.hasBooleanType());
  143. ASSERT_NO_THROW(tempExpression = !boolVarExpression);
  144. EXPECT_TRUE(tempExpression.hasBooleanType());
  145. ASSERT_THROW(tempExpression = trueExpression == piExpression, storm::exceptions::InvalidTypeException);
  146. ASSERT_NO_THROW(tempExpression = threeExpression == threeExpression);
  147. EXPECT_TRUE(tempExpression.hasBooleanType());
  148. ASSERT_NO_THROW(tempExpression = intVarExpression == rationalVarExpression);
  149. EXPECT_TRUE(tempExpression.hasBooleanType());
  150. ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException);
  151. ASSERT_NO_THROW(tempExpression = threeExpression != threeExpression);
  152. EXPECT_TRUE(tempExpression.hasBooleanType());
  153. ASSERT_NO_THROW(tempExpression = intVarExpression != rationalVarExpression);
  154. EXPECT_TRUE(tempExpression.hasBooleanType());
  155. ASSERT_THROW(tempExpression = trueExpression > piExpression, storm::exceptions::InvalidTypeException);
  156. ASSERT_NO_THROW(tempExpression = threeExpression > threeExpression);
  157. EXPECT_TRUE(tempExpression.hasBooleanType());
  158. ASSERT_NO_THROW(tempExpression = intVarExpression > rationalVarExpression);
  159. EXPECT_TRUE(tempExpression.hasBooleanType());
  160. ASSERT_THROW(tempExpression = trueExpression >= piExpression, storm::exceptions::InvalidTypeException);
  161. ASSERT_NO_THROW(tempExpression = threeExpression >= threeExpression);
  162. EXPECT_TRUE(tempExpression.hasBooleanType());
  163. ASSERT_NO_THROW(tempExpression = intVarExpression >= rationalVarExpression);
  164. EXPECT_TRUE(tempExpression.hasBooleanType());
  165. ASSERT_THROW(tempExpression = trueExpression < piExpression, storm::exceptions::InvalidTypeException);
  166. ASSERT_NO_THROW(tempExpression = threeExpression < threeExpression);
  167. EXPECT_TRUE(tempExpression.hasBooleanType());
  168. ASSERT_NO_THROW(tempExpression = intVarExpression < rationalVarExpression);
  169. EXPECT_TRUE(tempExpression.hasBooleanType());
  170. ASSERT_THROW(tempExpression = trueExpression <= piExpression, storm::exceptions::InvalidTypeException);
  171. ASSERT_NO_THROW(tempExpression = threeExpression <= threeExpression);
  172. EXPECT_TRUE(tempExpression.hasBooleanType());
  173. ASSERT_NO_THROW(tempExpression = intVarExpression <= rationalVarExpression);
  174. EXPECT_TRUE(tempExpression.hasBooleanType());
  175. ASSERT_THROW(tempExpression = storm::expressions::minimum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
  176. ASSERT_NO_THROW(tempExpression = storm::expressions::minimum(threeExpression, threeExpression));
  177. EXPECT_TRUE(tempExpression.hasIntegerType());
  178. ASSERT_NO_THROW(tempExpression = storm::expressions::minimum(intVarExpression, rationalVarExpression));
  179. EXPECT_TRUE(tempExpression.hasRationalType());
  180. ASSERT_THROW(tempExpression = storm::expressions::maximum(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
  181. ASSERT_NO_THROW(tempExpression = storm::expressions::maximum(threeExpression, threeExpression));
  182. EXPECT_TRUE(tempExpression.hasIntegerType());
  183. ASSERT_NO_THROW(tempExpression = storm::expressions::maximum(intVarExpression, rationalVarExpression));
  184. EXPECT_TRUE(tempExpression.hasRationalType());
  185. ASSERT_THROW(tempExpression = storm::expressions::implies(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
  186. ASSERT_NO_THROW(tempExpression = storm::expressions::implies(trueExpression, falseExpression));
  187. EXPECT_TRUE(tempExpression.hasBooleanType());
  188. ASSERT_NO_THROW(tempExpression = storm::expressions::implies(boolVarExpression, boolVarExpression));
  189. EXPECT_TRUE(tempExpression.hasBooleanType());
  190. ASSERT_THROW(tempExpression = storm::expressions::iff(trueExpression, piExpression), storm::exceptions::InvalidTypeException);
  191. ASSERT_NO_THROW(tempExpression = storm::expressions::iff(trueExpression, falseExpression));
  192. EXPECT_TRUE(tempExpression.hasBooleanType());
  193. ASSERT_NO_THROW(tempExpression = storm::expressions::iff(boolVarExpression, boolVarExpression));
  194. EXPECT_TRUE(tempExpression.hasBooleanType());
  195. ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException);
  196. ASSERT_NO_THROW(tempExpression = trueExpression != falseExpression);
  197. EXPECT_TRUE(tempExpression.hasBooleanType());
  198. ASSERT_NO_THROW(tempExpression = boolVarExpression != boolVarExpression);
  199. EXPECT_TRUE(tempExpression.hasBooleanType());
  200. ASSERT_THROW(tempExpression = storm::expressions::floor(trueExpression), storm::exceptions::InvalidTypeException);
  201. ASSERT_NO_THROW(tempExpression = storm::expressions::floor(threeExpression));
  202. EXPECT_TRUE(tempExpression.hasIntegerType());
  203. ASSERT_NO_THROW(tempExpression = storm::expressions::floor(rationalVarExpression));
  204. EXPECT_TRUE(tempExpression.hasIntegerType());
  205. ASSERT_THROW(tempExpression = storm::expressions::ceil(trueExpression), storm::exceptions::InvalidTypeException);
  206. ASSERT_NO_THROW(tempExpression = storm::expressions::ceil(threeExpression));
  207. EXPECT_TRUE(tempExpression.hasIntegerType());
  208. ASSERT_NO_THROW(tempExpression = storm::expressions::ceil(rationalVarExpression));
  209. EXPECT_TRUE(tempExpression.hasIntegerType());
  210. ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException);
  211. ASSERT_NO_THROW(tempExpression = threeExpression ^ threeExpression);
  212. EXPECT_TRUE(tempExpression.hasIntegerType());
  213. ASSERT_NO_THROW(tempExpression = intVarExpression ^ rationalVarExpression);
  214. EXPECT_TRUE(tempExpression.hasRationalType());
  215. }
  216. TEST(Expression, SubstitutionTest) {
  217. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  218. storm::expressions::Expression trueExpression;
  219. storm::expressions::Expression falseExpression;
  220. storm::expressions::Expression threeExpression;
  221. storm::expressions::Expression piExpression;
  222. storm::expressions::Expression boolVarExpression;
  223. storm::expressions::Expression intVarExpression;
  224. storm::expressions::Expression rationalVarExpression;
  225. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  226. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  227. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  228. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  229. ASSERT_NO_THROW(boolVarExpression = manager->declareBooleanVariable("x"));
  230. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  231. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  232. storm::expressions::Expression tempExpression;
  233. ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolVarExpression);
  234. #ifdef WINDOWS
  235. storm::expressions::Expression twopointseven = manager->rational(2.7);
  236. std::map<storm::expressions::Variable, storm::expressions::Expression> substution = { std::make_pair(manager->getVariable("y"), twopointseven), std::make_pair(manager->getVariable("x"), manager->boolean(true)) };
  237. #else
  238. std::map<storm::expressions::Variable, storm::expressions::Expression> substution = { std::make_pair(manager->getVariable("y"), manager->rational(2.7)), std::make_pair(manager->getVariable("x"), manager->boolean(true)) };
  239. #endif
  240. storm::expressions::Expression substitutedExpression;
  241. ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute(substution));
  242. EXPECT_TRUE(substitutedExpression.simplify().isTrue());
  243. }
  244. TEST(Expression, SimplificationTest) {
  245. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  246. storm::expressions::Expression trueExpression;
  247. storm::expressions::Expression falseExpression;
  248. storm::expressions::Expression threeExpression;
  249. storm::expressions::Expression intVarExpression;
  250. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  251. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  252. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  253. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  254. storm::expressions::Expression tempExpression;
  255. storm::expressions::Expression simplifiedExpression;
  256. ASSERT_NO_THROW(tempExpression = trueExpression || intVarExpression > threeExpression);
  257. ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
  258. EXPECT_TRUE(simplifiedExpression.isTrue());
  259. ASSERT_NO_THROW(tempExpression = falseExpression && intVarExpression > threeExpression);
  260. ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
  261. EXPECT_TRUE(simplifiedExpression.isFalse());
  262. }
  263. TEST(Expression, SimpleEvaluationTest) {
  264. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  265. storm::expressions::Expression trueExpression;
  266. storm::expressions::Expression falseExpression;
  267. storm::expressions::Expression threeExpression;
  268. storm::expressions::Expression piExpression;
  269. storm::expressions::Expression boolVarExpression;
  270. storm::expressions::Expression intVarExpression;
  271. storm::expressions::Expression rationalVarExpression;
  272. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  273. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  274. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  275. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  276. ASSERT_NO_THROW(boolVarExpression = manager->declareBooleanVariable("x"));
  277. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  278. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  279. storm::expressions::Expression tempExpression;
  280. ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolVarExpression);
  281. ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation(manager));
  282. storm::expressions::SimpleValuation valuation(manager);
  283. ASSERT_NO_THROW(valuation.setBooleanValue(manager->getVariable("x"), false));
  284. ASSERT_NO_THROW(valuation.setIntegerValue(manager->getVariable("y"), 0));
  285. ASSERT_NO_THROW(valuation.setRationalValue(manager->getVariable("z"), 0));
  286. ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
  287. ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
  288. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  289. ASSERT_NO_THROW(valuation.setIntegerValue(manager->getVariable("y"), 3));
  290. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  291. ASSERT_NO_THROW(tempExpression = storm::expressions::ite(intVarExpression < threeExpression, trueExpression, falseExpression));
  292. ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
  293. ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
  294. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  295. }
  296. TEST(Expression, VisitorTest) {
  297. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  298. storm::expressions::Expression threeExpression;
  299. storm::expressions::Expression piExpression;
  300. storm::expressions::Expression intVarExpression;
  301. storm::expressions::Expression rationalVarExpression;
  302. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  303. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  304. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  305. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  306. storm::expressions::Expression tempExpression = intVarExpression + rationalVarExpression * threeExpression;
  307. storm::expressions::LinearityCheckVisitor visitor;
  308. EXPECT_TRUE(visitor.check(tempExpression));
  309. }