Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ExplicitQualitativeCheckResult.cpp
Go to the documentation of this file.
1#include "storm/adapters/RationalNumberAdapter.h" // Must come first
2
4
8
9namespace storm {
10namespace modelchecker {
12 // Intentionally left empty.
13}
14
16 // Intentionally left empty.
17}
18
20 // Intentionally left empty.
21}
22
24 boost::get<map_type>(truthValues)[state] = value;
25}
26
28 // Intentionally left empty.
29}
30
32 // Intentionally left empty.
33}
34
35ExplicitQualitativeCheckResult::ExplicitQualitativeCheckResult(boost::variant<vector_type, map_type> const& truthValues) : truthValues(truthValues) {
36 // Intentionally left empty.
37}
38
39ExplicitQualitativeCheckResult::ExplicitQualitativeCheckResult(boost::variant<vector_type, map_type>&& truthValues) : truthValues(std::move(truthValues)) {
40 // Intentionally left empty.
41}
42
43std::unique_ptr<CheckResult> ExplicitQualitativeCheckResult::clone() const {
44 return std::make_unique<ExplicitQualitativeCheckResult>(this->truthValues);
45}
46
47void ExplicitQualitativeCheckResult::performLogicalOperation(ExplicitQualitativeCheckResult& first, QualitativeCheckResult const& second, bool logicalAnd) {
48 STORM_LOG_THROW(second.isExplicitQualitativeCheckResult(), storm::exceptions::InvalidOperationException,
49 "Cannot perform logical 'and' on check results of incompatible type.");
50 STORM_LOG_THROW(first.isResultForAllStates() == second.isResultForAllStates(), storm::exceptions::InvalidOperationException,
51 "Cannot perform logical 'and' on check results of incompatible type.");
52 ExplicitQualitativeCheckResult const& secondCheckResult = static_cast<ExplicitQualitativeCheckResult const&>(second);
53 if (first.isResultForAllStates()) {
54 if (logicalAnd) {
55 boost::get<vector_type>(first.truthValues) &= boost::get<vector_type>(secondCheckResult.truthValues);
56 } else {
57 boost::get<vector_type>(first.truthValues) |= boost::get<vector_type>(secondCheckResult.truthValues);
58 }
59 } else {
60 std::function<bool(bool, bool)> function = logicalAnd ? std::function<bool(bool, bool)>([](bool a, bool b) { return a && b; })
61 : std::function<bool(bool, bool)>([](bool a, bool b) { return a || b; });
62
63 map_type& map1 = boost::get<map_type>(first.truthValues);
64 map_type const& map2 = boost::get<map_type>(secondCheckResult.truthValues);
65 for (auto& element1 : map1) {
66 auto const& keyValuePair = map2.find(element1.first);
67 STORM_LOG_THROW(keyValuePair != map2.end(), storm::exceptions::InvalidOperationException,
68 "Cannot perform logical 'and' on check results of incompatible type.");
69 element1.second = function(element1.second, keyValuePair->second);
70 }
71
72 // Double-check that there are no entries in map2 that the current result does not have.
73 for (auto const& element2 : map2) {
74 auto const& keyValuePair = map1.find(element2.first);
75 STORM_LOG_THROW(keyValuePair != map1.end(), storm::exceptions::InvalidOperationException,
76 "Cannot perform logical 'and' on check results of incompatible type.");
77 }
78 }
79}
80
81QualitativeCheckResult& ExplicitQualitativeCheckResult::operator&=(QualitativeCheckResult const& other) {
82 performLogicalOperation(*this, other, true);
83 return *this;
84}
85
86QualitativeCheckResult& ExplicitQualitativeCheckResult::operator|=(QualitativeCheckResult const& other) {
87 performLogicalOperation(*this, other, false);
88 return *this;
89}
90
91bool ExplicitQualitativeCheckResult::existsTrue() const {
92 if (this->isResultForAllStates()) {
93 return !boost::get<vector_type>(truthValues).empty();
94 } else {
95 for (auto& element : boost::get<map_type>(truthValues)) {
96 if (element.second) {
97 return true;
98 }
99 }
100 return false;
101 }
102}
103bool ExplicitQualitativeCheckResult::forallTrue() const {
104 if (this->isResultForAllStates()) {
105 return boost::get<vector_type>(truthValues).full();
106 } else {
107 for (auto& element : boost::get<map_type>(truthValues)) {
108 if (!element.second) {
109 return false;
110 }
111 }
112 return true;
113 }
114}
115
116uint64_t ExplicitQualitativeCheckResult::count() const {
117 if (this->isResultForAllStates()) {
118 return boost::get<vector_type>(truthValues).getNumberOfSetBits();
119 } else {
120 uint64_t result = 0;
121 for (auto& element : boost::get<map_type>(truthValues)) {
122 if (element.second) {
123 ++result;
124 }
125 }
126 return result;
127 }
128}
129
130bool ExplicitQualitativeCheckResult::operator[](storm::storage::sparse::state_type state) const {
131 if (this->isResultForAllStates()) {
132 return boost::get<vector_type>(truthValues).get(state);
133 } else {
134 map_type const& map = boost::get<map_type>(truthValues);
135 auto const& keyValuePair = map.find(state);
136 STORM_LOG_THROW(keyValuePair != map.end(), storm::exceptions::InvalidOperationException, "Unknown key '" << state << "'.");
137 return keyValuePair->second;
138 }
139}
140
141ExplicitQualitativeCheckResult::vector_type const& ExplicitQualitativeCheckResult::getTruthValuesVector() const {
142 return boost::get<vector_type>(truthValues);
143}
144
145ExplicitQualitativeCheckResult::map_type const& ExplicitQualitativeCheckResult::getTruthValuesMap() const {
146 return boost::get<map_type>(truthValues);
147}
148
149void ExplicitQualitativeCheckResult::complement() {
150 if (this->isResultForAllStates()) {
151 boost::get<vector_type>(truthValues).complement();
152 } else {
153 for (auto& element : boost::get<map_type>(truthValues)) {
154 element.second = !element.second;
155 }
156 }
157}
158
159bool ExplicitQualitativeCheckResult::isExplicit() const {
160 return true;
161}
162
163bool ExplicitQualitativeCheckResult::isResultForAllStates() const {
164 return truthValues.which() == 0;
165}
166
167bool ExplicitQualitativeCheckResult::isExplicitQualitativeCheckResult() const {
168 return true;
169}
170
171std::ostream& ExplicitQualitativeCheckResult::writeToStream(std::ostream& out) const {
172 if (this->isResultForAllStates()) {
173 vector_type const& vector = boost::get<vector_type>(truthValues);
174 bool allTrue = vector.full();
175 bool allFalse = !allTrue && vector.empty();
176 if (allTrue) {
177 out << "{true}";
178 } else if (allFalse) {
179 out << "{false}";
180 } else {
181 out << "{true, false}";
182 }
183 } else {
184 std::ios::fmtflags oldflags(std::cout.flags());
185 out << std::boolalpha;
186
187 map_type const& map = boost::get<map_type>(truthValues);
188 if (map.size() == 1) {
189 out << map.begin()->second;
190 } else {
191 bool allTrue = true;
192 bool allFalse = true;
193 for (auto const& entry : map) {
194 if (entry.second) {
195 allFalse = false;
196 } else {
197 allTrue = false;
198 }
199 }
200 if (allTrue) {
201 out << "{true}";
202 } else if (allFalse) {
203 out << "{false}";
204 } else {
205 out << "{true, false}";
206 }
207 }
208
209 std::cout.flags(oldflags);
210 }
211 return out;
212}
213
214void ExplicitQualitativeCheckResult::filter(QualitativeCheckResult const& filter) {
215 STORM_LOG_THROW(filter.isExplicitQualitativeCheckResult(), storm::exceptions::InvalidOperationException,
216 "Cannot filter explicit check result with non-explicit filter.");
217 STORM_LOG_THROW(filter.isResultForAllStates(), storm::exceptions::InvalidOperationException, "Cannot filter check result with non-complete filter.");
218 ExplicitQualitativeCheckResult const& explicitFilter = filter.asExplicitQualitativeCheckResult();
219 vector_type const& filterTruthValues = explicitFilter.getTruthValuesVector();
220
221 if (this->isResultForAllStates()) {
222 map_type newMap;
223 for (auto element : filterTruthValues) {
224 newMap.emplace(element, this->getTruthValuesVector().get(element));
225 }
226 this->truthValues = newMap;
227 } else {
228 map_type const& map = boost::get<map_type>(truthValues);
229
230 map_type newMap;
231 for (auto const& element : map) {
232 if (filterTruthValues.get(element.first)) {
233 newMap.insert(element);
234 }
235 }
236
237 STORM_LOG_THROW(newMap.size() == filterTruthValues.getNumberOfSetBits(), storm::exceptions::InvalidOperationException,
238 "The check result fails to contain some results referred to by the filter.");
239
240 this->truthValues = newMap;
241 }
242}
243
244template<typename JsonRationalType>
245void insertJsonEntry(storm::json<JsonRationalType>& json, uint64_t const& id, bool value,
246 std::optional<storm::storage::sparse::StateValuations> const& stateValuations = std::nullopt,
247 std::optional<storm::models::sparse::StateLabeling> const& stateLabels = std::nullopt) {
249 if (stateValuations) {
250 entry["s"] = stateValuations->template toJson<JsonRationalType>(id);
251 } else {
252 entry["s"] = id;
253 }
254 entry["v"] = value;
255 if (stateLabels) {
256 auto labs = stateLabels->getLabelsOfState(id);
257 entry["l"] = labs;
258 }
259 json.push_back(std::move(entry));
260}
261
262template<typename JsonRationalType>
263storm::json<JsonRationalType> ExplicitQualitativeCheckResult::toJson(std::optional<storm::storage::sparse::StateValuations> const& stateValuations,
264 std::optional<storm::models::sparse::StateLabeling> const& stateLabels) const {
266 if (this->isResultForAllStates()) {
267 vector_type const& valuesAsVector = boost::get<vector_type>(truthValues);
268 for (uint64_t state = 0; state < valuesAsVector.size(); ++state) {
269 insertJsonEntry(result, state, valuesAsVector.get(state), stateValuations, stateLabels);
270 }
271 } else {
272 map_type const& valuesAsMap = boost::get<map_type>(truthValues);
273 for (auto const& stateValue : valuesAsMap) {
274 insertJsonEntry(result, stateValue.first, stateValue.second, stateValuations, stateLabels);
275 }
276 }
277 return result;
278}
279
280template storm::json<double> ExplicitQualitativeCheckResult::toJson<double>(std::optional<storm::storage::sparse::StateValuations> const&,
281 std::optional<storm::models::sparse::StateLabeling> const&) const;
282template storm::json<storm::RationalNumber> ExplicitQualitativeCheckResult::toJson<storm::RationalNumber>(
283 std::optional<storm::storage::sparse::StateValuations> const&, std::optional<storm::models::sparse::StateLabeling> const&) const;
284
285} // namespace modelchecker
286} // namespace storm
virtual bool isResultForAllStates() const
virtual bool isExplicitQualitativeCheckResult() const
virtual std::unique_ptr< CheckResult > clone() const override
std::map< storm::storage::sparse::state_type, bool > map_type
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
bool full() const
Retrieves whether all bits are set in this bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
size_t size() const
Retrieves the number of bits this bit vector can store.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
void insertJsonEntry(storm::json< JsonRationalType > &json, uint64_t const &id, bool value, std::optional< storm::storage::sparse::StateValuations > const &stateValuations=std::nullopt, std::optional< storm::models::sparse::StateLabeling > const &stateLabels=std::nullopt)
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