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.

365 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. 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)) };
  235. storm::expressions::Expression substitutedExpression;
  236. ASSERT_NO_THROW(substitutedExpression = tempExpression.substitute(substution));
  237. EXPECT_TRUE(substitutedExpression.simplify().isTrue());
  238. }
  239. TEST(Expression, SimplificationTest) {
  240. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  241. storm::expressions::Expression trueExpression;
  242. storm::expressions::Expression falseExpression;
  243. storm::expressions::Expression threeExpression;
  244. storm::expressions::Expression intVarExpression;
  245. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  246. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  247. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  248. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  249. storm::expressions::Expression tempExpression;
  250. storm::expressions::Expression simplifiedExpression;
  251. ASSERT_NO_THROW(tempExpression = trueExpression || intVarExpression > threeExpression);
  252. ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
  253. EXPECT_TRUE(simplifiedExpression.isTrue());
  254. ASSERT_NO_THROW(tempExpression = falseExpression && intVarExpression > threeExpression);
  255. ASSERT_NO_THROW(simplifiedExpression = tempExpression.simplify());
  256. EXPECT_TRUE(simplifiedExpression.isFalse());
  257. }
  258. TEST(Expression, SimpleEvaluationTest) {
  259. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  260. storm::expressions::Expression trueExpression;
  261. storm::expressions::Expression falseExpression;
  262. storm::expressions::Expression threeExpression;
  263. storm::expressions::Expression piExpression;
  264. storm::expressions::Expression boolVarExpression;
  265. storm::expressions::Expression intVarExpression;
  266. storm::expressions::Expression rationalVarExpression;
  267. ASSERT_NO_THROW(trueExpression = manager->boolean(true));
  268. ASSERT_NO_THROW(falseExpression = manager->boolean(false));
  269. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  270. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  271. ASSERT_NO_THROW(boolVarExpression = manager->declareBooleanVariable("x"));
  272. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  273. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  274. storm::expressions::Expression tempExpression;
  275. ASSERT_NO_THROW(tempExpression = (intVarExpression < threeExpression || boolVarExpression) && boolVarExpression);
  276. ASSERT_NO_THROW(storm::expressions::SimpleValuation valuation(manager));
  277. storm::expressions::SimpleValuation valuation(manager);
  278. ASSERT_NO_THROW(valuation.setBooleanValue(manager->getVariable("x"), false));
  279. ASSERT_NO_THROW(valuation.setIntegerValue(manager->getVariable("y"), 0));
  280. ASSERT_NO_THROW(valuation.setRationalValue(manager->getVariable("z"), 0));
  281. ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
  282. ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
  283. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  284. ASSERT_NO_THROW(valuation.setIntegerValue(manager->getVariable("y"), 3));
  285. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  286. ASSERT_NO_THROW(tempExpression = storm::expressions::ite(intVarExpression < threeExpression, trueExpression, falseExpression));
  287. ASSERT_THROW(tempExpression.evaluateAsDouble(&valuation), storm::exceptions::InvalidTypeException);
  288. ASSERT_THROW(tempExpression.evaluateAsInt(&valuation), storm::exceptions::InvalidTypeException);
  289. EXPECT_FALSE(tempExpression.evaluateAsBool(&valuation));
  290. }
  291. TEST(Expression, VisitorTest) {
  292. std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
  293. storm::expressions::Expression threeExpression;
  294. storm::expressions::Expression piExpression;
  295. storm::expressions::Expression intVarExpression;
  296. storm::expressions::Expression rationalVarExpression;
  297. ASSERT_NO_THROW(threeExpression = manager->integer(3));
  298. ASSERT_NO_THROW(piExpression = manager->rational(3.14));
  299. ASSERT_NO_THROW(intVarExpression = manager->declareIntegerVariable("y"));
  300. ASSERT_NO_THROW(rationalVarExpression = manager->declareRationalVariable("z"));
  301. storm::expressions::Expression tempExpression = intVarExpression + rationalVarExpression * threeExpression;
  302. storm::expressions::LinearityCheckVisitor visitor;
  303. EXPECT_TRUE(visitor.check(tempExpression));
  304. }