Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
StateValuations.cpp
Go to the documentation of this file.
2
3#include <boost/algorithm/string/join.hpp>
4
6
8
10
14
15namespace storm {
16namespace storage {
17namespace sparse {
18
19StateValuations::StateValuation::StateValuation(std::vector<bool>&& booleanValues, std::vector<int64_t>&& integerValues,
20 std::vector<storm::RationalNumber>&& rationalValues, std::vector<int64_t>&& observationLabelValues)
21 : booleanValues(std::move(booleanValues)),
22 integerValues(std::move(integerValues)),
23 rationalValues(std::move(rationalValues)),
24 observationLabelValues(std::move(observationLabelValues)) {
25 // Intentionally left empty
26}
27
28typename StateValuations::StateValuation const& StateValuations::getValuation(storm::storage::sparse::state_type const& stateIndex) const {
29 STORM_LOG_ASSERT(stateIndex < valuations.size(), "Invalid state index.");
30 STORM_LOG_ASSERT(assertValuation(valuations[stateIndex]), "Invalid state valuations");
31 return valuations[stateIndex];
32}
33
34StateValuations::StateValueIterator::StateValueIterator(typename std::map<storm::expressions::Variable, uint64_t>::const_iterator variableIt,
35 typename std::map<std::string, uint64_t>::const_iterator labelIt,
36 typename std::map<storm::expressions::Variable, uint64_t>::const_iterator variableBegin,
37 typename std::map<storm::expressions::Variable, uint64_t>::const_iterator variableEnd,
38 typename std::map<std::string, uint64_t>::const_iterator labelBegin,
39 typename std::map<std::string, uint64_t>::const_iterator labelEnd, StateValuation const* valuation)
40 : variableIt(variableIt),
41 labelIt(labelIt),
42 variableBegin(variableBegin),
43 variableEnd(variableEnd),
44 labelBegin(labelBegin),
45 labelEnd(labelEnd),
46 valuation(valuation) {
47 // Intentionally left empty.
48}
49
51 return variableIt != variableEnd;
52}
53
55 return variableIt == variableEnd;
56}
57
59 STORM_LOG_ASSERT(isVariableAssignment(), "Does not point to a variable");
60 return variableIt->first;
61}
63 STORM_LOG_ASSERT(isLabelAssignment(), "Does not point to a label");
64 return labelIt->first;
65}
67 return isVariableAssignment() && getVariable().hasBooleanType();
68}
70 return isVariableAssignment() && getVariable().hasIntegerType();
71}
73 return isVariableAssignment() && getVariable().hasRationalType();
74}
75
77 if (isVariableAssignment()) {
78 return getVariable().getName();
79 } else {
80 return getLabel();
81 }
82}
83
85 STORM_LOG_ASSERT(isBoolean(), "Variable has no boolean type.");
86 return valuation->booleanValues[variableIt->second];
87}
88
90 STORM_LOG_ASSERT(isInteger(), "Variable has no integer type.");
91 return valuation->integerValues[variableIt->second];
92}
93
95 STORM_LOG_ASSERT(isLabelAssignment(), "Not a label assignment");
96 STORM_LOG_ASSERT(labelIt->second < valuation->observationLabelValues.size(),
97 "Label index " << labelIt->second << " larger than number of labels " << valuation->observationLabelValues.size());
98 return valuation->observationLabelValues[labelIt->second];
99}
100
102 STORM_LOG_ASSERT(isRational(), "Variable has no rational type.");
103 return valuation->rationalValues[variableIt->second];
104}
105
107 STORM_LOG_ASSERT(valuation == valuation, "Comparing iterators for different states");
108 return variableIt == other.variableIt && labelIt == other.labelIt;
109}
111 return !(*this == other);
112}
113
115 if (variableIt != variableEnd) {
116 ++variableIt;
117 } else {
118 ++labelIt;
119 }
120
121 return *this;
122}
123
125 if (labelIt != labelBegin) {
126 --labelIt;
127 } else {
128 --variableIt;
129 }
130 return *this;
131}
132
133StateValuations::StateValueIteratorRange::StateValueIteratorRange(std::map<storm::expressions::Variable, uint64_t> const& variableMap,
134 std::map<std::string, uint64_t> const& labelMap, StateValuation const* valuation)
135 : variableMap(variableMap), labelMap(labelMap), valuation(valuation) {
136 // Intentionally left empty.
137}
138
140 return StateValueIterator(variableMap.cbegin(), labelMap.cbegin(), variableMap.cbegin(), variableMap.cend(), labelMap.cbegin(), labelMap.cend(), valuation);
141}
142
144 return StateValueIterator(variableMap.cend(), labelMap.cend(), variableMap.cbegin(), variableMap.cend(), labelMap.cbegin(), labelMap.cend(), valuation);
145}
146
148 auto const& valuation = getValuation(stateIndex);
149 STORM_LOG_ASSERT(variableToIndexMap.count(booleanVariable) > 0, "Variable " << booleanVariable.getName() << " is not part of this valuation.");
150 STORM_LOG_ASSERT(booleanVariable.hasBooleanType(), "Variable " << booleanVariable.getName() << " has no Boolean type.");
151 return valuation.booleanValues[variableToIndexMap.at(booleanVariable)];
152}
153
155 storm::expressions::Variable const& integerVariable) const {
156 auto const& valuation = getValuation(stateIndex);
157 STORM_LOG_ASSERT(variableToIndexMap.count(integerVariable) > 0, "Variable " << integerVariable.getName() << " is not part of this valuation.");
158 STORM_LOG_ASSERT(integerVariable.hasIntegerType(), "Variable " << integerVariable.getName() << " has no integer type.");
159 return valuation.integerValues[variableToIndexMap.at(integerVariable)];
160}
161
162storm::RationalNumber const& StateValuations::getRationalValue(storm::storage::sparse::state_type const& stateIndex,
163 storm::expressions::Variable const& rationalVariable) const {
164 auto const& valuation = getValuation(stateIndex);
165 STORM_LOG_ASSERT(variableToIndexMap.count(rationalVariable) > 0, "Variable " << rationalVariable.getName() << " is not part of this valuation.");
166 STORM_LOG_ASSERT(rationalVariable.hasRationalType(), "Variable " << rationalVariable.getName() << " has no rational type.");
167 return valuation.rationalValues[variableToIndexMap.at(rationalVariable)];
168}
169
171 STORM_LOG_ASSERT(variableToIndexMap.count(booleanVariable) > 0, "Variable " << booleanVariable.getName() << " is not part of this valuation.");
172 STORM_LOG_ASSERT(booleanVariable.hasBooleanType(), "Variable " << booleanVariable.getName() << " has no Boolean type.");
173 auto const varIndex = variableToIndexMap.at(booleanVariable);
175 for (uint64_t stateIndex = 0; stateIndex < getNumberOfStates(); ++stateIndex) {
176 if (getValuation(stateIndex).booleanValues[varIndex]) {
177 result.set(stateIndex);
178 }
179 }
180 return result;
181}
182
183std::vector<int64_t> StateValuations::getIntegerValues(storm::expressions::Variable const& integerVariable) const {
184 STORM_LOG_ASSERT(variableToIndexMap.count(integerVariable) > 0, "Variable " << integerVariable.getName() << " is not part of this valuation.");
185 STORM_LOG_ASSERT(integerVariable.hasIntegerType(), "Variable " << integerVariable.getName() << " has no integer type.");
186 auto const varIndex = variableToIndexMap.at(integerVariable);
187 std::vector<int64_t> result;
188 result.reserve(getNumberOfStates());
189 for (uint64_t stateIndex = 0; stateIndex < getNumberOfStates(); ++stateIndex) {
190 result.push_back(getValuation(stateIndex).integerValues[varIndex]);
191 }
192 return result;
193}
194
195std::vector<storm::RationalNumber> StateValuations::getRationalValues(storm::expressions::Variable const& rationalVariable) const {
196 STORM_LOG_ASSERT(variableToIndexMap.count(rationalVariable) > 0, "Variable " << rationalVariable.getName() << " is not part of this valuation.");
197 STORM_LOG_ASSERT(rationalVariable.hasRationalType(), "Variable " << rationalVariable.getName() << " has no rational type.");
198 auto const varIndex = variableToIndexMap.at(rationalVariable);
199 std::vector<storm::RationalNumber> result;
200 result.reserve(getNumberOfStates());
201 for (uint64_t stateIndex = 0; stateIndex < getNumberOfStates(); ++stateIndex) {
202 result.push_back(getValuation(stateIndex).rationalValues[varIndex]);
203 }
204 return result;
205}
206
208 auto const& valuation = valuations[stateIndex]; // Do not use getValuations, as that is only valid after adding stuff.
209 return valuation.booleanValues.empty() && valuation.integerValues.empty() && valuation.rationalValues.empty() && valuation.observationLabelValues.empty();
210}
211
212std::string StateValuations::toString(storm::storage::sparse::state_type const& stateIndex, bool pretty,
213 boost::optional<std::set<storm::expressions::Variable>> const& selectedVariables) const {
214 auto const& valueAssignment = at(stateIndex);
215 typename std::set<storm::expressions::Variable>::const_iterator setIt;
216 if (selectedVariables) {
217 setIt = selectedVariables->begin();
218 }
219 std::vector<std::string> assignments;
220 for (auto valIt = valueAssignment.begin(); valIt != valueAssignment.end(); ++valIt) {
221 if (selectedVariables && (*setIt != valIt.getVariable())) {
222 continue;
223 }
224
225 std::stringstream stream;
226 if (pretty) {
227 if (valIt.isBoolean() && !valIt.getBooleanValue()) {
228 stream << "!";
229 }
230 stream << valIt.getName();
231 if (valIt.isInteger()) {
232 stream << "=" << valIt.getIntegerValue();
233 } else if (valIt.isRational()) {
234 stream << "=" << valIt.getRationalValue();
235 } else if (valIt.isLabelAssignment()) {
236 stream << "=" << valIt.getLabelValue();
237 } else {
238 STORM_LOG_THROW(valIt.isBoolean(), storm::exceptions::InvalidTypeException, "Unexpected variable type.");
239 }
240 } else {
241 if (valIt.isBoolean()) {
242 stream << std::boolalpha << valIt.getBooleanValue() << std::noboolalpha;
243 } else if (valIt.isInteger()) {
244 stream << valIt.getIntegerValue();
245 } else if (valIt.isRational()) {
246 stream << valIt.getRationalValue();
247 } else if (valIt.isLabelAssignment()) {
248 stream << valIt.getLabelValue();
249 }
250 }
251 assignments.push_back(stream.str());
252
253 if (selectedVariables) {
254 // Go to next selected position
255 ++setIt;
256 }
257 }
258 STORM_LOG_ASSERT(!selectedVariables || setIt == selectedVariables->end(), "Valuation does not consider selected variable " << setIt->getName() << ".");
259
260 if (pretty) {
261 return "[" + boost::join(assignments, "\t& ") + "]";
262 } else {
263 return "[" + boost::join(assignments, "\t") + "]";
264 }
265}
266
267template<typename JsonRationalType>
269 boost::optional<std::set<storm::expressions::Variable>> const& selectedVariables) const {
270 auto const& valueAssignment = at(stateIndex);
271 typename std::set<storm::expressions::Variable>::const_iterator setIt;
272 if (selectedVariables) {
273 setIt = selectedVariables->begin();
274 }
276 for (auto valIt = valueAssignment.begin(); valIt != valueAssignment.end(); ++valIt) {
277 if (selectedVariables && (*setIt != valIt.getVariable())) {
278 continue;
279 }
280
281 if (valIt.isBoolean()) {
282 result[valIt.getName()] = valIt.getBooleanValue();
283 } else if (valIt.isInteger()) {
284 result[valIt.getName()] = valIt.getIntegerValue();
285 } else if (valIt.isLabelAssignment()) {
286 result[valIt.getLabel()] = valIt.getLabelValue();
287 } else {
288 STORM_LOG_ASSERT(valIt.isRational(), "Unexpected variable type for variable " << valIt.getName());
289 result[valIt.getName()] = storm::utility::convertNumber<JsonRationalType>(valIt.getRationalValue());
290 }
291
292 if (selectedVariables) {
293 // Go to next selected position
294 ++setIt;
295 }
296 }
297 return result;
298}
299
300bool StateValuations::assertValuation(StateValuation const& valuation) const {
301 storm::storage::BitVector foundBooleanValues(valuation.booleanValues.size(), false);
302 storm::storage::BitVector foundIntegerValues(valuation.integerValues.size(), false);
303 storm::storage::BitVector foundRationalValues(valuation.rationalValues.size(), false);
304 for (auto const& varIndex : variableToIndexMap) {
306 if (varIndex.first.hasBooleanType()) {
307 bv = &foundBooleanValues;
308 } else if (varIndex.first.hasIntegerType()) {
309 bv = &foundIntegerValues;
310 } else if (varIndex.first.hasRationalType()) {
311 bv = &foundRationalValues;
312 } else {
313 STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unexpected variable type.");
314 }
315 if (varIndex.second < bv->size()) {
316 if (bv->get(varIndex.second)) {
317 STORM_LOG_ERROR("Multiple variables refer to the same value index");
318 return false;
319 }
320 bv->set(varIndex.second, true);
321 } else {
322 STORM_LOG_ERROR("Valuation does not provide a value for all variables");
323 return false;
324 }
325 }
326 if (!(foundBooleanValues.full() && foundIntegerValues.full() && foundRationalValues.full())) {
327 STORM_LOG_ERROR("Valuation has too many entries.");
328 }
329 return true;
330}
331
332StateValuations::StateValuations(std::map<storm::expressions::Variable, uint64_t> const& variableToIndexMap, std::vector<StateValuation>&& valuations)
333 : variableToIndexMap(variableToIndexMap), valuations(valuations) {
334 // Intentionally left empty
335}
336
337std::string StateValuations::getStateInfo(state_type const& state) const {
338 STORM_LOG_ASSERT(state < getNumberOfStates(), "Invalid state index.");
339 return this->toString(state);
340}
341
343 STORM_LOG_ASSERT(state < getNumberOfStates(), "Invalid state index.");
344 return StateValueIteratorRange({variableToIndexMap, observationLabels, &(valuations[state])});
345}
346
348 return valuations.size();
349}
350
351std::size_t StateValuations::hash() const {
352 return 0;
353}
354
356 return StateValuations(variableToIndexMap, storm::utility::vector::filterVector(valuations, selectedStates));
357}
358
359StateValuations StateValuations::selectStates(std::vector<storm::storage::sparse::state_type> const& selectedStates) const {
360 std::vector<StateValuation> selectedValuations;
361 selectedValuations.reserve(selectedStates.size());
362 for (auto const& selectedState : selectedStates) {
363 if (selectedState < valuations.size()) {
364 selectedValuations.push_back(valuations[selectedState]);
365 } else {
366 selectedValuations.emplace_back();
367 }
368 }
369 return StateValuations(variableToIndexMap, std::move(selectedValuations));
370}
371
372StateValuations StateValuations::blowup(const std::vector<uint64_t>& mapNewToOld) const {
373 std::vector<StateValuation> newValuations;
374 for (auto const& oldState : mapNewToOld) {
375 newValuations.push_back(valuations[oldState]);
376 }
377 return StateValuations(variableToIndexMap, std::move(newValuations));
378}
379
380StateValuationsBuilder::StateValuationsBuilder() : booleanVarCount(0), integerVarCount(0), rationalVarCount(0), labelCount(0) {
381 // Intentionally left empty.
382}
383
385 STORM_LOG_ASSERT(currentStateValuations.valuations.empty(), "Tried to add a variable, although a state has already been added before.");
386 STORM_LOG_ASSERT(currentStateValuations.variableToIndexMap.count(variable) == 0, "Variable " << variable.getName() << " already added.");
387 if (variable.hasBooleanType()) {
388 currentStateValuations.variableToIndexMap[variable] = booleanVarCount++;
389 }
390 if (variable.hasIntegerType()) {
391 currentStateValuations.variableToIndexMap[variable] = integerVarCount++;
392 }
393 if (variable.hasRationalType()) {
394 currentStateValuations.variableToIndexMap[variable] = rationalVarCount++;
395 }
396}
397
398void StateValuationsBuilder::addObservationLabel(const std::string& label) {
399 currentStateValuations.observationLabels[label] = labelCount++;
400}
401
402void StateValuationsBuilder::addState(storm::storage::sparse::state_type const& state, std::vector<bool>&& booleanValues,
403 std::vector<int64_t>&& integerValues) {
404 addState(state, std::move(booleanValues), std::move(integerValues), {});
405}
406
407void StateValuationsBuilder::addState(storm::storage::sparse::state_type const& state, std::vector<bool>&& booleanValues, std::vector<int64_t>&& integerValues,
408 std::vector<storm::RationalNumber>&& rationalValues, std::vector<int64_t>&& observationLabelValues) {
409 if (state > currentStateValuations.valuations.size()) {
410 currentStateValuations.valuations.resize(state);
411 }
412 if (state == currentStateValuations.valuations.size()) {
413 currentStateValuations.valuations.emplace_back(std::move(booleanValues), std::move(integerValues), std::move(rationalValues),
414 std::move(observationLabelValues));
415 } else {
416 STORM_LOG_ASSERT(currentStateValuations.isEmpty(state), "Adding a valuation to the same state multiple times.");
417 currentStateValuations.valuations[state] = typename StateValuations::StateValuation(std::move(booleanValues), std::move(integerValues),
418 std::move(rationalValues), std::move(observationLabelValues));
419 }
420}
421
423 return booleanVarCount;
424}
425
427 return integerVarCount;
428}
429
431 return labelCount;
432}
433
435 booleanVarCount = 0;
436 integerVarCount = 0;
437 rationalVarCount = 0;
438 labelCount = 0;
439 return std::move(currentStateValuations);
440}
441
442template storm::json<double> StateValuations::toJson<double>(storm::storage::sparse::state_type const&,
443 boost::optional<std::set<storm::expressions::Variable>> const&) const;
444template storm::json<storm::RationalNumber> StateValuations::toJson<storm::RationalNumber>(
445 storm::storage::sparse::state_type const&, boost::optional<std::set<storm::expressions::Variable>> const&) const;
446
447} // namespace sparse
448} // namespace storage
449} // namespace storm
bool hasBooleanType() const
Checks whether the variable is of boolean type.
Definition Variable.cpp:59
bool hasIntegerType() const
Checks whether the variable is of integral type.
Definition Variable.cpp:63
bool hasRationalType() const
Checks whether the variable is of rational type.
Definition Variable.cpp:71
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
storm::expressions::Variable const & getVariable() const
StateValueIterator(typename std::map< storm::expressions::Variable, uint64_t >::const_iterator variableIt, typename std::map< std::string, uint64_t >::const_iterator labelIt, typename std::map< storm::expressions::Variable, uint64_t >::const_iterator variableBegin, typename std::map< storm::expressions::Variable, uint64_t >::const_iterator variableEnd, typename std::map< std::string, uint64_t >::const_iterator labelBegin, typename std::map< std::string, uint64_t >::const_iterator labelEnd, StateValuation const *valuation)
StateValueIteratorRange(std::map< storm::expressions::Variable, uint64_t > const &variableMap, std::map< std::string, uint64_t > const &labelMap, StateValuation const *valuation)
void addState(storm::storage::sparse::state_type const &state, std::vector< bool > &&booleanValues={}, std::vector< int64_t > &&integerValues={})
Adds a new state.
void addObservationLabel(std::string const &label)
StateValuations build()
Creates the finalized state valuations object.
void addVariable(storm::expressions::Variable const &variable)
Adds a new variable to keep track of for the state valuations.
std::vector< storm::RationalNumber > getRationalValues(storm::expressions::Variable const &rationalVariable) const
Returns a vector of size getNumberOfStates() such that the i'th entry is the value of the given varia...
std::string toString(storm::storage::sparse::state_type const &stateIndex, bool pretty=true, boost::optional< std::set< storm::expressions::Variable > > const &selectedVariables=boost::none) const
Returns a string representation of the valuation.
StateValuations selectStates(storm::storage::BitVector const &selectedStates) const
storm::RationalNumber const & getRationalValue(storm::storage::sparse::state_type const &stateIndex, storm::expressions::Variable const &rationalVariable) const
bool isEmpty(storm::storage::sparse::state_type const &stateIndex) const
Returns true, if this valuation does not contain any value.
std::vector< int64_t > getIntegerValues(storm::expressions::Variable const &integerVariable) const
Returns a vector of size getNumberOfStates() such that the i'th entry is the value of the given varia...
int64_t const & getIntegerValue(storm::storage::sparse::state_type const &stateIndex, storm::expressions::Variable const &integerVariable) const
storm::storage::BitVector getBooleanValues(storm::expressions::Variable const &booleanVariable) const
Returns a vector of size getNumberOfStates() such that the i'th entry is the value of the given varia...
storm::json< JsonRationalType > toJson(storm::storage::sparse::state_type const &stateIndex, boost::optional< std::set< storm::expressions::Variable > > const &selectedVariables=boost::none) const
Returns a JSON representation of this valuation.
StateValuations blowup(std::vector< uint64_t > const &mapNewToOld) const
StateValueIteratorRange at(storm::storage::sparse::state_type const &state) const
virtual std::string getStateInfo(storm::storage::sparse::state_type const &state) const override
bool getBooleanValue(storm::storage::sparse::state_type const &stateIndex, storm::expressions::Variable const &booleanVariable) const
#define STORM_LOG_ERROR(message)
Definition logging.h:31
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
Definition vector.h:1213
LabParser.cpp.
Definition cli.cpp:18
nlohmann::basic_json< std::map, std::vector, std::string, bool, int64_t, uint64_t, ValueType > json
Definition JsonForward.h:10