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.

255 lines
9.1 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 <cmath>
  11. #include <vector>
  12. #include "src/parser/MarkovAutomatonSparseTransitionParser.h"
  13. #include "src/parser/SparseStateRewardParser.h"
  14. #include "src/parser/Parser.h"
  15. #include "src/parser/MarkovAutomatonParser.h"
  16. #define STATE_COUNT 6
  17. #define CHOICE_COUNT 7
  18. TEST(MarkovAutomatonSparseTransitionParserTest, BasicParseTest) {
  19. // The file that will be used for the test.
  20. std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra";
  21. // Execute the parser.
  22. storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  23. // Build the actual transition matrix.
  24. storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
  25. // Test all sizes and counts.
  26. ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
  27. ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
  28. ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
  29. ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
  30. ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
  31. ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
  32. ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
  33. ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
  34. // Test the general structure of the transition system (that will be an Markov automaton).
  35. // Test the mapping between states and transition matrix rows.
  36. ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
  37. ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
  38. ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
  39. ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
  40. ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
  41. ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
  42. ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
  43. // Test the Markovian states.
  44. ASSERT_TRUE(result.markovianStates.get(0));
  45. ASSERT_FALSE(result.markovianStates.get(1));
  46. ASSERT_TRUE(result.markovianStates.get(2));
  47. ASSERT_FALSE(result.markovianStates.get(3));
  48. ASSERT_FALSE(result.markovianStates.get(4));
  49. ASSERT_FALSE(result.markovianStates.get(5));
  50. // Test the exit rates. These have to be 0 for all non-Markovian states.
  51. ASSERT_EQ(result.exitRates[0], 2);
  52. ASSERT_EQ(result.exitRates[1], 0);
  53. ASSERT_EQ(result.exitRates[2], 15);
  54. ASSERT_EQ(result.exitRates[3], 0);
  55. ASSERT_EQ(result.exitRates[4], 0);
  56. ASSERT_EQ(result.exitRates[5], 0);
  57. // Finally, test the transition matrix itself.
  58. storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
  59. ASSERT_EQ(cIter->second, 2);
  60. cIter++;
  61. ASSERT_EQ(cIter->second, 1);
  62. cIter++;
  63. ASSERT_EQ(cIter->second, 1);
  64. cIter++;
  65. ASSERT_EQ(cIter->second, 2);
  66. cIter++;
  67. ASSERT_EQ(cIter->second, 4);
  68. cIter++;
  69. ASSERT_EQ(cIter->second, 8);
  70. cIter++;
  71. ASSERT_EQ(cIter->second, 0.5);
  72. cIter++;
  73. ASSERT_EQ(cIter->second, 0.5);
  74. cIter++;
  75. ASSERT_EQ(cIter->second, 1);
  76. cIter++;
  77. ASSERT_EQ(cIter->second, 0.5);
  78. cIter++;
  79. ASSERT_EQ(cIter->second, 0.5);
  80. cIter++;
  81. ASSERT_EQ(cIter->second, 1);
  82. cIter++;
  83. ASSERT_EQ(transitionMatrix.end(), cIter);
  84. }
  85. TEST(MarkovAutomatonSparseTransitionParserTest, WhiteSpaceTest) {
  86. // The file that will be used for the test.
  87. std::string filename = STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_whitespace_input_01.tra";
  88. // Execute the parser.
  89. storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  90. // Build the actual transition matrix.
  91. storm::storage::SparseMatrix<double> transitionMatrix(result.transitionMatrixBuilder.build(0,0));
  92. // Test all sizes and counts.
  93. ASSERT_EQ(transitionMatrix.getColumnCount(), STATE_COUNT);
  94. ASSERT_EQ(transitionMatrix.getRowCount(), CHOICE_COUNT);
  95. ASSERT_EQ(transitionMatrix.getEntryCount(), 12);
  96. ASSERT_EQ(result.markovianChoices.size(), CHOICE_COUNT);
  97. ASSERT_EQ(result.markovianStates.size(), STATE_COUNT);
  98. ASSERT_EQ(result.markovianStates.getNumberOfSetBits(), 2);
  99. ASSERT_EQ(result.exitRates.size(), STATE_COUNT);
  100. ASSERT_EQ(result.nondeterministicChoiceIndices.size(), 7);
  101. // Test the general structure of the transition system (that will be an Markov automaton).
  102. // Test the mapping between states and transition matrix rows.
  103. ASSERT_EQ(result.nondeterministicChoiceIndices[0], 0);
  104. ASSERT_EQ(result.nondeterministicChoiceIndices[1], 1);
  105. ASSERT_EQ(result.nondeterministicChoiceIndices[2], 2);
  106. ASSERT_EQ(result.nondeterministicChoiceIndices[3], 3);
  107. ASSERT_EQ(result.nondeterministicChoiceIndices[4], 4);
  108. ASSERT_EQ(result.nondeterministicChoiceIndices[5], 6);
  109. ASSERT_EQ(result.nondeterministicChoiceIndices[6], 7);
  110. // Test the Markovian states.
  111. ASSERT_TRUE(result.markovianStates.get(0));
  112. ASSERT_FALSE(result.markovianStates.get(1));
  113. ASSERT_TRUE(result.markovianStates.get(2));
  114. ASSERT_FALSE(result.markovianStates.get(3));
  115. ASSERT_FALSE(result.markovianStates.get(4));
  116. ASSERT_FALSE(result.markovianStates.get(5));
  117. // Test the exit rates. These have to be 0 for all non-Markovian states.
  118. ASSERT_EQ(result.exitRates[0], 2);
  119. ASSERT_EQ(result.exitRates[1], 0);
  120. ASSERT_EQ(result.exitRates[2], 15);
  121. ASSERT_EQ(result.exitRates[3], 0);
  122. ASSERT_EQ(result.exitRates[4], 0);
  123. ASSERT_EQ(result.exitRates[5], 0);
  124. // Finally, test the transition matrix itself.
  125. storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
  126. ASSERT_EQ(cIter->second, 2);
  127. cIter++;
  128. ASSERT_EQ(cIter->second, 1);
  129. cIter++;
  130. ASSERT_EQ(cIter->second, 1);
  131. cIter++;
  132. ASSERT_EQ(cIter->second, 2);
  133. cIter++;
  134. ASSERT_EQ(cIter->second, 4);
  135. cIter++;
  136. ASSERT_EQ(cIter->second, 8);
  137. cIter++;
  138. ASSERT_EQ(cIter->second, 0.5);
  139. cIter++;
  140. ASSERT_EQ(cIter->second, 0.5);
  141. cIter++;
  142. ASSERT_EQ(cIter->second, 1);
  143. cIter++;
  144. ASSERT_EQ(cIter->second, 0.5);
  145. cIter++;
  146. ASSERT_EQ(cIter->second, 0.5);
  147. cIter++;
  148. ASSERT_EQ(cIter->second, 1);
  149. cIter++;
  150. ASSERT_EQ(transitionMatrix.end(), cIter);
  151. }
  152. //TODO: Deadlock Test. I am quite sure that the deadlock state handling does not behave quite right.
  153. // Find a way to test this by manipulating the fixDeadlocks flag of the settings.
  154. /*
  155. TEST(MarkovAutomatonSparseTransitionParserTest, DeadlockTest) {
  156. // Save the fixDeadlocks flag, since it will be manipulated during the test.
  157. bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
  158. storm::settings::Settings::getInstance()->set("fixDeadlocks");
  159. // The file that will be used for the test.
  160. std::string filename = "/functional/parser/tra_files/ma_general_input_01.tra";
  161. storm::parser::MarkovAutomatonSparseTransitionParser::ResultType result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  162. // Test if the result of the first pass has been transfered correctly
  163. ASSERT_EQ(result.transitionMatrix.colCount, 7);
  164. ASSERT_EQ(result.transitionMatrix.nonZeroEntryCount, 8);
  165. ASSERT_EQ(result.markovianChoices.getNumberOfSetBits(), 2);
  166. // Test the general structure of the transition system (that will be an Markov automaton).
  167. //TODO
  168. //Do the test again but this time without the fixDeadlock flag. This should throw an exception.
  169. storm::settings::Settings::getInstance()->unset("fixDeadlocks");
  170. bool thrown = false;
  171. try {
  172. // Parse the file, again.
  173. result = storm::parser::MarkovAutomatonSparseTransitionParser::parseMarkovAutomatonTransitions(filename);
  174. } catch(Exception &exception) {
  175. // Print the exception and remember that it was thrown.
  176. exception.print(std::cout);
  177. thrown = true;
  178. }
  179. ASSERT_TRUE(thrown);
  180. // Reset the fixDeadlocks flag to its original value.
  181. if(fixDeadlocks) {
  182. storm::settings::Settings::getInstance()->set("fixDeadlocks");
  183. }
  184. }*/
  185. double round(double val, int precision)
  186. {
  187. std::stringstream s;
  188. s << std::setprecision(precision) << std::setiosflags(std::ios_base::fixed) << val;
  189. s >> val;
  190. return val;
  191. }
  192. TEST(SparseStateRewardParserTest, BasicParseTest) {
  193. // Get the parsing result.
  194. std::vector<double> result = storm::parser::SparseStateRewardParser::parseSparseStateReward(100, STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/state_reward_parser_basic.state.rew");
  195. // Now test if the correct value were parsed.
  196. for(int i = 0; i < 100; i++) {
  197. ASSERT_EQ(std::round(result[i]) , std::round(2*i + 15/13*i*i - 1.5/(i+0.1) + 15.7));
  198. }
  199. }
  200. TEST(MarkovAutomatonParserTest, BasicParseTest) {
  201. // Get the parsing result.
  202. storm::models::MarkovAutomaton<double> result = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general_input_01.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general_input_01.lab", STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/ma_general_input_01.state.rew", "");
  203. // Test sizes and counts.
  204. ASSERT_EQ(result.getNumberOfStates(), STATE_COUNT);
  205. ASSERT_EQ(result.getNumberOfChoices(), CHOICE_COUNT);
  206. ASSERT_EQ(result.getNumberOfTransitions(), 12);
  207. // Test
  208. std::vector<double> rates = result.getExitRates();
  209. ASSERT_EQ(rates[0], 2);
  210. }