Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ExpressionTranslator.cpp
Go to the documentation of this file.
2
4
7
9
12
13namespace storm::gbar {
14namespace abstraction {
15
16using namespace storm::expressions;
17
18template<storm::dd::DdType DdType>
20 std::unique_ptr<storm::solver::SmtSolver>&& smtSolver)
21 : abstractionInformation(abstractionInformation),
22 equivalenceChecker(std::move(smtSolver)),
23 locationVariables(abstractionInformation.getLocationExpressionVariables()),
24 abstractedVariables(abstractionInformation.getAbstractedVariables()) {
25 equivalenceChecker.addConstraints(abstractionInformation.getConstraints());
26}
27
28template<storm::dd::DdType DdType>
30 return boost::any_cast<storm::dd::Bdd<DdType>>(expression.accept(*this, boost::none));
31}
32
33template<storm::dd::DdType DdType>
34boost::any ExpressionTranslator<DdType>::visit(IfThenElseExpression const&, boost::any const&) {
35 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
36 "Expressions of this kind are currently not supported by the abstraction expression translator.");
37}
38
39template<storm::dd::DdType DdType>
40boost::any ExpressionTranslator<DdType>::visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) {
41 // Check whether the expression is either fully contained in the location variables fragment or the abstracted
42 // variables fragment.
43 std::set<storm::expressions::Variable> variablesInExpression;
44 expression.gatherVariables(variablesInExpression);
45
46 std::set<storm::expressions::Variable> tmp;
47 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(),
48 std::inserter(tmp, tmp.begin()));
49 bool hasLocationVariables = !tmp.empty();
50
51 tmp.clear();
52 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(),
53 std::inserter(tmp, tmp.begin()));
54 bool hasAbstractedVariables = !tmp.empty();
55
56 STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException,
57 "Expressions without variables are currently not supported by the abstraction expression translator.");
58
59 if (hasAbstractedVariables && !hasLocationVariables) {
60 for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) {
61 if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) {
62 return abstractionInformation.get().encodePredicateAsSource(predicateIndex);
63 } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) {
64 return !abstractionInformation.get().encodePredicateAsSource(predicateIndex);
65 }
66 }
67
68 // At this point, none of the predicates was found to be equivalent, so we split the expression.
69 }
70
71 storm::dd::Bdd<DdType> left = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getFirstOperand()->accept(*this, data));
72 storm::dd::Bdd<DdType> right = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getSecondOperand()->accept(*this, data));
73 switch (expression.getOperatorType()) {
74 case BinaryBooleanFunctionExpression::OperatorType::And:
75 return left && right;
76 case BinaryBooleanFunctionExpression::OperatorType::Or:
77 return left || right;
78 case BinaryBooleanFunctionExpression::OperatorType::Xor:
79 return left.exclusiveOr(right);
80 case BinaryBooleanFunctionExpression::OperatorType::Implies:
81 return !left || right;
82 case BinaryBooleanFunctionExpression::OperatorType::Iff:
83 return (left && right) || (!left && !right);
84 }
85 return boost::any();
86}
87
88template<storm::dd::DdType DdType>
90 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
91 "Expressions of this kind are currently not supported by the abstraction expression translator.");
92}
93
94template<storm::dd::DdType DdType>
95boost::any ExpressionTranslator<DdType>::visit(BinaryRelationExpression const& expression, boost::any const& data) {
96 // Check whether the expression is either fully contained in the location variables fragment or the abstracted
97 // variables fragment.
98 std::set<storm::expressions::Variable> variablesInExpression;
99 expression.gatherVariables(variablesInExpression);
100
101 std::set<storm::expressions::Variable> tmp;
102 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(),
103 std::inserter(tmp, tmp.begin()));
104 bool hasLocationVariables = !tmp.empty();
105
106 tmp.clear();
107 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(),
108 std::inserter(tmp, tmp.begin()));
109 bool hasAbstractedVariables = !tmp.empty();
110
111 STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException,
112 "Expressions without variables are currently not supported by the abstraction expression translator.");
113 STORM_LOG_THROW(!hasLocationVariables || !hasAbstractedVariables, storm::exceptions::NotSupportedException,
114 "Expressions with two types (location variables and abstracted variables) of variables are currently not supported by the abstraction "
115 "expression translator.");
116
117 if (hasLocationVariables) {
118 storm::dd::Add<DdType, double> left = boost::any_cast<storm::dd::Add<DdType, double>>(expression.getFirstOperand()->accept(*this, data));
119 storm::dd::Add<DdType, double> right = boost::any_cast<storm::dd::Add<DdType, double>>(expression.getSecondOperand()->accept(*this, data));
120
121 switch (expression.getRelationType()) {
122 case RelationType::Equal:
123 return left.equals(right);
124 case RelationType::NotEqual:
125 return left.notEquals(right);
126 case RelationType::Less:
127 return left.less(right);
128 case RelationType::LessOrEqual:
129 return left.lessOrEqual(right);
130 case RelationType::Greater:
131 return left.greater(right);
132 case RelationType::GreaterOrEqual:
133 return left.greaterOrEqual(right);
134 }
135 } else {
136 for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) {
137 if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) {
138 return abstractionInformation.get().encodePredicateAsSource(predicateIndex);
139 } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) {
140 return !abstractionInformation.get().encodePredicateAsSource(predicateIndex);
141 }
142 }
143
144 // At this point, none of the predicates was found to be equivalent, but there is no need to split as the subexpressions are not valid predicates.
145
146 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
147 "Expressions of this kind are currently not supported by the abstraction expression translator (" << expression << ").");
148 }
149 return boost::any();
150}
151
152template<storm::dd::DdType DdType>
153boost::any ExpressionTranslator<DdType>::visit(VariableExpression const& expression, boost::any const&) {
154 if (abstractedVariables.find(expression.getVariable()) != abstractedVariables.end()) {
155 for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) {
156 if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) {
157 return abstractionInformation.get().encodePredicateAsSource(predicateIndex);
158 } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) {
159 return !abstractionInformation.get().encodePredicateAsSource(predicateIndex);
160 }
161 }
162
163 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
164 "Expressions of this kind are currently not supported by the abstraction expression translator.");
165 } else {
166 return abstractionInformation.get().getDdManager().template getIdentity<double>(
167 abstractionInformation.get().getDdLocationMetaVariable(expression.getVariable(), true));
168 }
169}
170
171template<storm::dd::DdType DdType>
172boost::any ExpressionTranslator<DdType>::visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) {
173 // Check whether the expression is either fully contained in the location variables fragment or the abstracted
174 // variables fragment.
175 std::set<storm::expressions::Variable> variablesInExpression;
176 expression.gatherVariables(variablesInExpression);
177
178 std::set<storm::expressions::Variable> tmp;
179 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(),
180 std::inserter(tmp, tmp.begin()));
181 bool hasLocationVariables = !tmp.empty();
182
183 tmp.clear();
184 std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(),
185 std::inserter(tmp, tmp.begin()));
186 bool hasAbstractedVariables = !tmp.empty();
187
188 STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException,
189 "Expressions without variables are currently not supported by the abstraction expression translator.");
190
191 if (hasAbstractedVariables && !hasLocationVariables) {
192 for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) {
193 if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) {
194 return abstractionInformation.get().encodePredicateAsSource(predicateIndex);
195 } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) {
196 return !abstractionInformation.get().encodePredicateAsSource(predicateIndex);
197 }
198 }
199
200 // At this point, none of the predicates was found to be equivalent, so we split the expression.
201 }
202
203 storm::dd::Bdd<DdType> sub = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getOperand()->accept(*this, data));
204 switch (expression.getOperatorType()) {
205 case UnaryBooleanFunctionExpression::OperatorType::Not:
206 return !sub;
207 }
208 return boost::any();
209}
210
211template<storm::dd::DdType DdType>
213 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
214 "Expressions of this kind are currently not supported by the abstraction expression translator.");
215}
216
217template<storm::dd::DdType DdType>
218boost::any ExpressionTranslator<DdType>::visit(BooleanLiteralExpression const& expression, boost::any const&) {
219 if (expression.isTrue()) {
220 return abstractionInformation.get().getDdManager().getBddOne();
221 } else {
222 return abstractionInformation.get().getDdManager().getBddZero();
223 }
224}
225
226template<storm::dd::DdType DdType>
227boost::any ExpressionTranslator<DdType>::visit(IntegerLiteralExpression const& expression, boost::any const&) {
228 return abstractionInformation.get().getDdManager().template getConstant<double>(expression.getValue());
229}
230
231template<storm::dd::DdType DdType>
233 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
234 "Expressions of this kind are currently not supported by the abstraction expression translator.");
235}
236
239
240} // namespace abstraction
241} // namespace storm::gbar
Bdd< LibraryType > equals(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one that have identical function values.
Definition Add.cpp:96
Bdd< LibraryType > lessOrEqual(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are les...
Definition Add.cpp:111
Bdd< LibraryType > greater(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are gre...
Definition Add.cpp:116
Bdd< LibraryType > greaterOrEqual(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are gre...
Definition Add.cpp:121
Bdd< LibraryType > notEquals(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one that have distinct function values.
Definition Add.cpp:101
Bdd< LibraryType > less(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are les...
Definition Add.cpp:106
Bdd< LibraryType > exclusiveOr(Bdd< LibraryType > const &other) const
Performs a logical exclusive-or of the current and the given BDD.
Definition Bdd.cpp:157
Expression toExpression() const
Converts the base expression to a proper expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
std::shared_ptr< BaseExpression const > const & getSecondOperand() const
Retrieves the second operand of the expression.
std::shared_ptr< BaseExpression const > const & getFirstOperand() const
Retrieves the first operand of the expression.
virtual void gatherVariables(std::set< storm::expressions::Variable > &variables) const override
Retrieves the set of all variables that appear in the expression.
RelationType getRelationType() const
Retrieves the relation associated with the expression.
virtual bool isTrue() const override
Checks if the expression is equal to the boolean literal true.
void addConstraints(std::vector< storm::expressions::Expression > const &constraints)
boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const
Accepts the given visitor.
int_fast64_t getValue() const
Retrieves the value of the integer literal.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
virtual void gatherVariables(std::set< storm::expressions::Variable > &variables) const override
Retrieves the set of all variables that appear in the expression.
Variable const & getVariable() const
Retrieves the variable associated with this expression.
std::vector< storm::expressions::Expression > const & getConstraints() const
Retrieves a list of expressions that constrain the valid variable values.
ExpressionTranslator(AbstractionInformation< DdType > &abstractionInformation, std::unique_ptr< storm::solver::SmtSolver > &&smtSolver)
storm::dd::Bdd< DdType > translate(storm::expressions::Expression const &expression)
virtual boost::any visit(storm::expressions::IfThenElseExpression const &expression, boost::any const &data)
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30