Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
InternalSylvanAdd.cpp
Go to the documentation of this file.
2
14
15namespace storm {
16namespace dd {
17
18#ifdef STORM_HAVE_SYLVAN
19template<typename ValueType>
20InternalAdd<DdType::Sylvan, ValueType>::InternalAdd() : ddManager(nullptr), sylvanMtbdd() {
21 // Intentionally left empty.
22}
23
24template<typename ValueType>
25InternalAdd<DdType::Sylvan, ValueType>::InternalAdd(InternalDdManager<DdType::Sylvan> const* ddManager, sylvan::Mtbdd const& sylvanMtbdd)
26 : ddManager(ddManager), sylvanMtbdd(sylvanMtbdd) {
27 // Intentionally left empty.
28}
29
30template<typename ValueType>
31ValueType InternalAdd<DdType::Sylvan, ValueType>::getValue(MTBDD const& node) {
32 STORM_LOG_ASSERT(mtbdd_isleaf(node), "Expected leaf, but got variable " << mtbdd_getvar(node) << ".");
33
34 bool negated = mtbdd_hascomp(node);
35 MTBDD n = mtbdd_regular(node);
36
37 if (std::is_same<ValueType, double>::value) {
38 STORM_LOG_ASSERT(mtbdd_gettype(n) == 1, "Expected a double value.");
39 return negated ? -mtbdd_getdouble(n) : mtbdd_getdouble(n);
40 } else if (std::is_same<ValueType, uint_fast64_t>::value) {
41 STORM_LOG_ASSERT(mtbdd_gettype(node) == 0, "Expected an unsigned value.");
42 return negated ? -mtbdd_getint64(node) : mtbdd_getint64(node);
43 } else if (std::is_same<ValueType, storm::RationalFunction>::value) {
44 STORM_LOG_ASSERT(false, "Non-specialized version of getValue() called for storm::RationalFunction value.");
45 } else {
46 STORM_LOG_ASSERT(false, "Illegal or unknown type in MTBDD.");
47 }
48}
49
50template<>
51storm::RationalNumber InternalAdd<DdType::Sylvan, storm::RationalNumber>::getValue(MTBDD const& node) {
52 STORM_LOG_ASSERT(mtbdd_isleaf(node), "Expected leaf, but got variable " << mtbdd_getvar(node) << ".");
53
54 bool negated = mtbdd_hascomp(node);
55
56 STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_number_get_type(), "Expected a storm::RationalNumber value.");
57 storm_rational_number_ptr ptr = (storm_rational_number_ptr)mtbdd_getstorm_rational_number_ptr(node);
58 storm::RationalNumber* rationalNumber = (storm::RationalNumber*)(ptr);
59
60 return negated ? -(*rationalNumber) : (*rationalNumber);
61}
62
63template<>
64storm::RationalFunction InternalAdd<DdType::Sylvan, storm::RationalFunction>::getValue(MTBDD const& node) {
65 STORM_LOG_ASSERT(mtbdd_isleaf(node), "Expected leaf, but got variable " << mtbdd_getvar(node) << ".");
66
67 bool negated = mtbdd_hascomp(node);
68
69 STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_function_get_type(), "Expected a storm::RationalFunction value.");
70 uint64_t value = mtbdd_getvalue(node);
71 storm_rational_function_ptr ptr = (storm_rational_function_ptr)value;
72
73 storm::RationalFunction* rationalFunction = (storm::RationalFunction*)(ptr);
74
75 return negated ? -(*rationalFunction) : (*rationalFunction);
76}
77
78template<typename ValueType>
79bool InternalAdd<DdType::Sylvan, ValueType>::operator==(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
80 return this->sylvanMtbdd == other.sylvanMtbdd;
81}
82
83template<typename ValueType>
84bool InternalAdd<DdType::Sylvan, ValueType>::operator!=(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
85 return this->sylvanMtbdd != other.sylvanMtbdd;
86}
87
88template<typename ValueType>
89InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::operator+(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
90 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Plus(other.sylvanMtbdd));
91}
92
93template<>
94InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator+(
95 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
96 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.PlusRN(other.sylvanMtbdd));
97}
98
99template<>
100InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator+(
101 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
102 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.PlusRF(other.sylvanMtbdd));
103}
104
105template<typename ValueType>
106InternalAdd<DdType::Sylvan, ValueType>& InternalAdd<DdType::Sylvan, ValueType>::operator+=(InternalAdd<DdType::Sylvan, ValueType> const& other) {
107 this->sylvanMtbdd = this->sylvanMtbdd.Plus(other.sylvanMtbdd);
108 return *this;
109}
110
111template<>
112InternalAdd<DdType::Sylvan, storm::RationalNumber>& InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator+=(
113 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) {
114 this->sylvanMtbdd = this->sylvanMtbdd.PlusRN(other.sylvanMtbdd);
115 return *this;
116}
117
118template<>
119InternalAdd<DdType::Sylvan, storm::RationalFunction>& InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator+=(
120 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) {
121 this->sylvanMtbdd = this->sylvanMtbdd.PlusRF(other.sylvanMtbdd);
122 return *this;
123}
124
125template<typename ValueType>
126InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::operator*(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
127 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Times(other.sylvanMtbdd));
128}
129
130template<>
131InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator*(
132 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
133 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.TimesRN(other.sylvanMtbdd));
134}
135
136template<>
137InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator*(
138 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
139 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.TimesRF(other.sylvanMtbdd));
140}
141
142template<typename ValueType>
143InternalAdd<DdType::Sylvan, ValueType>& InternalAdd<DdType::Sylvan, ValueType>::operator*=(InternalAdd<DdType::Sylvan, ValueType> const& other) {
144 this->sylvanMtbdd = this->sylvanMtbdd.Times(other.sylvanMtbdd);
145 return *this;
146}
147
148template<>
149InternalAdd<DdType::Sylvan, storm::RationalNumber>& InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator*=(
150 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) {
151 this->sylvanMtbdd = this->sylvanMtbdd.TimesRN(other.sylvanMtbdd);
152 return *this;
153}
154
155template<>
156InternalAdd<DdType::Sylvan, storm::RationalFunction>& InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator*=(
157 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) {
158 this->sylvanMtbdd = this->sylvanMtbdd.TimesRF(other.sylvanMtbdd);
159 return *this;
160}
161
162template<typename ValueType>
163InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::operator-(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
164 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Minus(other.sylvanMtbdd));
165}
166
167template<>
168InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator-(
169 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
170 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.MinusRN(other.sylvanMtbdd));
171}
172
173template<>
174InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator-(
175 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
176 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.MinusRF(other.sylvanMtbdd));
177}
178
179template<typename ValueType>
180InternalAdd<DdType::Sylvan, ValueType>& InternalAdd<DdType::Sylvan, ValueType>::operator-=(InternalAdd<DdType::Sylvan, ValueType> const& other) {
181 this->sylvanMtbdd = this->sylvanMtbdd.Minus(other.sylvanMtbdd);
182 return *this;
183}
184
185template<>
186InternalAdd<DdType::Sylvan, storm::RationalNumber>& InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator-=(
187 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) {
188 this->sylvanMtbdd = this->sylvanMtbdd.MinusRN(other.sylvanMtbdd);
189 return *this;
190}
191
192template<>
193InternalAdd<DdType::Sylvan, storm::RationalFunction>& InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator-=(
194 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) {
195 this->sylvanMtbdd = this->sylvanMtbdd.MinusRF(other.sylvanMtbdd);
196 return *this;
197}
198
199template<typename ValueType>
200InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::operator/(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
201 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Divide(other.sylvanMtbdd));
202}
203
204template<>
205InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator/(
206 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
207 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.DivideRN(other.sylvanMtbdd));
208}
209
210template<>
211InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator/(
212 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
213 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.DivideRF(other.sylvanMtbdd));
214}
215
216template<typename ValueType>
217InternalAdd<DdType::Sylvan, ValueType>& InternalAdd<DdType::Sylvan, ValueType>::operator/=(InternalAdd<DdType::Sylvan, ValueType> const& other) {
218 this->sylvanMtbdd = this->sylvanMtbdd.Divide(other.sylvanMtbdd);
219 return *this;
220}
221
222template<>
223InternalAdd<DdType::Sylvan, storm::RationalNumber>& InternalAdd<DdType::Sylvan, storm::RationalNumber>::operator/=(
224 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) {
225 this->sylvanMtbdd = this->sylvanMtbdd.DivideRN(other.sylvanMtbdd);
226 return *this;
227}
228
229template<>
230InternalAdd<DdType::Sylvan, storm::RationalFunction>& InternalAdd<DdType::Sylvan, storm::RationalFunction>::operator/=(
231 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) {
232 this->sylvanMtbdd = this->sylvanMtbdd.DivideRF(other.sylvanMtbdd);
233 return *this;
234}
235
236template<typename ValueType>
237InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::equals(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
238 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.Equals(other.sylvanMtbdd));
239}
240
241template<>
242InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::equals(InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
243 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.EqualsRN(other.sylvanMtbdd));
244}
245
246template<>
247InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalFunction>::equals(
248 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
249 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.EqualsRF(other.sylvanMtbdd));
250}
251
252template<typename ValueType>
253InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::notEquals(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
254 return !this->equals(other);
255}
256
257template<typename ValueType>
258InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::less(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
259 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.Less(other.sylvanMtbdd));
260}
261
262template<>
263InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::less(InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
264 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.LessRN(other.sylvanMtbdd));
265}
266
267template<>
268InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalFunction>::less(
269 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
270 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.LessRF(other.sylvanMtbdd));
271}
272
273template<typename ValueType>
274InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::lessOrEqual(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
275 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.LessOrEqual(other.sylvanMtbdd));
276}
277
278template<>
279InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::lessOrEqual(
280 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
281 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.LessOrEqualRN(other.sylvanMtbdd));
282}
283
284template<>
285InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalFunction>::lessOrEqual(
286 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
287 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.LessOrEqualRF(other.sylvanMtbdd));
288}
289
290template<typename ValueType>
291InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::greater(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
292 return !this->lessOrEqual(other);
293}
294
295template<typename ValueType>
296InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::greaterOrEqual(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
297 return !this->less(other);
298}
299
300template<typename ValueType>
301InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::pow(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
302 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Pow(other.sylvanMtbdd));
303}
304
305template<>
306InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::pow(
307 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
308 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.PowRN(other.sylvanMtbdd));
309}
310
311template<>
312InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::pow(
313 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
314 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.PowRF(other.sylvanMtbdd));
315}
316
317template<typename ValueType>
318InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::mod(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
319 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Mod(other.sylvanMtbdd));
320}
321
322template<>
323InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::mod(
324 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
325 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.ModRN(other.sylvanMtbdd));
326}
327
328template<>
329InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::mod(
330 InternalAdd<DdType::Sylvan, storm::RationalFunction> const&) const {
331 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Operation (mod) not supported by rational functions.");
332}
333
334template<typename ValueType>
335InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::logxy(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
336 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Logxy(other.sylvanMtbdd));
337}
338
339template<>
340InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::logxy(
341 InternalAdd<DdType::Sylvan, storm::RationalNumber> const&) const {
342 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Operation (logxy) not supported by rational numbers.");
343}
344
345template<>
346InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::logxy(
347 InternalAdd<DdType::Sylvan, storm::RationalFunction> const&) const {
348 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Operation (logxy) not supported by rational functions.");
349}
350
351template<typename ValueType>
352InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::floor() const {
353 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Floor());
354}
355
356template<>
357InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::floor() const {
358 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.FloorRN());
359}
360
361template<>
362InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::floor() const {
363 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.FloorRF());
364}
365
366template<typename ValueType>
367InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::ceil() const {
368 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Ceil());
369}
370
371template<>
372InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::ceil() const {
373 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.CeilRN());
374}
375
376template<>
377InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::ceil() const {
378 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.CeilRF());
379}
380
381template<typename ValueType>
382InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, ValueType>::sharpenKwekMehlhorn(size_t precision) const {
383 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.SharpenKwekMehlhorn(precision));
384}
385
386template<>
387InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalFunction>::sharpenKwekMehlhorn(size_t /*precision*/) const {
388 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
389}
390
391template<typename ValueType>
392InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::minimum(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
393 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Min(other.sylvanMtbdd));
394}
395
396template<>
397InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::minimum(
398 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
399 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.MinRN(other.sylvanMtbdd));
400}
401
402template<>
403InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::minimum(
404 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
405 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.MinRF(other.sylvanMtbdd));
406}
407
408template<typename ValueType>
409InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::maximum(InternalAdd<DdType::Sylvan, ValueType> const& other) const {
410 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Max(other.sylvanMtbdd));
411}
412
413template<>
414InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::maximum(
415 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other) const {
416 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.MaxRN(other.sylvanMtbdd));
417}
418
419template<>
420InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::maximum(
421 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other) const {
422 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.MaxRF(other.sylvanMtbdd));
423}
424
425template<typename ValueType>
426template<typename TargetValueType>
427InternalAdd<DdType::Sylvan, TargetValueType> InternalAdd<DdType::Sylvan, ValueType>::toValueType() const {
428 if (std::is_same<TargetValueType, ValueType>::value) {
429 return *this;
430 }
431 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
432}
433
434template<>
435template<>
436InternalAdd<DdType::Sylvan, double> InternalAdd<DdType::Sylvan, storm::RationalNumber>::toValueType() const {
437 return InternalAdd<DdType::Sylvan, double>(ddManager, this->sylvanMtbdd.ToDoubleRN());
438}
439
440template<>
441template<>
442InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, double>::toValueType() const {
443 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.ToRationalNumber());
444}
445
446template<>
447template<>
448InternalAdd<DdType::Sylvan, double> InternalAdd<DdType::Sylvan, storm::RationalFunction>::toValueType() const {
449 return InternalAdd<DdType::Sylvan, double>(ddManager, this->sylvanMtbdd.ToDoubleRF());
450}
451
452template<typename ValueType>
453InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::sumAbstract(InternalBdd<DdType::Sylvan> const& cube) const {
454 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.AbstractPlus(cube.sylvanBdd));
455}
456
457template<>
458InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::sumAbstract(
459 InternalBdd<DdType::Sylvan> const& cube) const {
460 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.AbstractPlusRN(cube.sylvanBdd));
461}
462
463template<>
464InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::sumAbstract(
465 InternalBdd<DdType::Sylvan> const& cube) const {
466 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.AbstractPlusRF(cube.sylvanBdd));
467}
468
469template<typename ValueType>
470InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::minAbstract(InternalBdd<DdType::Sylvan> const& cube) const {
471 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.AbstractMin(cube.sylvanBdd));
472}
473
474template<typename ValueType>
475InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::minAbstractRepresentative(InternalBdd<DdType::Sylvan> const& cube) const {
476 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.AbstractMinRepresentative(cube.sylvanBdd));
477}
478
479template<>
480InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::minAbstractRepresentative(InternalBdd<DdType::Sylvan> const& cube) const {
481 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.AbstractMinRepresentativeRN(cube.sylvanBdd));
482}
483
484template<>
485InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::minAbstract(
486 InternalBdd<DdType::Sylvan> const& cube) const {
487 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.AbstractMinRN(cube.sylvanBdd));
488}
489
490template<>
491InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::minAbstract(
492 InternalBdd<DdType::Sylvan> const& cube) const {
493 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.AbstractMinRF(cube.sylvanBdd));
494}
495
496template<typename ValueType>
497InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::maxAbstract(InternalBdd<DdType::Sylvan> const& cube) const {
498 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.AbstractMax(cube.sylvanBdd));
499}
500
501template<typename ValueType>
502InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::maxAbstractRepresentative(InternalBdd<DdType::Sylvan> const& cube) const {
503 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.AbstractMaxRepresentative(cube.sylvanBdd));
504}
505
506template<>
507InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::maxAbstractRepresentative(InternalBdd<DdType::Sylvan> const& cube) const {
508 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.AbstractMaxRepresentativeRN(cube.sylvanBdd));
509}
510
511template<>
512InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::maxAbstract(
513 InternalBdd<DdType::Sylvan> const& cube) const {
514 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager, this->sylvanMtbdd.AbstractMaxRN(cube.sylvanBdd));
515}
516
517template<>
518InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::maxAbstract(
519 InternalBdd<DdType::Sylvan> const& cube) const {
520 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager, this->sylvanMtbdd.AbstractMaxRF(cube.sylvanBdd));
521}
522
523template<typename ValueType>
524bool InternalAdd<DdType::Sylvan, ValueType>::equalModuloPrecision(InternalAdd<DdType::Sylvan, ValueType> const& other, ValueType const& precision,
525 bool relative) const {
526 if (relative) {
527 return this->sylvanMtbdd.EqualNormRel(other.sylvanMtbdd, precision);
528 } else {
529 return this->sylvanMtbdd.EqualNorm(other.sylvanMtbdd, precision);
530 }
531}
532
533template<>
534bool InternalAdd<DdType::Sylvan, storm::RationalNumber>::equalModuloPrecision(InternalAdd<DdType::Sylvan, storm::RationalNumber> const& other,
535 storm::RationalNumber const& precision, bool relative) const {
536 if (relative) {
537 return this->sylvanMtbdd.EqualNormRelRN(other.sylvanMtbdd, precision);
538 } else {
539 return this->sylvanMtbdd.EqualNormRN(other.sylvanMtbdd, precision);
540 }
541}
542
543template<>
544bool InternalAdd<DdType::Sylvan, storm::RationalFunction>::equalModuloPrecision(InternalAdd<DdType::Sylvan, storm::RationalFunction> const& other,
545 storm::RationalFunction const& precision, bool relative) const {
546 if (relative) {
547 return this->sylvanMtbdd.EqualNormRelRF(other.sylvanMtbdd, precision);
548 } else {
549 return this->sylvanMtbdd.EqualNormRF(other.sylvanMtbdd, precision);
550 }
551}
552
553template<typename ValueType>
554InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::swapVariables(std::vector<InternalBdd<DdType::Sylvan>> const& from,
555 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
556 std::vector<uint32_t> fromIndices;
557 std::vector<uint32_t> toIndices;
558 for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) {
559 fromIndices.push_back(it1->getIndex());
560 fromIndices.push_back(it2->getIndex());
561 toIndices.push_back(it2->getIndex());
562 toIndices.push_back(it1->getIndex());
563 }
564 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Permute(fromIndices, toIndices));
565}
566
567template<typename ValueType>
568InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::permuteVariables(std::vector<InternalBdd<DdType::Sylvan>> const& from,
569 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
570 std::vector<uint32_t> fromIndices;
571 std::vector<uint32_t> toIndices;
572 for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) {
573 fromIndices.push_back(it1->getIndex());
574 toIndices.push_back(it2->getIndex());
575 }
576 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.Permute(fromIndices, toIndices));
577}
578
579template<typename ValueType>
580InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::multiplyMatrix(
581 InternalAdd<DdType::Sylvan, ValueType> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
582 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
583 for (auto const& ddVariable : summationDdVariables) {
584 summationVariables &= ddVariable;
585 }
586
587 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, this->sylvanMtbdd.AndExists(otherMatrix.sylvanMtbdd, summationVariables.getSylvanBdd()));
588}
589
590template<>
591InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::multiplyMatrix(
592 InternalAdd<DdType::Sylvan, storm::RationalFunction> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
593 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
594 for (auto const& ddVariable : summationDdVariables) {
595 summationVariables &= ddVariable;
596 }
597
598 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(ddManager,
599 this->sylvanMtbdd.AndExistsRF(otherMatrix.sylvanMtbdd, summationVariables.getSylvanBdd()));
600}
601
602template<>
603InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::multiplyMatrix(
604 InternalAdd<DdType::Sylvan, storm::RationalNumber> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
605 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
606 for (auto const& ddVariable : summationDdVariables) {
607 summationVariables &= ddVariable;
608 }
609
610 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(ddManager,
611 this->sylvanMtbdd.AndExistsRN(otherMatrix.sylvanMtbdd, summationVariables.getSylvanBdd()));
612}
613
614template<typename ValueType>
615InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::multiplyMatrix(
616 InternalBdd<DdType::Sylvan> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
617 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
618 for (auto const& ddVariable : summationDdVariables) {
619 summationVariables &= ddVariable;
620 }
621
622 return InternalAdd<DdType::Sylvan, ValueType>(
623 ddManager, this->sylvanMtbdd.AndExists(sylvan::Bdd(otherMatrix.getSylvanBdd().GetBDD()), summationVariables.getSylvanBdd()));
624}
625
626template<>
627InternalAdd<DdType::Sylvan, storm::RationalFunction> InternalAdd<DdType::Sylvan, storm::RationalFunction>::multiplyMatrix(
628 InternalBdd<DdType::Sylvan> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
629 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
630 for (auto const& ddVariable : summationDdVariables) {
631 summationVariables &= ddVariable;
632 }
633
634 return InternalAdd<DdType::Sylvan, storm::RationalFunction>(
635 ddManager, this->sylvanMtbdd.AndExistsRF(sylvan::Bdd(otherMatrix.getSylvanBdd().GetBDD()), summationVariables.getSylvanBdd()));
636}
637
638template<>
639InternalAdd<DdType::Sylvan, storm::RationalNumber> InternalAdd<DdType::Sylvan, storm::RationalNumber>::multiplyMatrix(
640 InternalBdd<DdType::Sylvan> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
641 InternalBdd<DdType::Sylvan> summationVariables = ddManager->getBddOne();
642 for (auto const& ddVariable : summationDdVariables) {
643 summationVariables &= ddVariable;
644 }
645
646 return InternalAdd<DdType::Sylvan, storm::RationalNumber>(
647 ddManager, this->sylvanMtbdd.AndExistsRN(sylvan::Bdd(otherMatrix.getSylvanBdd().GetBDD()), summationVariables.getSylvanBdd()));
648}
649
650template<typename ValueType>
651InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::greater(ValueType const& value) const {
652 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddStrictThreshold(value));
653}
654
655template<>
656InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::greater(storm::RationalNumber const& value) const {
657 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddStrictThresholdRN(value));
658}
659
660template<>
661InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalFunction>::greater(storm::RationalFunction const& value) const {
662 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddStrictThresholdRF(value));
663}
664
665template<typename ValueType>
666InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::greaterOrEqual(ValueType const& value) const {
667 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddThreshold(value));
668}
669
670template<>
671InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalNumber>::greaterOrEqual(storm::RationalNumber const& value) const {
672 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddThresholdRN(value));
673}
674
675template<>
676InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, storm::RationalFunction>::greaterOrEqual(storm::RationalFunction const& value) const {
677 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.BddThresholdRF(value));
678}
679
680template<typename ValueType>
681InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::less(ValueType const& value) const {
682 return !this->greaterOrEqual(value);
683}
684
685template<typename ValueType>
686InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::lessOrEqual(ValueType const& value) const {
687 return !this->greater(value);
688}
689
690template<typename ValueType>
691InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::notZero() const {
692 return InternalBdd<DdType::Sylvan>(ddManager, this->sylvanMtbdd.NotZero());
693}
694
695template<typename ValueType>
696InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::constrain(InternalAdd<DdType::Sylvan, ValueType> const&) const {
697 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Operation (constrain) not yet implemented.");
698}
699
700template<typename ValueType>
701InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::restrict(InternalAdd<DdType::Sylvan, ValueType> const&) const {
702 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Operation (restrict) not yet implemented.");
703}
704
705template<typename ValueType>
706InternalBdd<DdType::Sylvan> InternalAdd<DdType::Sylvan, ValueType>::getSupport() const {
707 return InternalBdd<DdType::Sylvan>(ddManager, sylvan::Bdd(static_cast<BDD>(this->sylvanMtbdd.Support().GetMTBDD())));
708}
709
710template<typename ValueType>
711uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getNonZeroCount(uint_fast64_t numberOfDdVariables) const {
712 if (numberOfDdVariables == 0) {
713 return 0;
714 }
715 return static_cast<uint_fast64_t>(this->sylvanMtbdd.NonZeroCount(numberOfDdVariables));
716}
717
718template<typename ValueType>
719uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getLeafCount() const {
720 return static_cast<uint_fast64_t>(this->sylvanMtbdd.CountLeaves());
721}
722
723template<typename ValueType>
724uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getNodeCount() const {
725 return static_cast<uint_fast64_t>(this->sylvanMtbdd.NodeCount());
726}
727
728template<typename ValueType>
729ValueType InternalAdd<DdType::Sylvan, ValueType>::getMin() const {
730 return getValue(this->sylvanMtbdd.Minimum().GetMTBDD());
731}
732
733template<>
734storm::RationalNumber InternalAdd<DdType::Sylvan, storm::RationalNumber>::getMin() const {
735 return getValue(this->sylvanMtbdd.MinimumRN().GetMTBDD());
736}
737
738template<>
739storm::RationalFunction InternalAdd<DdType::Sylvan, storm::RationalFunction>::getMin() const {
740 return getValue(this->sylvanMtbdd.MinimumRF().GetMTBDD());
741}
742
743template<typename ValueType>
744ValueType InternalAdd<DdType::Sylvan, ValueType>::getMax() const {
745 return getValue(this->sylvanMtbdd.Maximum().GetMTBDD());
746}
747
748template<>
749storm::RationalNumber InternalAdd<DdType::Sylvan, storm::RationalNumber>::getMax() const {
750 return getValue(this->sylvanMtbdd.MaximumRN().GetMTBDD());
751}
752
753template<>
754storm::RationalFunction InternalAdd<DdType::Sylvan, storm::RationalFunction>::getMax() const {
755 return getValue(this->sylvanMtbdd.MaximumRF().GetMTBDD());
756}
757
758template<typename ValueType>
759ValueType InternalAdd<DdType::Sylvan, ValueType>::getValue() const {
760 return getValue(this->sylvanMtbdd.GetMTBDD());
761}
762
763template<typename ValueType>
764bool InternalAdd<DdType::Sylvan, ValueType>::isOne() const {
765 return *this == ddManager->getAddOne<ValueType>();
766}
767
768template<typename ValueType>
769bool InternalAdd<DdType::Sylvan, ValueType>::isZero() const {
770 return *this == ddManager->getAddZero<ValueType>();
771}
772
773template<typename ValueType>
774bool InternalAdd<DdType::Sylvan, ValueType>::isConstant() const {
775 return this->sylvanMtbdd.isTerminal();
776}
777
778template<typename ValueType>
779uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getIndex() const {
780 return static_cast<uint_fast64_t>(this->sylvanMtbdd.TopVar());
781}
782
783template<typename ValueType>
784uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getLevel() const {
785 return this->getIndex();
786}
787
788template<typename ValueType>
789void InternalAdd<DdType::Sylvan, ValueType>::exportToDot(std::string const& filename, std::vector<std::string> const&, bool) const {
790 // Open the file, dump the DD and close it again.
791 FILE* filePointer = fopen(filename.c_str(), "a+");
792 // fopen returns a nullptr on failure
793 if (filePointer == nullptr) {
794 STORM_LOG_ERROR("Failure to open file: " << filename);
795 } else {
796 this->sylvanMtbdd.PrintDot(filePointer);
797 fclose(filePointer);
798 }
799}
800
801template<typename ValueType>
802void InternalAdd<DdType::Sylvan, ValueType>::exportToText(std::string const& filename) const {
803 // Open the file, dump the DD and close it again.
804 FILE* filePointer = fopen(filename.c_str(), "a+");
805 // fopen returns a nullptr on failure
806 if (filePointer == nullptr) {
807 STORM_LOG_ERROR("Failure to open file: " << filename);
808 } else {
809 this->sylvanMtbdd.PrintText(filePointer);
810 fclose(filePointer);
811 }
812}
813
814template<typename ValueType>
815AddIterator<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::begin(DdManager<DdType::Sylvan> const& fullDdManager,
816 InternalBdd<DdType::Sylvan> const& variableCube,
817 uint_fast64_t numberOfDdVariables,
818 std::set<storm::expressions::Variable> const& metaVariables,
819 bool enumerateDontCareMetaVariables) const {
820 return AddIterator<DdType::Sylvan, ValueType>::createBeginIterator(fullDdManager, this->getSylvanMtbdd(), variableCube.getSylvanBdd(), numberOfDdVariables,
821 &metaVariables, enumerateDontCareMetaVariables);
822}
823
824template<typename ValueType>
825AddIterator<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::end(DdManager<DdType::Sylvan> const& fullDdManager) const {
826 return AddIterator<DdType::Sylvan, ValueType>::createEndIterator(fullDdManager);
827}
828
829template<typename ValueType>
830Odd InternalAdd<DdType::Sylvan, ValueType>::createOdd(std::vector<uint_fast64_t> const& ddVariableIndices) const {
831 // Prepare a unique table for each level that keeps the constructed ODD nodes unique.
832 std::vector<std::unordered_map<BDD, std::shared_ptr<Odd>>> uniqueTableForLevels(ddVariableIndices.size() + 1);
833
834 // Now construct the ODD structure from the ADD.
835 std::shared_ptr<Odd> rootOdd =
836 createOddRec(mtbdd_regular(this->getSylvanMtbdd().GetMTBDD()), 0, ddVariableIndices.size(), ddVariableIndices, uniqueTableForLevels);
837
838 // Return a copy of the root node to remove the shared_ptr encapsulation.
839 return Odd(*rootOdd);
840}
841
842template<typename ValueType>
843std::shared_ptr<Odd> InternalAdd<DdType::Sylvan, ValueType>::createOddRec(BDD dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel,
844 std::vector<uint_fast64_t> const& ddVariableIndices,
845 std::vector<std::unordered_map<BDD, std::shared_ptr<Odd>>>& uniqueTableForLevels) {
846 // Check whether the ODD for this node has already been computed (for this level) and if so, return this instead.
847 auto const& iterator = uniqueTableForLevels[currentLevel].find(dd);
848 if (iterator != uniqueTableForLevels[currentLevel].end()) {
849 return iterator->second;
850 } else {
851 // Otherwise, we need to recursively compute the ODD.
852
853 // If we are already past the maximal level that is to be considered, we can simply create an Odd without
854 // successors
855 if (currentLevel == maxLevel) {
856 uint_fast64_t elseOffset = 0;
857 uint_fast64_t thenOffset = 0;
858
859 STORM_LOG_ASSERT(mtbdd_isleaf(dd), "Expected leaf at last level.");
860
861 // If the DD is not the zero leaf, then the then-offset is 1.
862 if (!mtbdd_iszero(dd)) {
863 thenOffset = 1;
864 }
865
866 auto oddNode = std::make_shared<Odd>(nullptr, elseOffset, nullptr, thenOffset);
867 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
868 return oddNode;
869 } else if (mtbdd_isleaf(dd) || ddVariableIndices[currentLevel] < mtbdd_getvar(dd)) {
870 // If we skipped the level in the DD, we compute the ODD just for the else-successor and use the same
871 // node for the then-successor as well.
872 std::shared_ptr<Odd> elseNode = createOddRec(dd, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
873 std::shared_ptr<Odd> thenNode = elseNode;
874 auto oddNode = std::make_shared<Odd>(elseNode, elseNode->getElseOffset() + elseNode->getThenOffset(), thenNode,
875 thenNode->getElseOffset() + thenNode->getThenOffset());
876 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
877 return oddNode;
878 } else {
879 // Otherwise, we compute the ODDs for both the then- and else successors.
880 std::shared_ptr<Odd> elseNode = createOddRec(mtbdd_regular(mtbdd_getlow(dd)), currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
881 std::shared_ptr<Odd> thenNode = createOddRec(mtbdd_regular(mtbdd_gethigh(dd)), currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
882
883 uint_fast64_t totalElseOffset = elseNode->getElseOffset() + elseNode->getThenOffset();
884 uint_fast64_t totalThenOffset = thenNode->getElseOffset() + thenNode->getThenOffset();
885
886 auto oddNode = std::make_shared<Odd>(elseNode, totalElseOffset, thenNode, totalThenOffset);
887 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
888 return oddNode;
889 }
890 }
891}
892
893template<typename ValueType>
894InternalDdManager<DdType::Sylvan> const& InternalAdd<DdType::Sylvan, ValueType>::getInternalDdManager() const {
895 return *ddManager;
896}
897
898template<typename ValueType>
899void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
900 std::vector<ValueType>& targetVector,
901 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
902 forEachRec(this->getSylvanMtbdd().GetMTBDD(), 0, ddVariableIndices.size(), 0, odd, ddVariableIndices,
903 [&function, &targetVector](uint64_t const& offset, ValueType const& value) { targetVector[offset] = function(targetVector[offset], value); });
904}
905
906template<typename ValueType>
907void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
908 std::vector<uint_fast64_t> const& offsets, std::vector<ValueType>& targetVector,
909 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
910 forEachRec(this->getSylvanMtbdd().GetMTBDD(), 0, ddVariableIndices.size(), 0, odd, ddVariableIndices,
911 [&function, &targetVector, &offsets](uint64_t const& offset, ValueType const& value) {
912 ValueType& targetValue = targetVector[offsets[offset]];
913 targetValue = function(targetValue, value);
914 });
915}
916
917template<typename ValueType>
918void InternalAdd<DdType::Sylvan, ValueType>::forEach(Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
919 std::function<void(uint64_t const&, ValueType const&)> const& function) const {
920 forEachRec(this->getSylvanMtbdd().GetMTBDD(), 0, ddVariableIndices.size(), 0, odd, ddVariableIndices, function);
921}
922
923template<typename ValueType>
924void InternalAdd<DdType::Sylvan, ValueType>::forEachRec(MTBDD dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset,
925 Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
926 std::function<void(uint64_t const&, ValueType const&)> const& function) const {
927 // For the empty DD, we do not need to add any entries.
928 if (mtbdd_isleaf(dd) && mtbdd_iszero(dd)) {
929 return;
930 }
931
932 // If we are at the maximal level, the value to be set is stored as a constant in the DD.
933 if (currentLevel == maxLevel) {
934 function(currentOffset, getValue(dd));
935 } else if (mtbdd_isleaf(dd) || ddVariableIndices[currentLevel] < mtbdd_getvar(dd)) {
936 // If we skipped a level, we need to enumerate the explicit entries for the case in which the bit is set
937 // and for the one in which it is not set.
938 forEachRec(dd, currentLevel + 1, maxLevel, currentOffset, odd.getElseSuccessor(), ddVariableIndices, function);
939 forEachRec(dd, currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), odd.getThenSuccessor(), ddVariableIndices, function);
940 } else {
941 // Otherwise, we simply recursively call the function for both (different) cases.
942 MTBDD thenNode = mtbdd_gethigh(dd);
943 MTBDD elseNode = mtbdd_getlow(dd);
944
945 forEachRec(elseNode, currentLevel + 1, maxLevel, currentOffset, odd.getElseSuccessor(), ddVariableIndices, function);
946 forEachRec(thenNode, currentLevel + 1, maxLevel, currentOffset + odd.getElseOffset(), odd.getThenSuccessor(), ddVariableIndices, function);
947 }
948}
949
950template<typename ValueType>
951std::vector<uint64_t> InternalAdd<DdType::Sylvan, ValueType>::decodeGroupLabels(std::vector<uint_fast64_t> const& ddGroupVariableIndices,
952 storm::storage::BitVector const& ddLabelVariableIndices) const {
953 std::vector<uint64_t> result;
954 decodeGroupLabelsRec(mtbdd_regular(this->getSylvanMtbdd().GetMTBDD()), result, ddGroupVariableIndices, ddLabelVariableIndices, 0,
955 ddGroupVariableIndices.size(), 0);
956 return result;
957}
958
959template<typename ValueType>
960void InternalAdd<DdType::Sylvan, ValueType>::decodeGroupLabelsRec(MTBDD dd, std::vector<uint64_t>& labels,
961 std::vector<uint_fast64_t> const& ddGroupVariableIndices,
962 storm::storage::BitVector const& ddLabelVariableIndices, uint_fast64_t currentLevel,
963 uint_fast64_t maxLevel, uint64_t label) const {
964 // For the empty DD, we do not need to create a group.
965 if (mtbdd_isleaf(dd) && mtbdd_iszero(dd)) {
966 return;
967 }
968
969 if (currentLevel == maxLevel) {
970 labels.push_back(label);
971 } else {
972 uint64_t elseLabel = label;
973 uint64_t thenLabel = label;
974
975 if (ddLabelVariableIndices.get(currentLevel)) {
976 elseLabel <<= 1;
977 thenLabel = (thenLabel << 1) | 1;
978 }
979
980 if (mtbdd_isleaf(dd) || ddGroupVariableIndices[currentLevel] < mtbdd_getvar(dd)) {
981 decodeGroupLabelsRec(dd, labels, ddGroupVariableIndices, ddLabelVariableIndices, currentLevel + 1, maxLevel, elseLabel);
982 decodeGroupLabelsRec(dd, labels, ddGroupVariableIndices, ddLabelVariableIndices, currentLevel + 1, maxLevel, thenLabel);
983 } else {
984 // Otherwise, we compute the ODDs for both the then- and else successors.
985 MTBDD thenDdNode = mtbdd_gethigh(dd);
986 MTBDD elseDdNode = mtbdd_getlow(dd);
987
988 decodeGroupLabelsRec(mtbdd_regular(elseDdNode), labels, ddGroupVariableIndices, ddLabelVariableIndices, currentLevel + 1, maxLevel, elseLabel);
989 decodeGroupLabelsRec(mtbdd_regular(thenDdNode), labels, ddGroupVariableIndices, ddLabelVariableIndices, currentLevel + 1, maxLevel, thenLabel);
990 }
991 }
992}
993
994template<typename ValueType>
995std::vector<InternalAdd<DdType::Sylvan, ValueType>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
996 std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
997 std::vector<InternalAdd<DdType::Sylvan, ValueType>> result;
998 splitIntoGroupsRec(mtbdd_regular(this->getSylvanMtbdd().GetMTBDD()), mtbdd_hascomp(this->getSylvanMtbdd().GetMTBDD()), result, ddGroupVariableIndices, 0,
999 ddGroupVariableIndices.size());
1000 return result;
1001}
1002
1003template<typename ValueType>
1004std::vector<std::pair<InternalAdd<DdType::Sylvan, ValueType>, InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1005 InternalAdd<DdType::Sylvan, ValueType> vector, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1006 std::vector<std::pair<InternalAdd<DdType::Sylvan, ValueType>, InternalAdd<DdType::Sylvan, ValueType>>> result;
1007 splitIntoGroupsRec(mtbdd_regular(this->getSylvanMtbdd().GetMTBDD()), mtbdd_hascomp(this->getSylvanMtbdd().GetMTBDD()),
1008 mtbdd_regular(vector.getSylvanMtbdd().GetMTBDD()), mtbdd_hascomp(vector.getSylvanMtbdd().GetMTBDD()), result, ddGroupVariableIndices, 0,
1009 ddGroupVariableIndices.size());
1010 return result;
1011}
1012
1013template<typename ValueType>
1014std::vector<std::vector<InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1015 std::vector<InternalAdd<DdType::Sylvan, ValueType>> const& vectors, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1016 std::vector<std::vector<InternalAdd<DdType::Sylvan, ValueType>>> result;
1017 std::vector<MTBDD> dds;
1018 storm::storage::BitVector negatedDds(vectors.size() + 1);
1019 for (auto const& vector : vectors) {
1020 negatedDds.set(dds.size(), mtbdd_hascomp(vector.getSylvanMtbdd().GetMTBDD()));
1021 dds.push_back(mtbdd_regular(vector.getSylvanMtbdd().GetMTBDD()));
1022 }
1023 dds.push_back(this->getSylvanMtbdd().GetMTBDD());
1024 negatedDds.set(vectors.size(), mtbdd_hascomp(this->getSylvanMtbdd().GetMTBDD()));
1025
1026 splitIntoGroupsRec(dds, negatedDds, result, ddGroupVariableIndices, 0, ddGroupVariableIndices.size());
1027 return result;
1028}
1029
1030template<typename ValueType>
1031void InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroupsRec(MTBDD dd, bool negated, std::vector<InternalAdd<DdType::Sylvan, ValueType>>& groups,
1032 std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel,
1033 uint_fast64_t maxLevel) const {
1034 // For the empty DD, we do not need to create a group.
1035 if (mtbdd_isleaf(dd) && mtbdd_iszero(dd)) {
1036 return;
1037 }
1038
1039 if (currentLevel == maxLevel) {
1040 groups.push_back(InternalAdd<DdType::Sylvan, ValueType>(ddManager, negated ? sylvan::Mtbdd(dd).Negate() : sylvan::Mtbdd(dd)));
1041 } else if (mtbdd_isleaf(dd) || ddGroupVariableIndices[currentLevel] < mtbdd_getvar(dd)) {
1042 splitIntoGroupsRec(dd, negated, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1043 splitIntoGroupsRec(dd, negated, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1044 } else {
1045 // Otherwise, we compute the ODDs for both the then- and else successors.
1046 MTBDD thenDdNode = mtbdd_gethigh(dd);
1047 MTBDD elseDdNode = mtbdd_getlow(dd);
1048
1049 // Determine whether we have to evaluate the successors as if they were complemented.
1050 bool elseComplemented = mtbdd_hascomp(elseDdNode) ^ negated;
1051 bool thenComplemented = mtbdd_hascomp(thenDdNode) ^ negated;
1052
1053 // FIXME: We first traverse the else successor (unlike other variants of this method).
1054 // Otherwise, the GameBasedMdpModelCheckerTest would not terminate. See github issue #64
1055 splitIntoGroupsRec(mtbdd_regular(elseDdNode), elseComplemented, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1056 splitIntoGroupsRec(mtbdd_regular(thenDdNode), thenComplemented, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1057 }
1058}
1059
1060template<typename ValueType>
1061void InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroupsRec(
1062 MTBDD dd1, bool negated1, MTBDD dd2, bool negated2,
1063 std::vector<std::pair<InternalAdd<DdType::Sylvan, ValueType>, InternalAdd<DdType::Sylvan, ValueType>>>& groups,
1064 std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel) const {
1065 // For the empty DD, we do not need to create a group.
1066 if (mtbdd_isleaf(dd1) && mtbdd_isleaf(dd2) && mtbdd_iszero(dd1) && mtbdd_iszero(dd2)) {
1067 return;
1068 }
1069
1070 if (currentLevel == maxLevel) {
1071 groups.push_back(std::make_pair(InternalAdd<DdType::Sylvan, ValueType>(ddManager, negated1 ? sylvan::Mtbdd(dd1).Negate() : sylvan::Mtbdd(dd1)),
1072 InternalAdd<DdType::Sylvan, ValueType>(ddManager, negated2 ? sylvan::Mtbdd(dd2).Negate() : sylvan::Mtbdd(dd2))));
1073 } else if (mtbdd_isleaf(dd1) || ddGroupVariableIndices[currentLevel] < mtbdd_getvar(dd1)) {
1074 if (mtbdd_isleaf(dd2) || ddGroupVariableIndices[currentLevel] < mtbdd_getvar(dd2)) {
1075 splitIntoGroupsRec(dd1, negated1, dd2, negated2, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1076 splitIntoGroupsRec(dd1, negated1, dd2, negated2, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1077 } else {
1078 MTBDD dd2ThenNode = mtbdd_gethigh(dd2);
1079 MTBDD dd2ElseNode = mtbdd_getlow(dd2);
1080
1081 // Determine whether we have to evaluate the successors as if they were complemented.
1082 bool elseComplemented = mtbdd_hascomp(dd2ElseNode) ^ negated2;
1083 bool thenComplemented = mtbdd_hascomp(dd2ThenNode) ^ negated2;
1084
1085 splitIntoGroupsRec(dd1, negated1, mtbdd_regular(dd2ThenNode), thenComplemented, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1086 splitIntoGroupsRec(dd1, negated1, mtbdd_regular(dd2ElseNode), elseComplemented, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1087 }
1088 } else if (mtbdd_isleaf(dd2) || ddGroupVariableIndices[currentLevel] < mtbdd_getvar(dd2)) {
1089 MTBDD dd1ThenNode = mtbdd_gethigh(dd1);
1090 MTBDD dd1ElseNode = mtbdd_getlow(dd1);
1091
1092 // Determine whether we have to evaluate the successors as if they were complemented.
1093 bool elseComplemented = mtbdd_hascomp(dd1ElseNode) ^ negated1;
1094 bool thenComplemented = mtbdd_hascomp(dd1ThenNode) ^ negated1;
1095
1096 splitIntoGroupsRec(mtbdd_regular(dd1ThenNode), thenComplemented, dd2, negated2, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1097 splitIntoGroupsRec(mtbdd_regular(dd1ElseNode), elseComplemented, dd2, negated2, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1098 } else {
1099 MTBDD dd1ThenNode = mtbdd_gethigh(dd1);
1100 MTBDD dd1ElseNode = mtbdd_getlow(dd1);
1101 MTBDD dd2ThenNode = mtbdd_gethigh(dd2);
1102 MTBDD dd2ElseNode = mtbdd_getlow(dd2);
1103
1104 // Determine whether we have to evaluate the successors as if they were complemented.
1105 bool dd1ElseComplemented = mtbdd_hascomp(dd1ElseNode) ^ negated1;
1106 bool dd1ThenComplemented = mtbdd_hascomp(dd1ThenNode) ^ negated1;
1107 bool dd2ElseComplemented = mtbdd_hascomp(dd2ElseNode) ^ negated2;
1108 bool dd2ThenComplemented = mtbdd_hascomp(dd2ThenNode) ^ negated2;
1109
1110 splitIntoGroupsRec(mtbdd_regular(dd1ThenNode), dd1ThenComplemented, mtbdd_regular(dd2ThenNode), dd2ThenComplemented, groups, ddGroupVariableIndices,
1111 currentLevel + 1, maxLevel);
1112 splitIntoGroupsRec(mtbdd_regular(dd1ElseNode), dd1ElseComplemented, mtbdd_regular(dd2ElseNode), dd2ElseComplemented, groups, ddGroupVariableIndices,
1113 currentLevel + 1, maxLevel);
1114 }
1115}
1116
1117template<typename ValueType>
1118void InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroupsRec(std::vector<MTBDD> const& dds, storm::storage::BitVector const& negatedDds,
1119 std::vector<std::vector<InternalAdd<DdType::Sylvan, ValueType>>>& groups,
1120 std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel,
1121 uint_fast64_t maxLevel) const {
1122 // For the empty DD, we do not need to create a group.
1123 {
1124 bool emptyDd = true;
1125 for (auto const& dd : dds) {
1126 if (!(mtbdd_isleaf(dd) && mtbdd_iszero(dd))) {
1127 emptyDd = false;
1128 break;
1129 }
1130 }
1131 if (emptyDd) {
1132 return;
1133 }
1134 }
1135
1136 if (currentLevel == maxLevel) {
1137 std::vector<InternalAdd<DdType::Sylvan, ValueType>> newGroup;
1138 for (uint64_t ddIndex = 0; ddIndex < dds.size(); ++ddIndex) {
1139 newGroup.emplace_back(ddManager, negatedDds.get(ddIndex) ? sylvan::Mtbdd(dds[ddIndex]).Negate() : sylvan::Mtbdd(dds[ddIndex]));
1140 }
1141 groups.push_back(std::move(newGroup));
1142 } else {
1143 std::vector<MTBDD> thenSubDds(dds), elseSubDds(dds);
1144 storm::storage::BitVector thenNegatedSubDds(negatedDds), elseNegatedSubDds(negatedDds);
1145 for (uint64_t ddIndex = 0; ddIndex < dds.size(); ++ddIndex) {
1146 auto const& dd = dds[ddIndex];
1147 if (!mtbdd_isleaf(dd) && ddGroupVariableIndices[currentLevel] == mtbdd_getvar(dd)) {
1148 MTBDD ddThenNode = mtbdd_gethigh(dd);
1149 MTBDD ddElseNode = mtbdd_getlow(dd);
1150 thenSubDds[ddIndex] = mtbdd_regular(ddThenNode);
1151 elseSubDds[ddIndex] = mtbdd_regular(ddElseNode);
1152 // Determine whether we have to evaluate the successors as if they were complemented.
1153 thenNegatedSubDds.set(ddIndex, mtbdd_hascomp(ddThenNode) ^ negatedDds.get(ddIndex));
1154 elseNegatedSubDds.set(ddIndex, mtbdd_hascomp(ddElseNode) ^ negatedDds.get(ddIndex));
1155 }
1156 }
1157 splitIntoGroupsRec(thenSubDds, thenNegatedSubDds, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1158 splitIntoGroupsRec(elseSubDds, elseNegatedSubDds, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
1159 }
1160}
1161
1162template<typename ValueType>
1163void InternalAdd<DdType::Sylvan, ValueType>::toMatrixComponents(std::vector<uint_fast64_t> const& rowGroupIndices, std::vector<uint_fast64_t>& rowIndications,
1164 std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>& columnsAndValues,
1165 Odd const& rowOdd, Odd const& columnOdd, std::vector<uint_fast64_t> const& ddRowVariableIndices,
1166 std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool writeValues) const {
1167 return toMatrixComponentsRec(mtbdd_regular(this->getSylvanMtbdd().GetMTBDD()), mtbdd_hascomp(this->getSylvanMtbdd().GetMTBDD()), rowGroupIndices,
1168 rowIndications, columnsAndValues, rowOdd, columnOdd, 0, 0, ddRowVariableIndices.size() + ddColumnVariableIndices.size(), 0, 0,
1169 ddRowVariableIndices, ddColumnVariableIndices, writeValues);
1170}
1171
1172template<typename ValueType>
1173void InternalAdd<DdType::Sylvan, ValueType>::toMatrixComponentsRec(MTBDD dd, bool negated, std::vector<uint_fast64_t> const& rowGroupOffsets,
1174 std::vector<uint_fast64_t>& rowIndications,
1175 std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>& columnsAndValues,
1176 Odd const& rowOdd, Odd const& columnOdd, uint_fast64_t currentRowLevel,
1177 uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset,
1178 uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices,
1179 std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues) const {
1180 // For the empty DD, we do not need to add any entries.
1181 if (mtbdd_isleaf(dd) && mtbdd_iszero(dd)) {
1182 return;
1183 }
1184
1185 // If we are at the maximal level, the value to be set is stored as a constant in the DD.
1186 if (currentRowLevel + currentColumnLevel == maxLevel) {
1187 if (generateValues) {
1188 columnsAndValues[rowIndications[rowGroupOffsets[currentRowOffset]]] =
1189 storm::storage::MatrixEntry<uint_fast64_t, ValueType>(currentColumnOffset, negated ? -getValue(dd) : getValue(dd));
1190 }
1191 ++rowIndications[rowGroupOffsets[currentRowOffset]];
1192 } else {
1193 MTBDD elseElse;
1194 MTBDD elseThen;
1195 MTBDD thenElse;
1196 MTBDD thenThen;
1197
1198 if (mtbdd_isleaf(dd) || ddColumnVariableIndices[currentColumnLevel] < mtbdd_getvar(dd)) {
1199 elseElse = elseThen = thenElse = thenThen = dd;
1200 } else if (ddRowVariableIndices[currentColumnLevel] < mtbdd_getvar(dd)) {
1201 elseElse = thenElse = mtbdd_getlow(dd);
1202 elseThen = thenThen = mtbdd_gethigh(dd);
1203 } else {
1204 MTBDD elseNode = mtbdd_getlow(dd);
1205 if (mtbdd_isleaf(elseNode) || ddColumnVariableIndices[currentColumnLevel] < mtbdd_getvar(elseNode)) {
1206 elseElse = elseThen = elseNode;
1207 } else {
1208 elseElse = mtbdd_getlow(elseNode);
1209 elseThen = mtbdd_gethigh(elseNode);
1210 }
1211
1212 MTBDD thenNode = mtbdd_gethigh(dd);
1213 if (mtbdd_isleaf(thenNode) || ddColumnVariableIndices[currentColumnLevel] < mtbdd_getvar(thenNode)) {
1214 thenElse = thenThen = thenNode;
1215 } else {
1216 thenElse = mtbdd_getlow(thenNode);
1217 thenThen = mtbdd_gethigh(thenNode);
1218 }
1219 }
1220
1221 // Visit else-else.
1222 toMatrixComponentsRec(mtbdd_regular(elseElse), mtbdd_hascomp(elseElse) ^ negated, rowGroupOffsets, rowIndications, columnsAndValues,
1223 rowOdd.getElseSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset,
1224 currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
1225 // Visit else-then.
1226 toMatrixComponentsRec(mtbdd_regular(elseThen), mtbdd_hascomp(elseThen) ^ negated, rowGroupOffsets, rowIndications, columnsAndValues,
1227 rowOdd.getElseSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel, currentRowOffset,
1228 currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices, ddColumnVariableIndices, generateValues);
1229 // Visit then-else.
1230 toMatrixComponentsRec(mtbdd_regular(thenElse), mtbdd_hascomp(thenElse) ^ negated, rowGroupOffsets, rowIndications, columnsAndValues,
1231 rowOdd.getThenSuccessor(), columnOdd.getElseSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel,
1232 currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset, ddRowVariableIndices, ddColumnVariableIndices, generateValues);
1233 // Visit then-then.
1234 toMatrixComponentsRec(mtbdd_regular(thenThen), mtbdd_hascomp(thenThen) ^ negated, rowGroupOffsets, rowIndications, columnsAndValues,
1235 rowOdd.getThenSuccessor(), columnOdd.getThenSuccessor(), currentRowLevel + 1, currentColumnLevel + 1, maxLevel,
1236 currentRowOffset + rowOdd.getElseOffset(), currentColumnOffset + columnOdd.getElseOffset(), ddRowVariableIndices,
1237 ddColumnVariableIndices, generateValues);
1238 }
1239}
1240
1241template<typename ValueType>
1242InternalAdd<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::fromVector(InternalDdManager<DdType::Sylvan> const* ddManager,
1243 std::vector<ValueType> const& values, storm::dd::Odd const& odd,
1244 std::vector<uint_fast64_t> const& ddVariableIndices) {
1245 uint_fast64_t offset = 0;
1246 return InternalAdd<DdType::Sylvan, ValueType>(ddManager, sylvan::Mtbdd(fromVectorRec(offset, 0, ddVariableIndices.size(), values, odd, ddVariableIndices)));
1247}
1248
1249template<typename ValueType>
1250MTBDD InternalAdd<DdType::Sylvan, ValueType>::fromVectorRec(uint_fast64_t& currentOffset, uint_fast64_t currentLevel, uint_fast64_t maxLevel,
1251 std::vector<ValueType> const& values, Odd const& odd,
1252 std::vector<uint_fast64_t> const& ddVariableIndices) {
1253 if (currentLevel == maxLevel) {
1254 // If we are in a terminal node of the ODD, we need to check whether the then-offset of the ODD is one
1255 // (meaning the encoding is a valid one) or zero (meaning the encoding is not valid). Consequently, we
1256 // need to copy the next value of the vector iff the then-offset is greater than zero.
1257 if (odd.getThenOffset() > 0) {
1258 return getLeaf(values[currentOffset++]);
1259 } else {
1260 return getLeaf(storm::utility::zero<ValueType>());
1261 }
1262 } else {
1263 // If the total offset is zero, we can just return the constant zero DD.
1264 if (odd.getThenOffset() + odd.getElseOffset() == 0) {
1265 return getLeaf(storm::utility::zero<ValueType>());
1266 }
1267
1268 // Determine the new else-successor.
1269 MTBDD elseSuccessor;
1270 if (odd.getElseOffset() > 0) {
1271 elseSuccessor = fromVectorRec(currentOffset, currentLevel + 1, maxLevel, values, odd.getElseSuccessor(), ddVariableIndices);
1272 } else {
1273 elseSuccessor = getLeaf(storm::utility::zero<ValueType>());
1274 }
1275 mtbdd_refs_push(elseSuccessor);
1276
1277 // Determine the new then-successor.
1278 MTBDD thenSuccessor;
1279 if (odd.getThenOffset() > 0) {
1280 thenSuccessor = fromVectorRec(currentOffset, currentLevel + 1, maxLevel, values, odd.getThenSuccessor(), ddVariableIndices);
1281 } else {
1282 thenSuccessor = getLeaf(storm::utility::zero<ValueType>());
1283 }
1284 mtbdd_refs_push(thenSuccessor);
1285
1286 // Create a node representing ITE(currentVar, thenSuccessor, elseSuccessor);
1287 MTBDD currentVar = mtbdd_makenode(ddVariableIndices[currentLevel], mtbdd_false, mtbdd_true);
1288 mtbdd_refs_push(thenSuccessor);
1289#pragma clang diagnostic push
1290#pragma clang diagnostic ignored "-Wextra-semi-stmt"
1291#pragma clang diagnostic ignored "-Wused-but-marked-unused"
1292 MTBDD result = mtbdd_ite(currentVar, thenSuccessor, elseSuccessor);
1293#pragma clang diagnostic pop
1294
1295 // Dispose of the intermediate results
1296 mtbdd_refs_pop(3);
1297
1298 return result;
1299 }
1300}
1301
1302template<typename ValueType>
1303MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(double value) {
1304 return mtbdd_double(value);
1305}
1306
1307template<typename ValueType>
1308MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(uint_fast64_t value) {
1309 return mtbdd_int64(value);
1310}
1311
1312template<typename ValueType>
1313MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(storm::RationalFunction const& value) {
1314 storm_rational_function_ptr ptr = (storm_rational_function_ptr)(&value);
1315 return mtbdd_storm_rational_function(ptr);
1316}
1317
1318template<typename ValueType>
1319MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(storm::RationalNumber const& value) {
1320 storm_rational_function_ptr ptr = (storm_rational_number_ptr)(&value);
1321 return mtbdd_storm_rational_number(ptr);
1322}
1323
1324template<typename ValueType>
1325sylvan::Mtbdd InternalAdd<DdType::Sylvan, ValueType>::getSylvanMtbdd() const {
1326 return sylvanMtbdd;
1327}
1328
1329template<typename ValueType>
1330std::string InternalAdd<DdType::Sylvan, ValueType>::getStringId() const {
1331 std::stringstream ss;
1332 ss << this->getSylvanMtbdd().GetMTBDD();
1333 return ss.str();
1334}
1335
1336#else
1337template<typename ValueType>
1339 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1340 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1341 "version of Storm with Sylvan support.");
1342}
1343
1344template<typename ValueType>
1346 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1347 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1348 "version of Storm with Sylvan support.");
1349}
1350
1351template<typename ValueType>
1353 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1354 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1355 "version of Storm with Sylvan support.");
1356}
1357
1358template<typename ValueType>
1360 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1361 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1362 "version of Storm with Sylvan support.");
1363}
1364
1365template<typename ValueType>
1367 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1368 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1369 "version of Storm with Sylvan support.");
1370}
1371
1372template<typename ValueType>
1374 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1375 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1376 "version of Storm with Sylvan support.");
1377}
1378
1379template<typename ValueType>
1381 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1382 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1383 "version of Storm with Sylvan support.");
1384}
1385
1386template<typename ValueType>
1388 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1389 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1390 "version of Storm with Sylvan support.");
1391}
1392
1393template<typename ValueType>
1395 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1396 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1397 "version of Storm with Sylvan support.");
1398}
1399
1400template<typename ValueType>
1402 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1403 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1404 "version of Storm with Sylvan support.");
1405}
1406
1407template<typename ValueType>
1409 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1410 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1411 "version of Storm with Sylvan support.");
1412}
1413
1414template<typename ValueType>
1416 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1417 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1418 "version of Storm with Sylvan support.");
1419}
1420
1421template<typename ValueType>
1423 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1424 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1425 "version of Storm with Sylvan support.");
1426}
1427
1428template<typename ValueType>
1430 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1431 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1432 "version of Storm with Sylvan support.");
1433}
1434
1435template<typename ValueType>
1437 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1438 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1439 "version of Storm with Sylvan support.");
1440}
1441
1442template<typename ValueType>
1444 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1445 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1446 "version of Storm with Sylvan support.");
1447}
1448
1449template<typename ValueType>
1451 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1452 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1453 "version of Storm with Sylvan support.");
1454}
1455
1456template<typename ValueType>
1458 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1459 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1460 "version of Storm with Sylvan support.");
1461}
1462
1463template<typename ValueType>
1465 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1466 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1467 "version of Storm with Sylvan support.");
1468}
1469
1470template<typename ValueType>
1472 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1473 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1474 "version of Storm with Sylvan support.");
1475}
1476
1477template<typename ValueType>
1479 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1480 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1481 "version of Storm with Sylvan support.");
1482}
1483
1484template<typename ValueType>
1486 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1487 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1488 "version of Storm with Sylvan support.");
1489}
1490
1491template<typename ValueType>
1493 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1494 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1495 "version of Storm with Sylvan support.");
1496}
1497
1498template<typename ValueType>
1500 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1501 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1502 "version of Storm with Sylvan support.");
1503}
1504
1505template<typename ValueType>
1507 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1508 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1509 "version of Storm with Sylvan support.");
1510}
1511
1512template<typename ValueType>
1513template<typename TargetValueType>
1515 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1516 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1517 "version of Storm with Sylvan support.");
1518}
1519
1520template<>
1521template<>
1523 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1524}
1525
1526template<>
1527template<>
1529 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1530}
1531
1532template<>
1533template<>
1535 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1536}
1537
1538template<typename ValueType>
1540 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1541 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1542 "version of Storm with Sylvan support.");
1543}
1544
1545template<typename ValueType>
1547 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1548 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1549 "version of Storm with Sylvan support.");
1550}
1551
1552template<typename ValueType>
1554 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1555 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1556 "version of Storm with Sylvan support.");
1557}
1558
1559template<typename ValueType>
1561 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1562 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1563 "version of Storm with Sylvan support.");
1564}
1565
1566template<typename ValueType>
1568 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1569 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1570 "version of Storm with Sylvan support.");
1571}
1572
1573template<typename ValueType>
1575 bool relative) const {
1576 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1577 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1578 "version of Storm with Sylvan support.");
1579}
1580
1581template<typename ValueType>
1583 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
1584 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1585 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1586 "version of Storm with Sylvan support.");
1587}
1588
1589template<typename ValueType>
1591 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
1592 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1593 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1594 "version of Storm with Sylvan support.");
1595}
1596
1597template<typename ValueType>
1599 InternalAdd<DdType::Sylvan, ValueType> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
1600 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1601 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1602 "version of Storm with Sylvan support.");
1603}
1604
1605template<typename ValueType>
1607 InternalBdd<DdType::Sylvan> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
1608 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1609 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1610 "version of Storm with Sylvan support.");
1611}
1612
1613template<typename ValueType>
1615 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1616 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1617 "version of Storm with Sylvan support.");
1618}
1619
1620template<typename ValueType>
1622 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1623 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1624 "version of Storm with Sylvan support.");
1625}
1626
1627template<typename ValueType>
1629 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1630 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1631 "version of Storm with Sylvan support.");
1632}
1633
1634template<typename ValueType>
1636 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1637 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1638 "version of Storm with Sylvan support.");
1639}
1640
1641template<typename ValueType>
1643 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1644 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1645 "version of Storm with Sylvan support.");
1646}
1647
1648template<typename ValueType>
1650 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1651 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1652 "version of Storm with Sylvan support.");
1653}
1654
1655template<typename ValueType>
1657 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1658 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1659 "version of Storm with Sylvan support.");
1660}
1661
1662template<typename ValueType>
1664 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1665 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1666 "version of Storm with Sylvan support.");
1667}
1668
1669template<typename ValueType>
1670uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getNonZeroCount(uint_fast64_t numberOfDdVariables) const {
1671 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1672 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1673 "version of Storm with Sylvan support.");
1674}
1675
1676template<typename ValueType>
1678 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1679 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1680 "version of Storm with Sylvan support.");
1681}
1682
1683template<typename ValueType>
1685 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1686 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1687 "version of Storm with Sylvan support.");
1688}
1689
1690template<typename ValueType>
1692 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1693 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1694 "version of Storm with Sylvan support.");
1695}
1696
1697template<typename ValueType>
1699 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1700 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1701 "version of Storm with Sylvan support.");
1702}
1703
1704template<typename ValueType>
1706 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1707 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1708 "version of Storm with Sylvan support.");
1709}
1710
1711template<typename ValueType>
1713 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1714 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1715 "version of Storm with Sylvan support.");
1716}
1717
1718template<typename ValueType>
1720 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1721 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1722 "version of Storm with Sylvan support.");
1723}
1724
1725template<typename ValueType>
1727 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1728 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1729 "version of Storm with Sylvan support.");
1730}
1731
1732template<typename ValueType>
1734 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1735 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1736 "version of Storm with Sylvan support.");
1737}
1738
1739template<typename ValueType>
1741 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1742 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1743 "version of Storm with Sylvan support.");
1744}
1745
1746template<typename ValueType>
1747void InternalAdd<DdType::Sylvan, ValueType>::exportToDot(std::string const& filename, std::vector<std::string> const&, bool) const {
1748 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1749 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1750 "version of Storm with Sylvan support.");
1751}
1752
1753template<typename ValueType>
1754void InternalAdd<DdType::Sylvan, ValueType>::exportToText(std::string const& filename) const {
1755 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1756 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1757 "version of Storm with Sylvan support.");
1758}
1759
1760template<typename ValueType>
1762 InternalBdd<DdType::Sylvan> const& variableCube,
1763 uint_fast64_t numberOfDdVariables,
1764 std::set<storm::expressions::Variable> const& metaVariables,
1765 bool enumerateDontCareMetaVariables) const {
1766 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1767 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1768 "version of Storm with Sylvan support.");
1769}
1770
1771template<typename ValueType>
1773 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1774 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1775 "version of Storm with Sylvan support.");
1776}
1777
1778template<typename ValueType>
1779Odd InternalAdd<DdType::Sylvan, ValueType>::createOdd(std::vector<uint_fast64_t> const& ddVariableIndices) const {
1780 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1781 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1782 "version of Storm with Sylvan support.");
1783}
1784
1785template<typename ValueType>
1787 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1788 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1789 "version of Storm with Sylvan support.");
1790}
1791
1792template<typename ValueType>
1793void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1794 std::vector<ValueType>& targetVector,
1795 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
1796 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1797 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1798 "version of Storm with Sylvan support.");
1799}
1800
1801template<typename ValueType>
1802void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1803 std::vector<uint_fast64_t> const& offsets, std::vector<ValueType>& targetVector,
1804 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
1805 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1806 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1807 "version of Storm with Sylvan support.");
1808}
1809
1810template<typename ValueType>
1811void InternalAdd<DdType::Sylvan, ValueType>::forEach(Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1812 std::function<void(uint64_t const&, ValueType const&)> const& function) const {
1813 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1814 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1815 "version of Storm with Sylvan support.");
1816}
1817
1818template<typename ValueType>
1819std::vector<uint64_t> InternalAdd<DdType::Sylvan, ValueType>::decodeGroupLabels(std::vector<uint_fast64_t> const& ddGroupVariableIndices,
1820 storm::storage::BitVector const& ddLabelVariableIndices) const {
1821 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1822 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1823 "version of Storm with Sylvan support.");
1824}
1825
1826template<typename ValueType>
1827std::vector<InternalAdd<DdType::Sylvan, ValueType>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1828 std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1829 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1830 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1831 "version of Storm with Sylvan support.");
1832}
1833
1834template<typename ValueType>
1835std::vector<std::pair<InternalAdd<DdType::Sylvan, ValueType>, InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1836 InternalAdd<DdType::Sylvan, ValueType> vector, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1837 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1838 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1839 "version of Storm with Sylvan support.");
1840}
1841
1842template<typename ValueType>
1843std::vector<std::vector<InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1844 std::vector<InternalAdd<DdType::Sylvan, ValueType>> const& vectors, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1845 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1846 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1847 "version of Storm with Sylvan support.");
1848}
1849
1850template<typename ValueType>
1851void InternalAdd<DdType::Sylvan, ValueType>::toMatrixComponents(std::vector<uint_fast64_t> const& rowGroupIndices, std::vector<uint_fast64_t>& rowIndications,
1852 std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>& columnsAndValues,
1853 Odd const& rowOdd, Odd const& columnOdd, std::vector<uint_fast64_t> const& ddRowVariableIndices,
1854 std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool writeValues) const {
1855 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1856 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1857 "version of Storm with Sylvan support.");
1858}
1859
1860template<typename ValueType>
1862 std::vector<ValueType> const& values, storm::dd::Odd const& odd,
1863 std::vector<uint_fast64_t> const& ddVariableIndices) {
1864 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1865 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1866 "version of Storm with Sylvan support.");
1867}
1868
1869template<typename ValueType>
1871 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1872 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1873 "version of Storm with Sylvan support.");
1874}
1875#endif
1876
1881
1882} // namespace dd
1883} // namespace storm
InternalAdd< DdType::Sylvan, double > toValueType() const
InternalBdd< DdType::CUDD > lessOrEqual(storm::RationalNumber const &value) const
InternalBdd< DdType::CUDD > greaterOrEqual(storm::RationalNumber const &value) const
bool equalModuloPrecision(InternalAdd< DdType::CUDD, storm::RationalNumber > const &, storm::RationalNumber const &, bool) const
InternalBdd< DdType::CUDD > less(storm::RationalNumber const &value) const
InternalBdd< DdType::CUDD > greater(storm::RationalNumber const &value) const
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
#define STORM_LOG_ERROR(message)
Definition logging.h:29
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
SFTBDDChecker::ValueType ValueType
ValueType zero()
Definition constants.cpp:24
carl::RationalFunction< Polynomial, true > RationalFunction