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.

191 lines
6.1 KiB

  1. /*
  2. * LtlParserTest.cpp
  3. *
  4. * Created on: 22.04.2013
  5. * Author: thomas
  6. */
  7. #include "gtest/gtest.h"
  8. #include "storm-config.h"
  9. #include "src/parser/LtlParser.h"
  10. #include "src/exceptions/WrongFormatException.h"
  11. #include "src/properties/actions/InvertAction.h"
  12. #include "src/properties/actions/SortAction.h"
  13. #include "src/properties/actions/RangeAction.h"
  14. #include "src/properties/actions/BoundAction.h"
  15. namespace ltl = storm::properties::ltl;
  16. TEST(LtlParserTest, parseApOnlyTest) {
  17. std::string input = "ap";
  18. std::shared_ptr<storm::properties::ltl::LtlFilter<double>> formula(nullptr);
  19. ASSERT_NO_THROW(
  20. formula = storm::parser::LtlParser::parseLtlFormula(input);
  21. );
  22. ASSERT_TRUE(formula->getChild()->isPropositional());
  23. ASSERT_NE(formula.get(), nullptr);
  24. ASSERT_EQ(input, formula->toString());
  25. }
  26. TEST(LtlParserTest, parsePropositionalFormulaTest) {
  27. std::string input = "!(a & b) | a & ! c";
  28. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  29. ASSERT_NO_THROW(
  30. formula = storm::parser::LtlParser::parseLtlFormula(input);
  31. );
  32. ASSERT_TRUE(formula->getChild()->isPropositional());
  33. ASSERT_NE(formula.get(), nullptr);
  34. ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString());
  35. }
  36. /*!
  37. * The following test checks whether in the formula "F & b", F is correctly interpreted as proposition instead of the
  38. * "Eventually" operator.
  39. */
  40. TEST(LtlParserTest, parseAmbiguousFormulaTest) {
  41. std::string input = "F & b";
  42. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  43. ASSERT_NO_THROW(
  44. formula = storm::parser::LtlParser::parseLtlFormula(input);
  45. );
  46. ASSERT_TRUE(formula->getChild()->isPropositional());
  47. ASSERT_NE(formula.get(), nullptr);
  48. ASSERT_EQ("(F & b)", formula->toString());
  49. }
  50. /*!
  51. * The following test checks whether in the formula "F F", F is interpreted as "eventually" operator or atomic proposition,
  52. * depending where it occurs.
  53. */
  54. TEST(LtlParserTest, parseAmbiguousFormulaTest2) {
  55. std::string input = "F F";
  56. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  57. ASSERT_NO_THROW(
  58. formula = storm::parser::LtlParser::parseLtlFormula(input);
  59. );
  60. ASSERT_FALSE(formula->getChild()->isPropositional());
  61. ASSERT_NE(formula.get(), nullptr);
  62. ASSERT_EQ("F F", formula->toString());
  63. }
  64. TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) {
  65. std::string input = "F<=5 a";
  66. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  67. ASSERT_NO_THROW(
  68. formula = storm::parser::LtlParser::parseLtlFormula(input);
  69. );
  70. ASSERT_NE(formula.get(), nullptr);
  71. ASSERT_FALSE(formula->getChild()->isPropositional());
  72. std::shared_ptr<storm::properties::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedEventually<double>>(formula->getChild());
  73. ASSERT_NE(op.get(), nullptr);
  74. ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound());
  75. ASSERT_EQ("F<=5 a", formula->toString());
  76. }
  77. TEST(LtlParserTest, parseBoundedUntilFormulaTest) {
  78. std::string input = "a U<=3 b";
  79. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  80. ASSERT_NO_THROW(
  81. formula = storm::parser::LtlParser::parseLtlFormula(input);
  82. );
  83. ASSERT_NE(formula.get(), nullptr);
  84. ASSERT_FALSE(formula->getChild()->isPropositional());
  85. std::shared_ptr<storm::properties::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedUntil<double>>(formula->getChild());
  86. ASSERT_NE(op.get(), nullptr);
  87. ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound());
  88. ASSERT_EQ("(a U<=3 b)", formula->toString());
  89. }
  90. TEST(LtlParserTest, parseLtlFilterTest) {
  91. std::string input = "filter[max; invert; bound(<, 0.5); sort(value); range(0,3)](X a)";
  92. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  93. ASSERT_NO_THROW(
  94. formula = storm::parser::LtlParser::parseLtlFormula(input)
  95. );
  96. // The parser did not falsely recognize the input as a comment.
  97. ASSERT_NE(formula, nullptr);
  98. ASSERT_FALSE(formula->getChild()->isPropositional());
  99. ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator());
  100. ASSERT_EQ(4, formula->getActionCount());
  101. ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(0)).get(), nullptr);
  102. ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(1)).get(), nullptr);
  103. ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(2)).get(), nullptr);
  104. ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(3)).get(), nullptr);
  105. // The input was parsed correctly.
  106. ASSERT_EQ("filter[max; invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](X a)", formula->toString());
  107. }
  108. TEST(LtlParserTest, commentTest) {
  109. std::string input = "// This is a comment. And this is a commented out formula: F X a";
  110. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  111. ASSERT_NO_THROW(
  112. formula = storm::parser::LtlParser::parseLtlFormula(input)
  113. );
  114. // The parser recognized the input as a comment.
  115. ASSERT_NE(nullptr, formula.get());
  116. ASSERT_EQ(nullptr, formula->getChild().get());
  117. // Test if the parser recognizes the comment at the end of a line.
  118. input = "F X a // This is a comment.";
  119. ASSERT_NO_THROW(
  120. formula = storm::parser::LtlParser::parseLtlFormula(input)
  121. );
  122. ASSERT_FALSE(formula->getChild()->isPropositional());
  123. ASSERT_EQ("F X a", formula->toString());
  124. }
  125. TEST(LtlParserTest, parseComplexUntilTest) {
  126. std::string input = "a U b U<=3 c";
  127. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  128. ASSERT_NO_THROW(
  129. formula = storm::parser::LtlParser::parseLtlFormula(input);
  130. );
  131. ASSERT_NE(formula.get(), nullptr);
  132. ASSERT_EQ("((a U b) U<=3 c)", formula->toString());
  133. }
  134. TEST(LtlParserTest, parseComplexFormulaTest) {
  135. std::string input = "a U F b | G a & F<=3 a U<=7 b // and a comment";
  136. std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr);
  137. ASSERT_NO_THROW(
  138. formula = storm::parser::LtlParser::parseLtlFormula(input);
  139. );
  140. ASSERT_NE(formula.get(), nullptr);
  141. ASSERT_EQ("(a U F (b | G (a & F<=3 (a U<=7 b))))", formula->toString());
  142. }
  143. TEST(LtlParserTest, wrongFormulaTest) {
  144. std::string input = "(a | c) & +";
  145. ASSERT_THROW(
  146. storm::parser::LtlParser::parseLtlFormula(input),
  147. storm::exceptions::WrongFormatException
  148. );
  149. }