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.

219 lines
14 KiB

  1. #include "src/logic/FragmentChecker.h"
  2. #include "src/logic/Formulas.h"
  3. namespace storm {
  4. namespace logic {
  5. class InheritedInformation {
  6. public:
  7. InheritedInformation(FragmentSpecification const& fragmentSpecification) : fragmentSpecification(fragmentSpecification) {
  8. // Intentionally left empty.
  9. }
  10. FragmentSpecification const& getSpecification() const {
  11. return fragmentSpecification;
  12. }
  13. private:
  14. FragmentSpecification const& fragmentSpecification;
  15. };
  16. bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const {
  17. bool result = boost::any_cast<bool>(f.accept(*this, InheritedInformation(specification)));
  18. if (specification.isOperatorAtTopLevelRequired()) {
  19. result &= f.isOperatorFormula();
  20. }
  21. return result;
  22. }
  23. boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
  24. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  25. return inherited.getSpecification().areAtomicExpressionFormulasAllowed();
  26. }
  27. boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const {
  28. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  29. return inherited.getSpecification().areAtomicLabelFormulasAllowed();
  30. }
  31. boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
  32. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  33. bool result = inherited.getSpecification().areBinaryBooleanStateFormulasAllowed();
  34. result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
  35. result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
  36. return result;
  37. }
  38. boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
  39. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  40. return inherited.getSpecification().areBooleanLiteralFormulasAllowed();
  41. }
  42. boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const {
  43. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  44. bool result = inherited.getSpecification().areBoundedUntilFormulasAllowed();
  45. if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
  46. result = result && !f.getLeftSubformula().isPathFormula();
  47. result = result && !f.getRightSubformula().isPathFormula();
  48. }
  49. if (f.hasDiscreteTimeBound()) {
  50. result = result && inherited.getSpecification().areStepBoundedUntilFormulasAllowed();
  51. } else {
  52. result = result && inherited.getSpecification().areTimeBoundedUntilFormulasAllowed();
  53. }
  54. result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
  55. result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
  56. return result;
  57. }
  58. boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const {
  59. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  60. bool result = true;
  61. if (f.isConditionalProbabilityFormula()) {
  62. result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed();
  63. } else if (f.isConditionalRewardFormula()) {
  64. result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed();
  65. }
  66. if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) {
  67. if (f.isConditionalProbabilityFormula()) {
  68. result = result && f.getSubformula().isReachabilityProbabilityFormula() && f.getConditionFormula().isReachabilityProbabilityFormula();
  69. } else if (f.isConditionalRewardFormula()) {
  70. result = result && f.getSubformula().isReachabilityRewardFormula() && f.getConditionFormula().isEventuallyFormula();
  71. }
  72. }
  73. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  74. result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data));
  75. return result;
  76. }
  77. boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
  78. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  79. return inherited.getSpecification().areCumulativeRewardFormulasAllowed();
  80. }
  81. boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const {
  82. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  83. bool result = true;
  84. if (f.isReachabilityProbabilityFormula()) {
  85. result = inherited.getSpecification().areReachabilityProbabilityFormulasAllowed();
  86. if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
  87. result = result && !f.getSubformula().isPathFormula();
  88. }
  89. } else if (f.isReachabilityRewardFormula()) {
  90. result = result && inherited.getSpecification().areReachabilityRewardFormulasAllowed();
  91. result = result && f.getSubformula().isStateFormula();
  92. } else if (f.isReachabilityTimeFormula()) {
  93. result = result && inherited.getSpecification().areReachbilityTimeFormulasAllowed();
  94. result = result && f.getSubformula().isStateFormula();
  95. }
  96. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  97. return result;
  98. }
  99. boost::any FragmentChecker::visit(TimeOperatorFormula const& f, boost::any const& data) const {
  100. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  101. bool result = inherited.getSpecification().areTimeOperatorsAllowed();
  102. result = result && (!f.hasQualitativeResult() || inherited.getSpecification().areQualitativeOperatorResultsAllowed());
  103. result = result && (!f.hasQuantitativeResult() || inherited.getSpecification().areQuantitativeOperatorResultsAllowed());
  104. result = result && f.getSubformula().isTimePathFormula();
  105. result = result && (inherited.getSpecification().isVarianceMeasureTypeAllowed() || f.getMeasureType() == RewardMeasureType::Expectation);
  106. if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
  107. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
  108. } else {
  109. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  110. }
  111. return result;
  112. }
  113. boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const {
  114. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  115. bool result = inherited.getSpecification().areGloballyFormulasAllowed();
  116. if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
  117. result = result && !f.getSubformula().isPathFormula();
  118. }
  119. result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  120. return result;
  121. }
  122. boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
  123. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  124. return inherited.getSpecification().areInstantaneousRewardFormulasAllowed();
  125. }
  126. boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
  127. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  128. bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed();
  129. result = result && f.getSubformula().isStateFormula();
  130. if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
  131. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
  132. } else {
  133. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  134. }
  135. return result;
  136. }
  137. boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
  138. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  139. return inherited.getSpecification().areLongRunAverageRewardFormulasAllowed();
  140. }
  141. boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const {
  142. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  143. bool result = inherited.getSpecification().areNextFormulasAllowed();
  144. if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
  145. result = result && !f.getSubformula().isPathFormula();
  146. }
  147. result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  148. return result;
  149. }
  150. boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
  151. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  152. bool result = inherited.getSpecification().areProbabilityOperatorsAllowed();
  153. result = result && (!f.hasQualitativeResult() || inherited.getSpecification().areQualitativeOperatorResultsAllowed());
  154. result = result && (!f.hasQuantitativeResult() || inherited.getSpecification().areQuantitativeOperatorResultsAllowed());
  155. result = result && (f.getSubformula().isProbabilityPathFormula() || f.getSubformula().isConditionalProbabilityFormula());
  156. if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
  157. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
  158. } else {
  159. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  160. }
  161. return result;
  162. }
  163. boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const {
  164. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  165. bool result = inherited.getSpecification().areRewardOperatorsAllowed();
  166. result = result && (!f.hasQualitativeResult() || inherited.getSpecification().areQualitativeOperatorResultsAllowed());
  167. result = result && (!f.hasQuantitativeResult() || inherited.getSpecification().areQuantitativeOperatorResultsAllowed());
  168. result = result && (f.getSubformula().isRewardPathFormula() || f.getSubformula().isConditionalRewardFormula());
  169. result = result && (inherited.getSpecification().isVarianceMeasureTypeAllowed() || f.getMeasureType() == RewardMeasureType::Expectation);
  170. if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
  171. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
  172. } else {
  173. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  174. }
  175. return result;
  176. }
  177. boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
  178. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  179. bool result = inherited.getSpecification().areUnaryBooleanStateFormulasAllowed();
  180. result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
  181. return result;
  182. }
  183. boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const {
  184. InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
  185. bool result = inherited.getSpecification().areUntilFormulasAllowed();
  186. if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
  187. result = result && !f.getLeftSubformula().isPathFormula();
  188. result = result && !f.getRightSubformula().isPathFormula();
  189. }
  190. result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
  191. result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
  192. return result;
  193. }
  194. }
  195. }