diff --git a/src/storm/logic/ExtractMaximalStateFormulasVisitor.cpp b/src/storm/logic/ExtractMaximalStateFormulasVisitor.cpp new file mode 100644 index 000000000..d6f465027 --- /dev/null +++ b/src/storm/logic/ExtractMaximalStateFormulasVisitor.cpp @@ -0,0 +1,170 @@ +#include "storm/logic/ExtractMaximalStateFormulasVisitor.h" + +#include "storm/logic/Formulas.h" + +#include "storm/exceptions/InvalidOperationException.h" + +namespace storm { + namespace logic { + + ExtractMaximalStateFormulasVisitor::ExtractMaximalStateFormulasVisitor(std::vector& extractedFormulas) : extractedFormulas(extractedFormulas), nestingLevel(0) { + } + + std::shared_ptr ExtractMaximalStateFormulasVisitor::extract(PathFormula const& f, std::vector& extractedFormulas) { + ExtractMaximalStateFormulasVisitor visitor(extractedFormulas); + boost::any result = f.accept(visitor, boost::any()); + return boost::any_cast>(result); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(BinaryBooleanPathFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr left = boost::any_cast>(f.getLeftSubformula().accept(*this, data)); + if (left->hasQualitativeResult()) { + left = extract(left); + } + + std::shared_ptr right = boost::any_cast>(f.getRightSubformula().accept(*this, data)); + if (right->hasQualitativeResult()) { + right = extract(right); + } + + return std::static_pointer_cast(std::make_shared(f.getOperator(), left, right)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + STORM_LOG_THROW(true, storm::exceptions::InvalidOperationException, "Can not extract maximal state formulas for bounded until"); + // never reached + return boost::any(); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(EventuallyFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr sub = boost::any_cast>(f.getSubformula().accept(*this, data)); + if (sub->hasQualitativeResult()) { + sub = extract(sub); + } + + return std::static_pointer_cast(std::make_shared(sub)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(GloballyFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr sub = boost::any_cast>(f.getSubformula().accept(*this, data)); + if (sub->hasQualitativeResult()) { + sub = extract(sub); + } + + return std::static_pointer_cast(std::make_shared(sub)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(NextFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr sub = boost::any_cast>(f.getSubformula().accept(*this, data)); + if (sub->hasQualitativeResult()) { + sub = extract(sub); + } + + return std::static_pointer_cast(std::make_shared(sub)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(UnaryBooleanPathFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr sub = boost::any_cast>(f.getSubformula().accept(*this, data)); + if (sub->hasQualitativeResult()) { + sub = extract(sub); + } + + return std::static_pointer_cast(std::make_shared(f.getOperator(), sub)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(UntilFormula const& f, boost::any const& data) const { + if (nestingLevel > 0) { + return CloneVisitor::visit(f, data); + } + + std::shared_ptr left = boost::any_cast>(f.getLeftSubformula().accept(*this, data)); + if (left->hasQualitativeResult()) { + left = extract(left); + } + + std::shared_ptr right = boost::any_cast>(f.getRightSubformula().accept(*this, data)); + if (right->hasQualitativeResult()) { + right = extract(right); + } + + return std::static_pointer_cast(std::make_shared(left, right)); + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(TimeOperatorFormula const& f, boost::any const& data) const { + incrementNestingLevel(); + boost::any result = CloneVisitor::visit(f, data); + decrementNestingLevel(); + return result; + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const { + incrementNestingLevel(); + boost::any result = CloneVisitor::visit(f, data); + decrementNestingLevel(); + return result; + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(MultiObjectiveFormula const& f, boost::any const& data) const { + incrementNestingLevel(); + boost::any result = CloneVisitor::visit(f, data); + decrementNestingLevel(); + return result; + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const { + incrementNestingLevel(); + boost::any result = CloneVisitor::visit(f, data); + decrementNestingLevel(); + return result; + } + + boost::any ExtractMaximalStateFormulasVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const { + incrementNestingLevel(); + boost::any result = CloneVisitor::visit(f, data); + decrementNestingLevel(); + return result; + } + + std::shared_ptr ExtractMaximalStateFormulasVisitor::extract(std::shared_ptr f) const { + std::string label = "p" + std::to_string(extractedFormulas.size()); + + const_cast&>(extractedFormulas).emplace_back(label, f); + + return std::make_shared(label); + } + + void ExtractMaximalStateFormulasVisitor::incrementNestingLevel() const { + const_cast(nestingLevel)++; + } + void ExtractMaximalStateFormulasVisitor::decrementNestingLevel() const { + STORM_LOG_ASSERT(nestingLevel > 0, "Illegal nesting level decrement"); + const_cast(nestingLevel)--; + } + + + } +} diff --git a/src/storm/logic/ExtractMaximalStateFormulasVisitor.h b/src/storm/logic/ExtractMaximalStateFormulasVisitor.h new file mode 100644 index 000000000..e3bd1cea5 --- /dev/null +++ b/src/storm/logic/ExtractMaximalStateFormulasVisitor.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "storm/logic/CloneVisitor.h" + +namespace storm { + namespace logic { + + class ExtractMaximalStateFormulasVisitor : public CloneVisitor { + public: + typedef std::pair> LabelFormulaPair; + + static std::shared_ptr extract(PathFormula const& f, std::vector& extractedFormulas); + + virtual boost::any visit(BinaryBooleanPathFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; + virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(NextFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UnaryBooleanPathFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override; + + virtual boost::any visit(TimeOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(MultiObjectiveFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override; + + private: + ExtractMaximalStateFormulasVisitor(std::vector& extractedFormulas); + + std::shared_ptr extract(std::shared_ptr f) const; + void incrementNestingLevel() const; + void decrementNestingLevel() const; + + std::vector& extractedFormulas; + std::size_t nestingLevel; + }; + + } +} +