Storm 1.11.1.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 MTBDD result = mtbdd_ite(currentVar, thenSuccessor, elseSuccessor);
1290
1291 // Dispose of the intermediate results
1292 mtbdd_refs_pop(3);
1293
1294 return result;
1295 }
1296}
1297
1298template<typename ValueType>
1299MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(double value) {
1300 return mtbdd_double(value);
1301}
1302
1303template<typename ValueType>
1304MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(uint_fast64_t value) {
1305 return mtbdd_int64(value);
1306}
1307
1308template<typename ValueType>
1309MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(storm::RationalFunction const& value) {
1310 storm_rational_function_ptr ptr = (storm_rational_function_ptr)(&value);
1311 return mtbdd_storm_rational_function(ptr);
1312}
1313
1314template<typename ValueType>
1315MTBDD InternalAdd<DdType::Sylvan, ValueType>::getLeaf(storm::RationalNumber const& value) {
1316 storm_rational_function_ptr ptr = (storm_rational_number_ptr)(&value);
1317 return mtbdd_storm_rational_number(ptr);
1318}
1319
1320template<typename ValueType>
1321sylvan::Mtbdd InternalAdd<DdType::Sylvan, ValueType>::getSylvanMtbdd() const {
1322 return sylvanMtbdd;
1323}
1324
1325template<typename ValueType>
1326std::string InternalAdd<DdType::Sylvan, ValueType>::getStringId() const {
1327 std::stringstream ss;
1328 ss << this->getSylvanMtbdd().GetMTBDD();
1329 return ss.str();
1330}
1331
1332#else
1333template<typename ValueType>
1335 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1336 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1337 "version of Storm with Sylvan support.");
1338}
1339
1340template<typename ValueType>
1342 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1343 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1344 "version of Storm with Sylvan support.");
1345}
1346
1347template<typename ValueType>
1349 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1350 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1351 "version of Storm with Sylvan support.");
1352}
1353
1354template<typename ValueType>
1356 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1357 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1358 "version of Storm with Sylvan support.");
1359}
1360
1361template<typename ValueType>
1363 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1364 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1365 "version of Storm with Sylvan support.");
1366}
1367
1368template<typename ValueType>
1370 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1371 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1372 "version of Storm with Sylvan support.");
1373}
1374
1375template<typename ValueType>
1377 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1378 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1379 "version of Storm with Sylvan support.");
1380}
1381
1382template<typename ValueType>
1384 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1385 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1386 "version of Storm with Sylvan support.");
1387}
1388
1389template<typename ValueType>
1391 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1392 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1393 "version of Storm with Sylvan support.");
1394}
1395
1396template<typename ValueType>
1398 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1399 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1400 "version of Storm with Sylvan support.");
1401}
1402
1403template<typename ValueType>
1405 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1406 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1407 "version of Storm with Sylvan support.");
1408}
1409
1410template<typename ValueType>
1412 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1413 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1414 "version of Storm with Sylvan support.");
1415}
1416
1417template<typename ValueType>
1419 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1420 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1421 "version of Storm with Sylvan support.");
1422}
1423
1424template<typename ValueType>
1426 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1427 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1428 "version of Storm with Sylvan support.");
1429}
1430
1431template<typename ValueType>
1433 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1434 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1435 "version of Storm with Sylvan support.");
1436}
1437
1438template<typename ValueType>
1440 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1441 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1442 "version of Storm with Sylvan support.");
1443}
1444
1445template<typename ValueType>
1447 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1448 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1449 "version of Storm with Sylvan support.");
1450}
1451
1452template<typename ValueType>
1454 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1455 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1456 "version of Storm with Sylvan support.");
1457}
1458
1459template<typename ValueType>
1461 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1462 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1463 "version of Storm with Sylvan support.");
1464}
1465
1466template<typename ValueType>
1468 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1469 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1470 "version of Storm with Sylvan support.");
1471}
1472
1473template<typename ValueType>
1475 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1476 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1477 "version of Storm with Sylvan support.");
1478}
1479
1480template<typename ValueType>
1482 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1483 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1484 "version of Storm with Sylvan support.");
1485}
1486
1487template<typename ValueType>
1489 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1490 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1491 "version of Storm with Sylvan support.");
1492}
1493
1494template<typename ValueType>
1496 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1497 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1498 "version of Storm with Sylvan support.");
1499}
1500
1501template<typename ValueType>
1503 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1504 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1505 "version of Storm with Sylvan support.");
1506}
1507
1508template<typename ValueType>
1509template<typename TargetValueType>
1511 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1512 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1513 "version of Storm with Sylvan support.");
1514}
1515
1516template<>
1517template<>
1519 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1520}
1521
1522template<>
1523template<>
1525 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1526}
1527
1528template<>
1529template<>
1531 STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot convert this ADD to the target type.");
1532}
1533
1534template<typename ValueType>
1536 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1537 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1538 "version of Storm with Sylvan support.");
1539}
1540
1541template<typename ValueType>
1543 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1544 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1545 "version of Storm with Sylvan support.");
1546}
1547
1548template<typename ValueType>
1550 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1551 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1552 "version of Storm with Sylvan support.");
1553}
1554
1555template<typename ValueType>
1557 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1558 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1559 "version of Storm with Sylvan support.");
1560}
1561
1562template<typename ValueType>
1564 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1565 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1566 "version of Storm with Sylvan support.");
1567}
1568
1569template<typename ValueType>
1571 bool relative) const {
1572 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1573 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1574 "version of Storm with Sylvan support.");
1575}
1576
1577template<typename ValueType>
1579 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
1580 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1581 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1582 "version of Storm with Sylvan support.");
1583}
1584
1585template<typename ValueType>
1587 std::vector<InternalBdd<DdType::Sylvan>> const& to) const {
1588 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1589 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1590 "version of Storm with Sylvan support.");
1591}
1592
1593template<typename ValueType>
1595 InternalAdd<DdType::Sylvan, ValueType> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
1596 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1597 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1598 "version of Storm with Sylvan support.");
1599}
1600
1601template<typename ValueType>
1603 InternalBdd<DdType::Sylvan> const& otherMatrix, std::vector<InternalBdd<DdType::Sylvan>> const& summationDdVariables) const {
1604 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1605 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1606 "version of Storm with Sylvan support.");
1607}
1608
1609template<typename ValueType>
1611 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1612 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1613 "version of Storm with Sylvan support.");
1614}
1615
1616template<typename ValueType>
1618 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1619 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1620 "version of Storm with Sylvan support.");
1621}
1622
1623template<typename ValueType>
1625 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1626 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1627 "version of Storm with Sylvan support.");
1628}
1629
1630template<typename ValueType>
1632 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1633 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1634 "version of Storm with Sylvan support.");
1635}
1636
1637template<typename ValueType>
1639 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1640 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1641 "version of Storm with Sylvan support.");
1642}
1643
1644template<typename ValueType>
1646 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1647 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1648 "version of Storm with Sylvan support.");
1649}
1650
1651template<typename ValueType>
1653 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1654 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1655 "version of Storm with Sylvan support.");
1656}
1657
1658template<typename ValueType>
1660 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1661 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1662 "version of Storm with Sylvan support.");
1663}
1664
1665template<typename ValueType>
1666uint_fast64_t InternalAdd<DdType::Sylvan, ValueType>::getNonZeroCount(uint_fast64_t numberOfDdVariables) const {
1667 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1668 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1669 "version of Storm with Sylvan support.");
1670}
1671
1672template<typename ValueType>
1674 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1675 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1676 "version of Storm with Sylvan support.");
1677}
1678
1679template<typename ValueType>
1681 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1682 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1683 "version of Storm with Sylvan support.");
1684}
1685
1686template<typename ValueType>
1688 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1689 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1690 "version of Storm with Sylvan support.");
1691}
1692
1693template<typename ValueType>
1695 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1696 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1697 "version of Storm with Sylvan support.");
1698}
1699
1700template<typename ValueType>
1702 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1703 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1704 "version of Storm with Sylvan support.");
1705}
1706
1707template<typename ValueType>
1709 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1710 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1711 "version of Storm with Sylvan support.");
1712}
1713
1714template<typename ValueType>
1716 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1717 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1718 "version of Storm with Sylvan support.");
1719}
1720
1721template<typename ValueType>
1723 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1724 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1725 "version of Storm with Sylvan support.");
1726}
1727
1728template<typename ValueType>
1730 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1731 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1732 "version of Storm with Sylvan support.");
1733}
1734
1735template<typename ValueType>
1737 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1738 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1739 "version of Storm with Sylvan support.");
1740}
1741
1742template<typename ValueType>
1743void InternalAdd<DdType::Sylvan, ValueType>::exportToDot(std::string const& filename, std::vector<std::string> const&, bool) const {
1744 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1745 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1746 "version of Storm with Sylvan support.");
1747}
1748
1749template<typename ValueType>
1750void InternalAdd<DdType::Sylvan, ValueType>::exportToText(std::string const& filename) const {
1751 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1752 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1753 "version of Storm with Sylvan support.");
1754}
1755
1756template<typename ValueType>
1758 InternalBdd<DdType::Sylvan> const& variableCube,
1759 uint_fast64_t numberOfDdVariables,
1760 std::set<storm::expressions::Variable> const& metaVariables,
1761 bool enumerateDontCareMetaVariables) const {
1762 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1763 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1764 "version of Storm with Sylvan support.");
1765}
1766
1767template<typename ValueType>
1769 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1770 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1771 "version of Storm with Sylvan support.");
1772}
1773
1774template<typename ValueType>
1775Odd InternalAdd<DdType::Sylvan, ValueType>::createOdd(std::vector<uint_fast64_t> const& ddVariableIndices) const {
1776 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1777 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1778 "version of Storm with Sylvan support.");
1779}
1780
1781template<typename ValueType>
1783 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1784 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1785 "version of Storm with Sylvan support.");
1786}
1787
1788template<typename ValueType>
1789void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1790 std::vector<ValueType>& targetVector,
1791 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
1792 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1793 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1794 "version of Storm with Sylvan support.");
1795}
1796
1797template<typename ValueType>
1798void InternalAdd<DdType::Sylvan, ValueType>::composeWithExplicitVector(storm::dd::Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1799 std::vector<uint_fast64_t> const& offsets, std::vector<ValueType>& targetVector,
1800 std::function<ValueType(ValueType const&, ValueType const&)> const& function) const {
1801 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1802 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1803 "version of Storm with Sylvan support.");
1804}
1805
1806template<typename ValueType>
1807void InternalAdd<DdType::Sylvan, ValueType>::forEach(Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices,
1808 std::function<void(uint64_t const&, ValueType const&)> const& function) const {
1809 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1810 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1811 "version of Storm with Sylvan support.");
1812}
1813
1814template<typename ValueType>
1815std::vector<uint64_t> InternalAdd<DdType::Sylvan, ValueType>::decodeGroupLabels(std::vector<uint_fast64_t> const& ddGroupVariableIndices,
1816 storm::storage::BitVector const& ddLabelVariableIndices) const {
1817 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1818 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1819 "version of Storm with Sylvan support.");
1820}
1821
1822template<typename ValueType>
1823std::vector<InternalAdd<DdType::Sylvan, ValueType>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1824 std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1825 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1826 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1827 "version of Storm with Sylvan support.");
1828}
1829
1830template<typename ValueType>
1831std::vector<std::pair<InternalAdd<DdType::Sylvan, ValueType>, InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1832 InternalAdd<DdType::Sylvan, ValueType> vector, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1833 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1834 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1835 "version of Storm with Sylvan support.");
1836}
1837
1838template<typename ValueType>
1839std::vector<std::vector<InternalAdd<DdType::Sylvan, ValueType>>> InternalAdd<DdType::Sylvan, ValueType>::splitIntoGroups(
1840 std::vector<InternalAdd<DdType::Sylvan, ValueType>> const& vectors, std::vector<uint_fast64_t> const& ddGroupVariableIndices) const {
1841 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1842 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1843 "version of Storm with Sylvan support.");
1844}
1845
1846template<typename ValueType>
1847void InternalAdd<DdType::Sylvan, ValueType>::toMatrixComponents(std::vector<uint_fast64_t> const& rowGroupIndices, std::vector<uint_fast64_t>& rowIndications,
1848 std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>& columnsAndValues,
1849 Odd const& rowOdd, Odd const& columnOdd, std::vector<uint_fast64_t> const& ddRowVariableIndices,
1850 std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool writeValues) const {
1851 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1852 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1853 "version of Storm with Sylvan support.");
1854}
1855
1856template<typename ValueType>
1858 std::vector<ValueType> const& values, storm::dd::Odd const& odd,
1859 std::vector<uint_fast64_t> const& ddVariableIndices) {
1860 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1861 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1862 "version of Storm with Sylvan support.");
1863}
1864
1865template<typename ValueType>
1867 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
1868 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
1869 "version of Storm with Sylvan support.");
1870}
1871#endif
1872
1877
1878} // namespace dd
1879} // namespace storm
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:26
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
SFTBDDChecker::ValueType ValueType