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.

211 lines
8.2 KiB

  1. /*
  2. * MarkovAutomatonParserTest.cpp
  3. *
  4. * Created on: 03.12.2013
  5. * Author: Manuel Sascha Weiand
  6. */
  7. #include "gtest/gtest.h"
  8. #include "storm-config.h"
  9. #include "src/settings/Settings.h"
  10. #include <vector>
  11. #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
  12. #include "src/utility/cstring.h"
  13. #include "src/parser/MarkovAutomatonParser.h"
  14. #include "src/settings/InternalOptionMemento.h"
  15. #include "src/exceptions/WrongFormatException.h"
  16. #include "src/exceptions/FileIoException.h"
  17. #define STATE_COUNT 6
  18. #define CHOICE_COUNT 7
  19. TEST(MarkovAutomatonSparseTransitionParserTest, NonExistingFile) {
  20. // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
  21. ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
  22. }
  23. TEST(MarkovAutomatonSparseTransitionParserTest, BasicParsing) {
  24. // The file that will be used for the test.
  25. std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra";
  26. // Execute the parser.
  27. storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  28. // Build the actual transition matrix.
  29. storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
  30. // Test all sizes and counts.
  31. ASSERT_EQ(STATE_COUNT, transitionMatrix.getColumnCount());
  32. ASSERT_EQ(CHOICE_COUNT, transitionMatrix.getRowCount());
  33. ASSERT_EQ(12, transitionMatrix.getEntryCount());
  34. ASSERT_EQ(6, transitionMatrix.getRowGroupCount());
  35. ASSERT_EQ(7, transitionMatrix.getRowGroupIndices().size());
  36. ASSERT_EQ(CHOICE_COUNT, result.markovianChoices.size());
  37. ASSERT_EQ(STATE_COUNT, result.markovianStates.size());
  38. ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
  39. ASSERT_EQ(STATE_COUNT, result.exitRates.size());
  40. // Test the general structure of the transition system (that will be an Markov automaton).
  41. // Test the mapping between states and transition matrix rows.
  42. ASSERT_EQ(0, transitionMatrix.getRowGroupIndices()[0]);
  43. ASSERT_EQ(1, transitionMatrix.getRowGroupIndices()[1]);
  44. ASSERT_EQ(2, transitionMatrix.getRowGroupIndices()[2]);
  45. ASSERT_EQ(3, transitionMatrix.getRowGroupIndices()[3]);
  46. ASSERT_EQ(4, transitionMatrix.getRowGroupIndices()[4]);
  47. ASSERT_EQ(6, transitionMatrix.getRowGroupIndices()[5]);
  48. ASSERT_EQ(7, transitionMatrix.getRowGroupIndices()[6]);
  49. // Test the Markovian states.
  50. ASSERT_TRUE(result.markovianStates.get(0));
  51. ASSERT_FALSE(result.markovianStates.get(1));
  52. ASSERT_TRUE(result.markovianStates.get(2));
  53. ASSERT_FALSE(result.markovianStates.get(3));
  54. ASSERT_FALSE(result.markovianStates.get(4));
  55. ASSERT_FALSE(result.markovianStates.get(5));
  56. // Test the exit rates. These have to be 0 for all non-Markovian states.
  57. ASSERT_EQ(2, result.exitRates[0]);
  58. ASSERT_EQ(0, result.exitRates[1]);
  59. ASSERT_EQ(15, result.exitRates[2]);
  60. ASSERT_EQ(0, result.exitRates[3]);
  61. ASSERT_EQ(0, result.exitRates[4]);
  62. ASSERT_EQ(0, result.exitRates[5]);
  63. // Finally, test the transition matrix itself.
  64. storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
  65. ASSERT_EQ(2, cIter->second);
  66. cIter++;
  67. ASSERT_EQ(1, cIter->second);
  68. cIter++;
  69. ASSERT_EQ(1, cIter->second);
  70. cIter++;
  71. ASSERT_EQ(2, cIter->second);
  72. cIter++;
  73. ASSERT_EQ(4, cIter->second);
  74. cIter++;
  75. ASSERT_EQ(8, cIter->second);
  76. cIter++;
  77. ASSERT_EQ(0.5, cIter->second);
  78. cIter++;
  79. ASSERT_EQ(0.5, cIter->second);
  80. cIter++;
  81. ASSERT_EQ(1, cIter->second);
  82. cIter++;
  83. ASSERT_EQ(0.5, cIter->second);
  84. cIter++;
  85. ASSERT_EQ(0.5, cIter->second);
  86. cIter++;
  87. ASSERT_EQ(1, cIter->second);
  88. cIter++;
  89. ASSERT_EQ(transitionMatrix.end(), cIter);
  90. }
  91. TEST(MarkovAutomatonSparseTransitionParserTest, Whitespaces) {
  92. // The file that will be used for the test.
  93. std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespaces.tra";
  94. // Execute the parser.
  95. storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  96. // Build the actual transition matrix.
  97. storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build());
  98. // Test all sizes and counts.
  99. ASSERT_EQ(STATE_COUNT, transitionMatrix.getColumnCount());
  100. ASSERT_EQ(CHOICE_COUNT, transitionMatrix.getRowCount());
  101. ASSERT_EQ(12, transitionMatrix.getEntryCount());
  102. ASSERT_EQ(6, transitionMatrix.getRowGroupCount());
  103. ASSERT_EQ(7, transitionMatrix.getRowGroupIndices().size());
  104. ASSERT_EQ(CHOICE_COUNT, result.markovianChoices.size());
  105. ASSERT_EQ(STATE_COUNT, result.markovianStates.size());
  106. ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
  107. ASSERT_EQ(STATE_COUNT, result.exitRates.size());
  108. // Test the general structure of the transition system (that will be an Markov automaton).
  109. // Test the mapping between states and transition matrix rows.
  110. ASSERT_EQ(0, transitionMatrix.getRowGroupIndices()[0]);
  111. ASSERT_EQ(1, transitionMatrix.getRowGroupIndices()[1]);
  112. ASSERT_EQ(2, transitionMatrix.getRowGroupIndices()[2]);
  113. ASSERT_EQ(3, transitionMatrix.getRowGroupIndices()[3]);
  114. ASSERT_EQ(4, transitionMatrix.getRowGroupIndices()[4]);
  115. ASSERT_EQ(6, transitionMatrix.getRowGroupIndices()[5]);
  116. ASSERT_EQ(7, transitionMatrix.getRowGroupIndices()[6]);
  117. // Test the Markovian states.
  118. ASSERT_TRUE(result.markovianStates.get(0));
  119. ASSERT_FALSE(result.markovianStates.get(1));
  120. ASSERT_TRUE(result.markovianStates.get(2));
  121. ASSERT_FALSE(result.markovianStates.get(3));
  122. ASSERT_FALSE(result.markovianStates.get(4));
  123. ASSERT_FALSE(result.markovianStates.get(5));
  124. // Test the exit rates. These have to be 0 for all non-Markovian states.
  125. ASSERT_EQ(2, result.exitRates[0]);
  126. ASSERT_EQ(0, result.exitRates[1]);
  127. ASSERT_EQ(15, result.exitRates[2]);
  128. ASSERT_EQ(0, result.exitRates[3]);
  129. ASSERT_EQ(0, result.exitRates[4]);
  130. ASSERT_EQ(0, result.exitRates[5]);
  131. // Finally, test the transition matrix itself.
  132. storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
  133. ASSERT_EQ(2, cIter->second);
  134. cIter++;
  135. ASSERT_EQ(1, cIter->second);
  136. cIter++;
  137. ASSERT_EQ(1, cIter->second);
  138. cIter++;
  139. ASSERT_EQ(2, cIter->second);
  140. cIter++;
  141. ASSERT_EQ(4, cIter->second);
  142. cIter++;
  143. ASSERT_EQ(8, cIter->second);
  144. cIter++;
  145. ASSERT_EQ(0.5, cIter->second);
  146. cIter++;
  147. ASSERT_EQ(0.5, cIter->second);
  148. cIter++;
  149. ASSERT_EQ(1, cIter->second);
  150. cIter++;
  151. ASSERT_EQ(0.5, cIter->second);
  152. cIter++;
  153. ASSERT_EQ(0.5, cIter->second);
  154. cIter++;
  155. ASSERT_EQ(1, cIter->second);
  156. cIter++;
  157. ASSERT_EQ(transitionMatrix.end(), cIter);
  158. }
  159. TEST(MarkovAutomatonSparseTransitionParserTest, FixDeadlocks) {
  160. // Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
  161. storm::settings::InternalOptionMemento setDeadlockOption("fixDeadlocks", true);
  162. // Parse a Markov Automaton transition file with the fixDeadlocks Flag set and test if it works.
  163. storm::parser::MarkovAutomatonSparseTransitionParser::Result result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock.tra");
  164. // Test if the result is consistent with the parsed Markov Automaton.
  165. storm::storage::SparseMatrix<double> resultMatrix(result.transitionMatrixBuilder.build());
  166. ASSERT_EQ(STATE_COUNT + 1, resultMatrix.getColumnCount());
  167. ASSERT_EQ(13, resultMatrix.getEntryCount());
  168. ASSERT_EQ(7, resultMatrix.getRowGroupCount());
  169. ASSERT_EQ(8, resultMatrix.getRowGroupIndices().size());
  170. ASSERT_EQ(CHOICE_COUNT +1, result.markovianChoices.size());
  171. ASSERT_EQ(STATE_COUNT +1, result.markovianStates.size());
  172. ASSERT_EQ(2, result.markovianStates.getNumberOfSetBits());
  173. ASSERT_EQ(STATE_COUNT + 1, result.exitRates.size());
  174. }
  175. TEST(MarkovAutomatonSparseTransitionParserTest, DontFixDeadlocks) {
  176. // Try to parse a Markov Automaton transition file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
  177. storm::settings::InternalOptionMemento unsetDeadlockOption("fixDeadlocks", false);
  178. ASSERT_THROW(storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_deadlock.tra"), storm::exceptions::WrongFormatException);
  179. }