Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
VariableSetPredicateSplitter.cpp
Go to the documentation of this file.
2
4
7
8namespace storm {
9namespace expressions {
10
11VariableSetPredicateSplitter::VariableSetPredicateSplitter(std::set<storm::expressions::Variable> const& irrelevantVariables)
12 : irrelevantVariables(irrelevantVariables) {
13 // Intentionally left empty.
14}
15
16std::vector<storm::expressions::Expression> VariableSetPredicateSplitter::split(storm::expressions::Expression const& expression) {
17 STORM_LOG_THROW(expression.hasBooleanType(), storm::exceptions::InvalidArgumentException, "Expected predicate of boolean type.");
18
19 // Gather all atoms.
20 resultPredicates.clear();
21 expression.accept(*this, boost::none);
22
23 // Remove all boolean literals from the atoms.
24 std::vector<storm::expressions::Expression> expressionsToKeep;
25 for (auto const& atom : resultPredicates) {
26 if (!atom.isTrue() && !atom.isFalse()) {
27 expressionsToKeep.push_back(atom);
28 }
29 }
30 resultPredicates = std::move(expressionsToKeep);
31
32 return resultPredicates;
33}
34
35boost::any VariableSetPredicateSplitter::visit(IfThenElseExpression const& expression, boost::any const&) {
36 std::set<storm::expressions::Variable> conditionVariables;
37 expression.getCondition()->gatherVariables(conditionVariables);
38 bool conditionOnlyIrrelevantVariables =
39 std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), conditionVariables.begin(), conditionVariables.end());
40
41 std::set<storm::expressions::Variable> tmp;
42 std::set_intersection(conditionVariables.begin(), conditionVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
43 std::inserter(tmp, tmp.begin()));
44 bool conditionHasIrrelevantVariables = !tmp.empty();
45
46 std::set<storm::expressions::Variable> thenVariables;
47 expression.getThenExpression()->gatherVariables(thenVariables);
48 bool thenOnlyIrrelevantVariables = std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), thenVariables.begin(), thenVariables.end());
49
50 tmp.clear();
51 std::set_intersection(thenVariables.begin(), thenVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(), std::inserter(tmp, tmp.begin()));
52 bool thenHasIrrelevantVariables = !tmp.empty();
53
54 std::set<storm::expressions::Variable> elseVariables;
55 expression.getElseExpression()->gatherVariables(elseVariables);
56 bool elseOnlyIrrelevantVariables = std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), elseVariables.begin(), elseVariables.end());
57
58 tmp.clear();
59 std::set_intersection(elseVariables.begin(), elseVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(), std::inserter(tmp, tmp.begin()));
60 bool elseHasIrrelevantVariables = !tmp.empty();
61
62 if (conditionHasIrrelevantVariables || thenHasIrrelevantVariables || elseHasIrrelevantVariables) {
63 STORM_LOG_THROW(conditionOnlyIrrelevantVariables && thenOnlyIrrelevantVariables && elseOnlyIrrelevantVariables,
64 storm::exceptions::InvalidArgumentException,
65 "Cannot split expression based on variable set as variables of different type are related.");
66 } else {
67 resultPredicates.push_back(expression.toExpression());
68 }
69 return boost::any();
70}
71
72boost::any VariableSetPredicateSplitter::visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) {
73 std::set<storm::expressions::Variable> leftContainedVariables;
74 expression.getFirstOperand()->gatherVariables(leftContainedVariables);
75 bool leftOnlyIrrelevantVariables =
76 std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), leftContainedVariables.begin(), leftContainedVariables.end());
77
78 std::set<storm::expressions::Variable> tmp;
79 std::set_intersection(leftContainedVariables.begin(), leftContainedVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
80 std::inserter(tmp, tmp.begin()));
81 bool leftHasIrrelevantVariables = !tmp.empty();
82
83 std::set<storm::expressions::Variable> rightContainedVariables;
84 expression.getSecondOperand()->gatherVariables(rightContainedVariables);
85 bool rightOnlyIrrelevantVariables =
86 std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), rightContainedVariables.begin(), rightContainedVariables.end());
87
88 tmp.clear();
89 std::set_intersection(rightContainedVariables.begin(), rightContainedVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
90 std::inserter(tmp, tmp.begin()));
91 bool rightHasIrrelevantVariables = !tmp.empty();
92
93 if (leftOnlyIrrelevantVariables && rightOnlyIrrelevantVariables) {
94 return boost::any();
95 }
96
97 if (!leftHasIrrelevantVariables && !rightHasIrrelevantVariables) {
98 resultPredicates.push_back(expression.toExpression());
99 }
100
101 if (!leftHasIrrelevantVariables) {
102 resultPredicates.push_back(expression.getFirstOperand()->toExpression());
103 } else if (!leftOnlyIrrelevantVariables) {
104 return expression.getFirstOperand()->accept(*this, data);
105 }
106
107 if (!rightHasIrrelevantVariables) {
108 resultPredicates.push_back(expression.getSecondOperand()->toExpression());
109 } else if (!rightOnlyIrrelevantVariables) {
110 return expression.getSecondOperand()->accept(*this, data);
111 }
112 return boost::any();
113}
114
116 return boost::any();
117}
118
119boost::any VariableSetPredicateSplitter::visit(BinaryRelationExpression const& expression, boost::any const&) {
120 std::set<storm::expressions::Variable> leftContainedVariables;
121 expression.getFirstOperand()->gatherVariables(leftContainedVariables);
122 bool leftOnlyIrrelevantVariables =
123 std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), leftContainedVariables.begin(), leftContainedVariables.end());
124
125 std::set<storm::expressions::Variable> tmp;
126 std::set_intersection(leftContainedVariables.begin(), leftContainedVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
127 std::inserter(tmp, tmp.begin()));
128 bool leftHasIrrelevantVariables = !tmp.empty();
129
130 std::set<storm::expressions::Variable> rightContainedVariables;
131 expression.getSecondOperand()->gatherVariables(rightContainedVariables);
132 bool rightOnlyIrrelevantVariables =
133 std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), rightContainedVariables.begin(), rightContainedVariables.end());
134
135 tmp.clear();
136 std::set_intersection(rightContainedVariables.begin(), rightContainedVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
137 std::inserter(tmp, tmp.begin()));
138 bool rightHasIrrelevantVariables = !tmp.empty();
139
140 if (!leftHasIrrelevantVariables && !rightHasIrrelevantVariables) {
141 resultPredicates.push_back(expression.toExpression());
142 } else {
143 STORM_LOG_THROW(leftOnlyIrrelevantVariables && rightOnlyIrrelevantVariables, storm::exceptions::InvalidArgumentException,
144 "Cannot abstract from variable set in expression as it mixes variables of different types.");
145 }
146 return boost::any();
147}
148
149boost::any VariableSetPredicateSplitter::visit(VariableExpression const& expression, boost::any const&) {
150 if (expression.hasBooleanType() && irrelevantVariables.find(expression.getVariable()) == irrelevantVariables.end()) {
151 resultPredicates.push_back(expression.toExpression());
152 }
153 return boost::any();
154}
155
156boost::any VariableSetPredicateSplitter::visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) {
157 std::set<storm::expressions::Variable> containedVariables;
158 expression.gatherVariables(containedVariables);
159 bool onlyIrrelevantVariables = std::includes(irrelevantVariables.begin(), irrelevantVariables.end(), containedVariables.begin(), containedVariables.end());
160
161 if (onlyIrrelevantVariables) {
162 return boost::any();
163 }
164
165 std::set<storm::expressions::Variable> tmp;
166 std::set_intersection(containedVariables.begin(), containedVariables.end(), irrelevantVariables.begin(), irrelevantVariables.end(),
167 std::inserter(tmp, tmp.begin()));
168 bool hasIrrelevantVariables = !tmp.empty();
169
170 if (hasIrrelevantVariables) {
171 expression.getOperand()->accept(*this, data);
172 } else {
173 resultPredicates.push_back(expression.toExpression());
174 }
175 return boost::any();
176}
177
179 return boost::any();
180}
181
183 return boost::any();
184}
185
187 return boost::any();
188}
189
191 return boost::any();
192}
193
194} // namespace expressions
195} // namespace storm
bool hasBooleanType() const
Retrieves whether the expression has a boolean type.
Expression toExpression() const
Converts the base expression to a proper 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.
bool hasBooleanType() const
Retrieves whether the expression has a boolean return type.
boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const
Accepts the given visitor.
std::shared_ptr< BaseExpression const > getElseExpression() const
Retrieves the else expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getCondition() const
Retrieves the condition expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getThenExpression() const
Retrieves the then expression of the if-then-else 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.
virtual boost::any visit(IfThenElseExpression const &expression, boost::any const &data) override
VariableSetPredicateSplitter(std::set< storm::expressions::Variable > const &irrelevantVariables)
std::vector< storm::expressions::Expression > split(storm::expressions::Expression const &expression)
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
LabParser.cpp.
Definition cli.cpp:18