Storm 1.10.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
Update.cpp
Go to the documentation of this file.
1#include "Update.h"
2
3#include <algorithm>
4#include <boost/algorithm/string/join.hpp>
7
10
11namespace storm {
12namespace prism {
13Update::Update(uint_fast64_t globalIndex, storm::expressions::Expression const& likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments,
14 std::string const& filename, uint_fast64_t lineNumber)
15 : Update(globalIndex, std::make_pair(likelihoodExpression, storm::expressions::Expression()), assignments, filename, lineNumber) {
16 // Intentionally left empty.
17}
18
22bool isValidLikelihoodSimpl(storm::expressions::Expression const& simplifiedExpression) {
23 return !simplifiedExpression.isLiteral() || simplifiedExpression.evaluateAsRational() >= 0;
24}
25
27 if (!expression.isInitialized()) {
28 return true; // Uninitialized expressions are considered valid.
29 }
30 auto simplified = expression.simplify();
31 return isValidLikelihoodSimpl(simplified);
32}
33
34Update::Update(uint_fast64_t globalIndex, ExpressionPair const& likelihoodExpressionInterval, std::vector<storm::prism::Assignment> const& assignments,
35 std::string const& filename, uint_fast64_t lineNumber)
36 : LocatedInformation(filename, lineNumber),
37 likelihoodExpressions(likelihoodExpressionInterval),
38 assignments(assignments),
39 variableToAssignmentIndexMap(),
40 globalIndex(globalIndex) {
41 STORM_LOG_ASSERT(likelihoodExpressions.first.isInitialized(), "likelihoodExpression must be initialized");
42 // Note: likelihoodExpressions.second might be uninitialized in which case we're having a non-interval likelihood
43 STORM_LOG_ASSERT(isValidLikelihood(likelihoodExpressions.first),
44 "Negative likelihood expressions are not allowed. Got " << likelihoodExpressions.first << ".");
45 STORM_LOG_ASSERT(isValidLikelihood(likelihoodExpressions.second),
46 "Negative likelihood expressions are not allowed. Got " << likelihoodExpressions.second << ".");
47 std::sort(this->assignments.begin(), this->assignments.end(), [](storm::prism::Assignment const& assignment1, storm::prism::Assignment const& assignment2) {
48 bool smaller = assignment1.getVariable().getType().isBooleanType() && !assignment2.getVariable().getType().isBooleanType();
49 if (!smaller) {
50 smaller = assignment1.getVariable() < assignment2.getVariable();
51 }
52 return smaller;
53 });
54 this->createAssignmentMapping();
55}
56
57bool Update::isLikelihoodInterval() const {
58 return likelihoodExpressions.second.isInitialized();
59}
60
61storm::expressions::Expression const& Update::getLikelihoodExpression() const {
62 STORM_LOG_ASSERT(!isLikelihoodInterval(), "Cannot retrieve likelihood expression of an interval update.");
63 return likelihoodExpressions.first;
64}
65
66typename Update::ExpressionPair const& Update::getLikelihoodExpressionInterval() const {
67 STORM_LOG_ASSERT(isLikelihoodInterval(), "Cannot retrieve likelihood expressions of non-interval update.");
68 return likelihoodExpressions;
69}
70
71std::size_t Update::getNumberOfAssignments() const {
72 return this->assignments.size();
73}
74
75std::vector<storm::prism::Assignment> const& Update::getAssignments() const {
76 return this->assignments;
77}
78
79std::vector<storm::prism::Assignment>& Update::getAssignments() {
80 return this->assignments;
81}
82
83storm::prism::Assignment const& Update::getAssignment(std::string const& variableName) const {
84 auto const& variableIndexPair = this->variableToAssignmentIndexMap.find(variableName);
85 STORM_LOG_THROW(variableIndexPair != this->variableToAssignmentIndexMap.end(), storm::exceptions::OutOfRangeException,
86 "Variable '" << variableName << "' is not assigned in update.");
87 return this->getAssignments()[variableIndexPair->second];
88}
89
90std::map<storm::expressions::Variable, storm::expressions::Expression> Update::getAsVariableToExpressionMap() const {
91 std::map<storm::expressions::Variable, storm::expressions::Expression> result;
92
93 for (auto const& assignment : this->getAssignments()) {
94 result.emplace(assignment.getVariable(), assignment.getExpression());
95 }
96
97 return result;
98}
99
100uint_fast64_t Update::getGlobalIndex() const {
101 return this->globalIndex;
102}
103
104void Update::createAssignmentMapping() {
105 this->variableToAssignmentIndexMap.clear();
106 for (uint_fast64_t assignmentIndex = 0; assignmentIndex < this->getAssignments().size(); ++assignmentIndex) {
107 this->variableToAssignmentIndexMap[this->getAssignments()[assignmentIndex].getVariableName()] = assignmentIndex;
108 }
109}
110
111Update Update::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
112 std::vector<Assignment> newAssignments;
113 newAssignments.reserve(this->getNumberOfAssignments());
114 for (auto const& assignment : this->getAssignments()) {
115 newAssignments.emplace_back(assignment.substitute(substitution));
116 }
117 auto subsAndSimpl = [&substitution](storm::expressions::Expression const& expr) {
118 auto res = expr.substitute(substitution).simplify();
119 STORM_LOG_THROW(isValidLikelihoodSimpl(res), storm::exceptions::IllegalArgumentException,
120 "Substitution yielding negative probabilities in '" << expr << "' are not allowed.");
121 return res;
122 };
123 if (isLikelihoodInterval()) {
124 ExpressionPair newLikelihoodExpression(subsAndSimpl(this->getLikelihoodExpressionInterval().first),
125 subsAndSimpl(this->getLikelihoodExpressionInterval().second));
126 return Update(this->getGlobalIndex(), newLikelihoodExpression, newAssignments, this->getFilename(), this->getLineNumber());
127 } else {
128 auto newLikelihoodExpression = subsAndSimpl(this->getLikelihoodExpression());
129 return Update(this->getGlobalIndex(), newLikelihoodExpression, newAssignments, this->getFilename(), this->getLineNumber());
130 }
131}
132
133Update Update::substituteNonStandardPredicates() const {
134 std::vector<Assignment> newAssignments;
135 newAssignments.reserve(this->getNumberOfAssignments());
136 for (auto const& assignment : this->getAssignments()) {
137 newAssignments.emplace_back(assignment.substituteNonStandardPredicates());
138 }
139 auto subsAndSimpl = [](storm::expressions::Expression const& expr) {
140 auto res = expr.substituteNonStandardPredicates().simplify();
141 STORM_LOG_THROW(isValidLikelihoodSimpl(res), storm::exceptions::IllegalArgumentException,
142 "Predicate substitution yielding negative probabilities in '" << expr << "' are not allowed.");
143 return res;
144 };
145 if (isLikelihoodInterval()) {
146 ExpressionPair newLikelihoodExpression(subsAndSimpl(this->getLikelihoodExpressionInterval().first),
147 subsAndSimpl(this->getLikelihoodExpressionInterval().second));
148 return Update(this->getGlobalIndex(), newLikelihoodExpression, newAssignments, this->getFilename(), this->getLineNumber());
149 } else {
150 auto newLikelihoodExpression = subsAndSimpl(this->getLikelihoodExpression());
151 return Update(this->getGlobalIndex(), newLikelihoodExpression, newAssignments, this->getFilename(), this->getLineNumber());
152 }
153}
154
155Update Update::removeIdentityAssignments() const {
156 std::vector<Assignment> newAssignments;
157 newAssignments.reserve(getNumberOfAssignments());
158 for (auto const& ass : this->assignments) {
159 if (!ass.isIdentity()) {
160 newAssignments.push_back(ass);
161 }
162 }
163 return Update(this->globalIndex, this->likelihoodExpressions, newAssignments, getFilename(), getLineNumber());
164}
165
166Update Update::simplify() const {
167 std::vector<Assignment> newAssignments;
168 newAssignments.reserve(getNumberOfAssignments());
169 for (auto const& ass : this->assignments) {
170 Assignment newAssignment(ass.getVariable(), ass.getExpression().simplify().reduceNesting(), ass.getFilename(), ass.getLineNumber());
171 if (!newAssignment.isIdentity()) {
172 newAssignments.push_back(std::move(newAssignment));
173 }
174 }
175 if (isLikelihoodInterval()) {
176 ExpressionPair simplLikelihoodExpr(getLikelihoodExpressionInterval().first.simplify().reduceNesting(),
177 getLikelihoodExpressionInterval().second.simplify().reduceNesting());
178 return Update(this->globalIndex, simplLikelihoodExpr, newAssignments, getFilename(), getLineNumber());
179 } else {
180 return Update(this->globalIndex, getLikelihoodExpression().simplify().reduceNesting(), newAssignments, getFilename(), getLineNumber());
181 }
182}
183
184std::ostream& operator<<(std::ostream& stream, Update const& update) {
185 if (update.isLikelihoodInterval()) {
186 stream << "[" << update.getLikelihoodExpressionInterval().first << ", " << update.getLikelihoodExpressionInterval().second << "] : ";
187 } else {
188 stream << update.getLikelihoodExpression() << " : ";
189 }
190 if (update.getAssignments().empty()) {
191 stream << "true";
192 } else {
193 std::vector<std::string> assignmentsAsStrings;
194 std::for_each(update.getAssignments().cbegin(), update.getAssignments().cend(), [&assignmentsAsStrings](Assignment const& assignment) {
195 std::stringstream stream;
196 stream << assignment;
197 assignmentsAsStrings.push_back(stream.str());
198 });
199 stream << boost::algorithm::join(assignmentsAsStrings, " & ");
200 }
201 return stream;
202}
203
204} // namespace prism
205} // namespace storm
Expression simplify() const
Simplifies the expression according to some basic rules.
storm::RationalNumber evaluateAsRational() const
Evaluates the expression and returns the resulting rational number.
bool isLiteral() const
Retrieves whether the expression is a literal.
bool isInitialized() const
Checks whether the object encapsulates a base-expression.
bool isIdentity() const
Checks whether the assignment is an identity (lhs equals rhs)
Update substituteNonStandardPredicates() const
Definition Update.cpp:133
bool isLikelihoodInterval() const
Definition Update.cpp:57
Update substitute(std::map< storm::expressions::Variable, storm::expressions::Expression > const &substitution) const
Substitutes all identifiers in the update according to the given map.
Definition Update.cpp:111
Update simplify() const
Simplifies the update in various ways (also removes identity assignments)
Definition Update.cpp:166
std::pair< storm::expressions::Expression, storm::expressions::Expression > ExpressionPair
Definition Update.h:13
ExpressionPair const & getLikelihoodExpressionInterval() const
Retrieves the two expression for the interval likelihood of this update.
Definition Update.cpp:66
std::vector< storm::prism::Assignment > const & getAssignments() const
Retrieves a reference to the map of variable names to their respective assignments.
Definition Update.cpp:75
storm::expressions::Expression const & getLikelihoodExpression() const
Retrieves the expression for the likelihood of this update.
Definition Update.cpp:61
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
bool isValidLikelihood(storm::expressions::Expression const &expression)
Definition Update.cpp:26
bool isValidLikelihoodSimpl(storm::expressions::Expression const &simplifiedExpression)
helper to assert valid likelihood expressions
Definition Update.cpp:22
LabParser.cpp.