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.

268 lines
12 KiB

  1. /*
  2. * NondeterministicSparseTransitionParserTest.cpp
  3. *
  4. * Created on: Feb 26, 2014
  5. * Author: Manuel Sascha Weiand
  6. */
  7. #include "gtest/gtest.h"
  8. #include "storm-config.h"
  9. #include "src/parser/NondeterministicSparseTransitionParser.h"
  10. #include "src/storage/SparseMatrix.h"
  11. #include "src/settings/InternalOptionMemento.h"
  12. #include "src/exceptions/FileIoException.h"
  13. #include "src/exceptions/WrongFormatException.h"
  14. TEST(NondeterministicSparseTransitionParserTest, NonExistingFile) {
  15. // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
  16. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
  17. storm::parser::NondeterministicSparseTransitionParser::Result nullInformation;
  18. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", nullInformation), storm::exceptions::FileIoException);
  19. }
  20. TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
  21. // Parse a nondeterministic transitions file and test the result.
  22. storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
  23. // Test the row mapping, i.e. at which row which state starts.
  24. ASSERT_EQ(result.rowMapping.size(), 7);
  25. ASSERT_EQ(result.rowMapping[0], 0);
  26. ASSERT_EQ(result.rowMapping[1], 4);
  27. ASSERT_EQ(result.rowMapping[2], 5);
  28. ASSERT_EQ(result.rowMapping[3], 7);
  29. ASSERT_EQ(result.rowMapping[4], 8);
  30. ASSERT_EQ(result.rowMapping[5], 9);
  31. ASSERT_EQ(result.rowMapping[6], 11);
  32. // Test the transition matrix.
  33. ASSERT_EQ(result.transitionMatrix.getColumnCount(), 6);
  34. ASSERT_EQ(result.transitionMatrix.getRowCount(), 11);
  35. ASSERT_EQ(result.transitionMatrix.getEntryCount(), 22);
  36. // Test every entry of the matrix.
  37. storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(0);
  38. ASSERT_EQ(cIter->first, 0);
  39. ASSERT_EQ(cIter->second, 0.9);
  40. cIter++;
  41. ASSERT_EQ(cIter->first, 1);
  42. ASSERT_EQ(cIter->second, 0.1);
  43. cIter++;
  44. ASSERT_EQ(cIter->first, 1);
  45. ASSERT_EQ(cIter->second, 0.2);
  46. cIter++;
  47. ASSERT_EQ(cIter->first, 2);
  48. ASSERT_EQ(cIter->second, 0.2);
  49. cIter++;
  50. ASSERT_EQ(cIter->first, 3);
  51. ASSERT_EQ(cIter->second, 0.2);
  52. cIter++;
  53. ASSERT_EQ(cIter->first, 4);
  54. ASSERT_EQ(cIter->second, 0.2);
  55. cIter++;
  56. ASSERT_EQ(cIter->first, 5);
  57. ASSERT_EQ(cIter->second, 0.2);
  58. cIter++;
  59. ASSERT_EQ(cIter->first, 5);
  60. ASSERT_EQ(cIter->second, 1);
  61. cIter++;
  62. ASSERT_EQ(cIter->first, 0);
  63. ASSERT_EQ(cIter->second, 0.1);
  64. cIter++;
  65. ASSERT_EQ(cIter->first, 4);
  66. ASSERT_EQ(cIter->second, 0.9);
  67. cIter++;
  68. ASSERT_EQ(cIter->first, 2);
  69. ASSERT_EQ(cIter->second, 1);
  70. cIter++;
  71. ASSERT_EQ(cIter->first, 2);
  72. ASSERT_EQ(cIter->second, 0.5);
  73. cIter++;
  74. ASSERT_EQ(cIter->first, 3);
  75. ASSERT_EQ(cIter->second, 0.5);
  76. cIter++;
  77. ASSERT_EQ(cIter->first, 2);
  78. ASSERT_EQ(cIter->second, 1);
  79. cIter++;
  80. ASSERT_EQ(cIter->first, 2);
  81. ASSERT_EQ(cIter->second, 0.001);
  82. cIter++;
  83. ASSERT_EQ(cIter->first, 3);
  84. ASSERT_EQ(cIter->second, 0.999);
  85. cIter++;
  86. ASSERT_EQ(cIter->first, 1);
  87. ASSERT_EQ(cIter->second, 0.7);
  88. cIter++;
  89. ASSERT_EQ(cIter->first, 4);
  90. ASSERT_EQ(cIter->second, 0.3);
  91. cIter++;
  92. ASSERT_EQ(cIter->first, 1);
  93. ASSERT_EQ(cIter->second, 0.2);
  94. cIter++;
  95. ASSERT_EQ(cIter->first, 4);
  96. ASSERT_EQ(cIter->second, 0.2);
  97. cIter++;
  98. ASSERT_EQ(cIter->first, 5);
  99. ASSERT_EQ(cIter->second, 0.6);
  100. cIter++;
  101. ASSERT_EQ(cIter->first, 5);
  102. ASSERT_EQ(cIter->second, 1);
  103. }
  104. TEST(NondeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
  105. // Parse a nondeterministic transitions file and test the result.
  106. storm::parser::NondeterministicSparseTransitionParser::Result modelInformation(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
  107. storm::storage::SparseMatrix<double> result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", modelInformation).transitionMatrix);
  108. // Test the transition matrix.
  109. ASSERT_EQ(result.getColumnCount(), 6);
  110. ASSERT_EQ(result.getRowCount(), 11);
  111. ASSERT_EQ(result.getEntryCount(), 17);
  112. // Test every entry of the matrix.
  113. storm::storage::SparseMatrix<double>::const_iterator cIter = result.begin(0);
  114. ASSERT_EQ(cIter->first, 0);
  115. ASSERT_EQ(cIter->second, 1);
  116. cIter++;
  117. ASSERT_EQ(cIter->first, 1);
  118. ASSERT_EQ(cIter->second, 30);
  119. cIter++;
  120. ASSERT_EQ(cIter->first, 1);
  121. ASSERT_EQ(cIter->second, 15.2);
  122. cIter++;
  123. ASSERT_EQ(cIter->first, 2);
  124. ASSERT_EQ(cIter->second, 75);
  125. cIter++;
  126. ASSERT_EQ(cIter->first, 5);
  127. ASSERT_EQ(cIter->second, 2.45);
  128. cIter++;
  129. ASSERT_EQ(cIter->first, 5);
  130. ASSERT_EQ(cIter->second, 1);
  131. cIter++;
  132. ASSERT_EQ(cIter->first, 0);
  133. ASSERT_EQ(cIter->second, 0.114);
  134. cIter++;
  135. ASSERT_EQ(cIter->first, 4);
  136. ASSERT_EQ(cIter->second, 90);
  137. cIter++;
  138. ASSERT_EQ(cIter->first, 2);
  139. ASSERT_EQ(cIter->second, 1);
  140. cIter++;
  141. ASSERT_EQ(cIter->first, 2);
  142. ASSERT_EQ(cIter->second, 55);
  143. cIter++;
  144. ASSERT_EQ(cIter->first, 3);
  145. ASSERT_EQ(cIter->second, 87);
  146. cIter++;
  147. ASSERT_EQ(cIter->first, 2);
  148. ASSERT_EQ(cIter->second, 13);
  149. cIter++;
  150. ASSERT_EQ(cIter->first, 3);
  151. ASSERT_EQ(cIter->second, 999);
  152. cIter++;
  153. ASSERT_EQ(cIter->first, 1);
  154. ASSERT_EQ(cIter->second, 0.7);
  155. cIter++;
  156. ASSERT_EQ(cIter->first, 4);
  157. ASSERT_EQ(cIter->second, 0.3);
  158. cIter++;
  159. ASSERT_EQ(cIter->first, 1);
  160. ASSERT_EQ(cIter->second, 0.1);
  161. cIter++;
  162. ASSERT_EQ(cIter->first, 5);
  163. ASSERT_EQ(cIter->second, 6);
  164. }
  165. TEST(NondeterministicSparseTransitionParserTest, Whitespaces) {
  166. // Test the resilience of the parser against whitespaces.
  167. // Do so by comparing the hashes of the transition matices and the rowMapping vectors element by element.
  168. storm::parser::NondeterministicSparseTransitionParser::Result correctResult(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra"));
  169. storm::parser::NondeterministicSparseTransitionParser::Result whitespaceResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_whitespaces.tra");
  170. ASSERT_EQ(correctResult.transitionMatrix.hash(), whitespaceResult.transitionMatrix.hash());
  171. ASSERT_EQ(correctResult.rowMapping.size(), whitespaceResult.rowMapping.size());
  172. for(uint_fast64_t i = 0; i < correctResult.rowMapping.size(); i++) {
  173. ASSERT_EQ(correctResult.rowMapping[i], whitespaceResult.rowMapping[i]);
  174. }
  175. // Do the same (minus the unused rowMapping) for the corresponding transition rewards file (with and without whitespaces)
  176. uint_fast64_t correctHash = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_general.trans.rew", correctResult).transitionMatrix.hash();
  177. ASSERT_EQ(correctHash, storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_whitespaces.trans.rew", whitespaceResult).transitionMatrix.hash());
  178. }
  179. TEST(NondeterministicSparseTransitionParserTest, MixedTransitionOrder) {
  180. // Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
  181. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedTransitionOrder.tra"), storm::exceptions::InvalidArgumentException);
  182. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_mixedStateOrder.tra"), storm::exceptions::InvalidArgumentException);
  183. storm::parser::NondeterministicSparseTransitionParser::Result modelInformation = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
  184. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedTransitionOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
  185. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_mixedStateOrder.trans.rew", modelInformation), storm::exceptions::InvalidArgumentException);
  186. }
  187. TEST(NondeterministicSparseTransitionParserTest, FixDeadlocks) {
  188. // Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
  189. storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
  190. // Parse a transitions file with the fixDeadlocks Flag set and test if it works.
  191. storm::parser::NondeterministicSparseTransitionParser::Result result(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"));
  192. ASSERT_EQ(result.rowMapping.size(), 8);
  193. ASSERT_EQ(result.rowMapping[5], 9);
  194. ASSERT_EQ(result.rowMapping[6], 10);
  195. ASSERT_EQ(result.rowMapping[7], 12);
  196. ASSERT_EQ(result.transitionMatrix.getColumnCount(), 7);
  197. ASSERT_EQ(result.transitionMatrix.getRowCount(), 12);
  198. ASSERT_EQ(result.transitionMatrix.getEntryCount(), 23);
  199. storm::storage::SparseMatrix<double>::const_iterator cIter = result.transitionMatrix.begin(8);
  200. ASSERT_EQ(cIter->first, 1);
  201. ASSERT_EQ(cIter->second, 0.7);
  202. cIter++;
  203. ASSERT_EQ(cIter->first, 4);
  204. ASSERT_EQ(cIter->second, 0.3);
  205. cIter++;
  206. ASSERT_EQ(cIter->first, 5);
  207. ASSERT_EQ(cIter->second, 1);
  208. cIter++;
  209. ASSERT_EQ(cIter->first, 1);
  210. ASSERT_EQ(cIter->second, 0.2);
  211. cIter++;
  212. ASSERT_EQ(cIter->first, 4);
  213. ASSERT_EQ(cIter->second, 0.2);
  214. cIter++;
  215. ASSERT_EQ(cIter->first, 5);
  216. ASSERT_EQ(cIter->second, 0.6);
  217. cIter++;
  218. ASSERT_EQ(cIter->first, 5);
  219. ASSERT_EQ(cIter->second, 1);
  220. }
  221. TEST(NondeterministicSparseTransitionParserTest, DontFixDeadlocks) {
  222. // Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
  223. storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
  224. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_deadlock.tra"), storm::exceptions::WrongFormatException);
  225. }
  226. TEST(NondeterministicSparseTransitionParserTest, DoubledLines) {
  227. // There is a redundant line in the transition file. As the transition already exists this should throw an exception.
  228. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
  229. }
  230. TEST(NondeterministicSparseTransitionParserTest, RewardForNonExistentTransition) {
  231. // First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
  232. storm::parser::NondeterministicSparseTransitionParser::Result transitionResult = storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/mdp_general.tra");
  233. // There is a reward for a transition that does not exist in the transition matrix.
  234. ASSERT_THROW(storm::parser::NondeterministicSparseTransitionParser::parseNondeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/mdp_rewardForNonExTrans.trans.rew", transitionResult), storm::exceptions::WrongFormatException);
  235. }