Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
OrderedAssignments.cpp
Go to the documentation of this file.
2
6
7namespace storm {
8namespace jani {
9
10OrderedAssignments::OrderedAssignments(std::vector<Assignment> const& assignments) {
11 for (auto const& assignment : assignments) {
12 add(assignment);
13 }
14}
15
17 add(assignment);
18}
19
21 OrderedAssignments result;
22 for (auto const& assignment : allAssignments) {
23 result.add(Assignment(*assignment));
24 }
25 return result;
26}
27
28bool OrderedAssignments::add(Assignment const& assignment, bool addToExisting) {
29 // If the element is contained in this set of assignment, nothing needs to be added.
30 if (!addToExisting && this->contains(assignment)) {
31 return false;
32 }
33
34 // Otherwise, we find the spot to insert it.
35 auto it = lowerBound(assignment, allAssignments);
36
37 // Check if an assignment to this variable is already present
38 if (it != allAssignments.end() && assignment.getLValue() == (*it)->getLValue()) {
39 STORM_LOG_THROW(addToExisting && assignment.getLValue().isVariable() && assignment.getExpressionVariable().hasNumericalType(),
40 storm::exceptions::InvalidArgumentException,
41 "Cannot add assignment ('" << assignment.getAssignedExpression() << "') as an assignment ('" << (*it)->getAssignedExpression()
42 << "') to LValue '" << (*it)->getLValue() << "' already exists.");
43 (*it)->setAssignedExpression((*it)->getAssignedExpression() + assignment.getAssignedExpression());
44 } else {
45 // Finally, insert the new element in the correct vectors.
46 auto elementToInsert = std::make_shared<Assignment>(assignment);
47 allAssignments.emplace(it, elementToInsert);
48 if (assignment.isTransient()) {
49 auto transientIt = lowerBound(assignment, transientAssignments);
50 transientAssignments.emplace(transientIt, elementToInsert);
51 } else {
52 auto nonTransientIt = lowerBound(assignment, nonTransientAssignments);
53 nonTransientAssignments.emplace(nonTransientIt, elementToInsert);
54 }
55 }
56
57 return true;
58}
59
60bool OrderedAssignments::remove(Assignment const& assignment) {
61 // If the element is contained in this set of assignment, nothing needs to be removed.
62 if (!this->contains(assignment)) {
63 return false;
64 }
65
66 // Otherwise, we find the element to delete.
67 auto it = lowerBound(assignment, allAssignments);
68 STORM_LOG_ASSERT(it != allAssignments.end(), "Invalid iterator, expected existing element.");
69 STORM_LOG_ASSERT(assignment == **it, "Wrong iterator position.");
70 allAssignments.erase(it);
71
72 if (assignment.isTransient()) {
73 auto transientIt = lowerBound(assignment, transientAssignments);
74 STORM_LOG_ASSERT(transientIt != transientAssignments.end(), "Invalid iterator, expected existing element.");
75 STORM_LOG_ASSERT(assignment == **transientIt, "Wrong iterator position.");
76 transientAssignments.erase(transientIt);
77 } else {
78 auto nonTransientIt = lowerBound(assignment, nonTransientAssignments);
79 STORM_LOG_ASSERT(nonTransientIt != nonTransientAssignments.end(), "Invalid iterator, expected existing element.");
80 STORM_LOG_ASSERT(assignment == **nonTransientIt, "Wrong iterator position.");
81 nonTransientAssignments.erase(nonTransientIt);
82 }
83 return true;
84}
85
86bool OrderedAssignments::hasMultipleLevels(bool onlyTransient) const {
87 if ((onlyTransient ? transientAssignments : allAssignments).empty()) {
88 return false;
89 }
90 return getLowestLevel(onlyTransient) != 0 || getHighestLevel(onlyTransient) != 0;
91}
92
93bool OrderedAssignments::empty(bool onlyTransient) const {
94 if (onlyTransient) {
95 return transientAssignments.empty();
96 }
97 return allAssignments.empty();
98}
99
101 allAssignments.clear();
102 transientAssignments.clear();
103 nonTransientAssignments.clear();
104}
105
107 return allAssignments.size();
108}
109
110int64_t OrderedAssignments::getLowestLevel(bool onlyTransient) const {
111 auto const& as = onlyTransient ? transientAssignments : allAssignments;
112 assert(!as.empty());
113 return as.front()->getLevel();
114}
115
116int64_t OrderedAssignments::getHighestLevel(bool onlyTransient) const {
117 auto const& as = onlyTransient ? transientAssignments : allAssignments;
118 assert(!as.empty());
119 return as.back()->getLevel();
120}
121
122bool OrderedAssignments::contains(Assignment const& assignment) const {
123 auto it = lowerBound(assignment, allAssignments);
124 if (it != allAssignments.end() && assignment == **it) {
125 return true;
126 } else {
127 return false;
128 }
129}
130
131OrderedAssignments OrderedAssignments::simplifyLevels(bool synchronous, VariableSet const& localVars, bool first) const {
132 bool changed = false;
133 if (first) {
134 std::vector<Assignment> newAssignments;
135 for (uint64_t i = 0; i < allAssignments.size(); ++i) {
136 auto const& iLValue = allAssignments.at(i)->getLValue();
137 if (synchronous && !localVars.hasVariable(iLValue.getVariable())) {
138 newAssignments.push_back(*(allAssignments.at(i)));
139 continue;
140 }
141 bool readBeforeWrite = true;
142 for (uint64_t j = i + 1; j < allAssignments.size(); ++j) {
143 if (allAssignments.at(j)->getAssignedExpression().containsVariable({iLValue.getVariable().getExpressionVariable()})) {
144 // is read.
145 break;
146 }
147 if (iLValue == allAssignments.at(j)->getLValue()) {
148 // is written, has not been read before
149 readBeforeWrite = false;
150 break;
151 }
152 }
153 if (readBeforeWrite) {
154 newAssignments.push_back(*(allAssignments.at(i)));
155 } else {
156 changed = true;
157 }
158 }
159 if (changed) {
160 return OrderedAssignments(newAssignments).simplifyLevels(synchronous, localVars, false);
161 }
162 }
163
164 std::vector<Assignment> newAssignments;
165 for (auto const& assignment : allAssignments) {
166 newAssignments.push_back(*assignment);
167 if (synchronous && !localVars.hasVariable(assignment->getLValue().getVariable())) {
168 continue;
169 }
170 if (assignment->getLevel() == 0) {
171 continue;
172 }
173 uint64_t assNr = upperBound(assignment->getLevel() - 1);
174 if (assNr == isWrittenBeforeAssignment(assignment->getLValue(), assNr)) {
175 if (assNr == isReadBeforeAssignment(assignment->getLValue(), assNr)) {
176 newAssignments.back().setLevel(0);
177 changed = true;
178 }
179 }
180 }
181 if (changed) {
182 return OrderedAssignments(newAssignments).simplifyLevels(synchronous, localVars, false);
183 } else {
184 return *this;
185 }
186}
187
189 return detail::ConstAssignments(allAssignments.begin(), allAssignments.end());
190}
191
193 return detail::ConstAssignments(transientAssignments.begin(), transientAssignments.end());
194}
195
197 return detail::ConstAssignments(nonTransientAssignments.begin(), nonTransientAssignments.end());
198}
199
201 bool operator()(std::shared_ptr<Assignment> const& left, int64_t const& right) const {
202 return left->getLevel() < right;
203 }
204 bool operator()(int64_t const& left, std::shared_ptr<Assignment> const& right) const {
205 return left < right->getLevel();
206 }
207};
208
210 auto begin = std::lower_bound(transientAssignments.begin(), transientAssignments.end(), assignmentLevel, AssignmentLevelToLevelComparator());
211 auto end = std::upper_bound(begin, transientAssignments.end(), assignmentLevel, AssignmentLevelToLevelComparator());
213}
214
216 auto begin = std::lower_bound(nonTransientAssignments.begin(), nonTransientAssignments.end(), assignmentLevel, AssignmentLevelToLevelComparator());
217 auto end = std::upper_bound(begin, nonTransientAssignments.end(), assignmentLevel, AssignmentLevelToLevelComparator());
219}
220
222 return !transientAssignments.empty();
223}
224
228
232
236
240
241void OrderedAssignments::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution,
242 bool const substituteTranscendentalNumbers) {
243 for (auto& assignment : allAssignments) {
244 assignment->substitute(substitution, substituteTranscendentalNumbers);
245 }
246}
247
248void OrderedAssignments::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) {
249 std::vector<Assignment> newAssignments;
250 for (auto& assignment : allAssignments) {
251 newAssignments.emplace_back(assignment->getLValue().changeAssignmentVariables(remapping), assignment->getAssignedExpression(), assignment->getLevel());
252 }
253 *this = OrderedAssignments(newAssignments);
254}
255
256std::vector<std::shared_ptr<Assignment>>::const_iterator OrderedAssignments::lowerBound(Assignment const& assignment,
257 std::vector<std::shared_ptr<Assignment>> const& assignments) {
258 return std::lower_bound(assignments.begin(), assignments.end(), assignment, storm::jani::AssignmentPartialOrderByLevelAndLValue());
259}
260
261uint64_t OrderedAssignments::isReadBeforeAssignment(LValue const& lValue, uint64_t assignmentNumber, uint64_t start) const {
262 Variable const& var = lValue.getVariable();
263 // TODO: do this more carefully
264 STORM_LOG_WARN_COND(lValue.isVariable(), "Called a method that is not optimized for arrays.");
265 for (uint64_t i = start; i < assignmentNumber; i++) {
266 if (allAssignments.at(i)->getAssignedExpression().containsVariable({var.getExpressionVariable()})) {
267 return i;
268 }
269 }
270 return assignmentNumber;
271}
272
273uint64_t OrderedAssignments::isWrittenBeforeAssignment(LValue const& lValue, uint64_t assignmentNumber, uint64_t start) const {
274 for (uint64_t i = start; i < assignmentNumber; i++) {
275 if (allAssignments.at(i)->getLValue() == lValue) {
276 return i;
277 }
278 }
279 return assignmentNumber;
280}
281
282uint64_t OrderedAssignments::upperBound(int64_t index) const {
283 uint64_t result = 0;
284 for (auto const& assignment : allAssignments) {
285 if (assignment->getLevel() > index) {
286 return result;
287 }
288 ++result;
289 }
290 return result;
291}
292
294 bool result = true;
295 for (auto const& assignment : getAllAssignments()) {
296 result &= assignment.isLinear();
297 }
298 return result;
299}
300
302 for (std::vector<std::shared_ptr<Assignment>>::const_iterator it = allAssignments.cbegin(); it != allAssignments.cend(); ++it) {
303 if (it != lowerBound(**it, allAssignments)) {
304 return false;
305 }
306 }
307 return true;
308}
309
310std::ostream& operator<<(std::ostream& stream, OrderedAssignments const& assignments) {
311 stream << "[\n";
312 for (auto const& e : assignments.allAssignments) {
313 stream << "\t" << *e << '\n';
314 }
315 stream << "]";
316 return stream;
317}
318} // namespace jani
319} // namespace storm
boost::transform_iterator< Dereferencer< value_type >, input_iterator > iterator
bool hasNumericalType() const
Checks whether the variable is of numerical type.
Definition Variable.cpp:75
storm::expressions::Expression const & getAssignedExpression() const
Retrieves the expression whose value is assigned to the target variable.
storm::jani::LValue const & getLValue() const
Retrieves the lValue that is written in this assignment.
storm::expressions::Variable const & getExpressionVariable() const
Retrieves the expression variable that is written in this assignment.
bool isTransient() const
Retrieves whether the assignment assigns to a transient variable.
bool isVariable() const
Definition LValue.cpp:20
bool hasMultipleLevels(bool onlyTransient=false) const
Checks whether the assignments have several levels.
void substitute(std::map< storm::expressions::Variable, storm::expressions::Expression > const &substitution, bool const substituteTranscendentalNumbers)
Substitutes all variables in all expressions according to the given substitution.
void changeAssignmentVariables(std::map< Variable const *, std::reference_wrapper< Variable const > > const &remapping)
Changes all variables in assignments based on the given mapping.
bool empty(bool onlyTransient=false) const
Retrieves whether this set of assignments is empty.
OrderedAssignments simplifyLevels(bool synchronous, VariableSet const &localVars, bool first=true) const
Produces a new OrderedAssignments object with simplified leveling.
std::size_t getNumberOfAssignments() const
Retrieves the total number of assignments.
detail::Assignments::iterator begin()
Returns an iterator to the assignments.
int64_t getLowestLevel(bool onlyTransient=false) const
Retrieves the lowest level among all assignments.
detail::ConstAssignments getNonTransientAssignments() const
Returns all non-transient assignments in this set of assignments.
detail::ConstAssignments getTransientAssignments() const
Returns all transient assignments in this set of assignments.
bool checkOrder() const
Checks whether this ordered assignment is in the correct order.
int64_t getHighestLevel(bool onlyTransient=false) const
Retrieves the highest level among all assignments.
bool areLinear() const
Checks the assignments for linearity.
bool hasTransientAssignment() const
Retrieves whether the set of assignments has at least one transient assignment.
bool remove(Assignment const &assignment)
Removes the given assignment from this set of assignments.
detail::ConstAssignments getAllAssignments() const
Returns all assignments in this set of assignments.
OrderedAssignments clone() const
OrderedAssignments(std::vector< Assignment > const &assignments=std::vector< Assignment >())
Creates an ordered set of assignments.
detail::Assignments::iterator end()
Returns an iterator past the end of the assignments.
void clear()
Removes all assignments from this set.
bool add(Assignment const &assignment, bool addToExisting=false)
Adds the given assignment to the set of assignments.
bool contains(Assignment const &assignment) const
Retrieves whether the given assignment is contained in this set of assignments.
bool hasVariable(std::string const &name) const
Retrieves whether this variable set contains a variable with the given name.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
storm::adapters::DereferenceIteratorAdapter< std::vector< std::shared_ptr< Assignment > > const > ConstAssignments
std::ostream & operator<<(std::ostream &stream, Assignment const &assignment)
LabParser.cpp.
Definition cli.cpp:18
bool operator()(int64_t const &left, std::shared_ptr< Assignment > const &right) const
bool operator()(std::shared_ptr< Assignment > const &left, int64_t const &right) const
This functor enables ordering the assignments first by the assignment level and then by lValue.
Definition Assignment.h:110