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.

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