Adiar 2.1.0
An External Memory Decision Diagram Library
Loading...
Searching...
No Matches
dd.h
1#ifndef ADIAR_INTERNAL_DD_H
2#define ADIAR_INTERNAL_DD_H
3
4#include <variant>
5
6#include <adiar/exec_policy.h>
7
8#include <adiar/internal/cut.h>
9#include <adiar/internal/data_types/arc.h>
10#include <adiar/internal/data_types/node.h>
11#include <adiar/internal/io/arc_file.h>
12#include <adiar/internal/io/node_file.h>
13
14namespace adiar::internal
15{
16 // TODO (MDD):
17 // TODO (QMDD):
18 // TODO (ADD (64-bit)):
19 // template both 'dd' and '__dd' with the node type (and derive the
20 // corresponding arc type).
21
22 class dd;
23
28 using no_file = std::monostate;
29
44 class __dd
45 {
46 public:
50 using node_type = node;
51
56
60 using pointer_type = node_type::pointer_type;
61
65 using label_type = node_type::label_type;
66
70 using signed_label_type = node_type::signed_label_type;
71
75 using arc_type = arc;
76
81
86 std::variant<no_file, shared_node_file_type, shared_arc_file_type> _union;
87
91 bool _negate = false;
92
97
102
104 // Constructors
105
109 __dd() = default;
110
115 : _union(f)
116 {}
117
122 : _union(f)
123 , _policy(ep)
124 {}
125
130 __dd(const dd& dd);
131
133 // Accessors
134 // TODO: change from 'file_t' to 'file::value_type'.
135
139 template <typename file_t>
140 bool
141 has() const
142 {
143 return std::holds_alternative<file_t>(_union);
144 }
145
151 template <typename file_t>
152 const file_t&
153 get() const
154 {
155 return std::get<file_t>(_union);
156 }
157
163 bool
164 empty() const
165 {
166 return has<no_file>();
167 }
168
169 // TODO (optimisation):
170 // Add precondition to be with 'arcs' only?
171
175 size_t
176 size() const
177 {
179 // TODO (QMDD): Divide by node::outdegree instead of 2u
180 return get<shared_arc_file_type>()->size() / 2u;
181 }
182 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->size(); }
183 return 0u;
184 }
185
192 cut::size_type
193 max_1level_cut(const cut ct) const
194 {
197 return af->max_1level_cut + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
198 + (ct.includes(true) ? af->number_of_terminals[true] : 0u);
199 }
200 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_1level_cut[ct]; }
201 return 0u;
202 }
203
210 cut::size_type
211 max_2level_cut(const cut ct) const
212 {
215 return std::min( // 3/2 times the 1-level cut
216 (3 * af->max_1level_cut) / 2 + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
217 + (ct.includes(true) ? af->number_of_terminals[true] : 0u),
218 // At most the number of nodes + 1
219 (af->size() / 2u) + 1);
220 }
221 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_2level_cut[ct]; }
222 return 0u;
223 }
224
228 size_t
229 number_of_terminals(const bool value) const
230 {
232 return get<shared_arc_file_type>()->number_of_terminals[this->_negate ^ value];
233 }
235 return get<shared_node_file_type>()->number_of_terminals[this->_negate ^ value];
236 }
237 return 0u;
238 }
239
243 size_t
245 {
248 return af->number_of_terminals[false] + af->number_of_terminals[true];
249 }
252 return nf->number_of_terminals[false] + nf->number_of_terminals[true];
253 }
254 return 0u;
255 }
256 };
257
264 class dd
265 {
267 // Constants
268 public:
273
277 using pointer_type = node_type::pointer_type;
278
282 using label_type = node_type::label_type;
283
287 using signed_label_type = node_type::signed_label_type;
288
292 static constexpr label_type max_label = node_type::max_label;
293
297 using id_type = node_type::id_type;
298
302 static constexpr id_type max_id = node_type::max_id;
303
307 using terminal_type = typename node_type::terminal_type;
308
313
318
320 // Internal state
321 protected:
326
332 void
334 {
335 this->_file.reset();
336 }
337
340 //
341 // TODO: move to 'bdd' or generalize to 'attribute'?
343 bool _negate = false;
344
349
351 // Constructors
352 public:
357 : _file(f)
358 , _negate(negate)
359 , _shift(shift)
360 {}
361
366 dd(const dd& dd) = default;
367
371 dd(dd&& dd) = default;
372
374 // NOTE:
375 //
376 // To implement the specific DD, add the following move-conversion that runs the Reduce
377 // algorithm.
378 //
379 // dd(__dd &&dd)
381
382 public:
387 file_ptr() const
388 {
389 return this->_file;
390 }
391
396 const node_file_type*
398 {
399 return this->_file.get();
400 }
401
405 bool
407 {
408 return this->_negate;
409 }
410
415 shift() const
416 {
417 return this->_shift;
418 }
419
427 cut::size_type
428 max_1level_cut(const cut ct) const
429 {
430 return this->_file->max_1level_cut[negate_cut_type(ct)];
431 }
432
439 cut::size_type
440 max_2level_cut(const cut ct) const
441 {
442 return this->_file->max_2level_cut[negate_cut_type(ct)];
443 }
444
446
450 size_t
451 size() const
452 {
453 return this->_file->size();
454 }
455
459 size_t
460 width() const
461 {
462 return this->_file->width;
463 }
464
468 size_t
469 number_of_terminals(const bool value) const
470 {
471 return this->_file->number_of_terminals[this->_negate ^ value];
472 }
473
477 size_t
479 {
480 return this->number_of_terminals(false) + this->number_of_terminals(true);
481 }
482
483 private:
488 cut
489 negate_cut_type(const cut ct) const
490 {
491 if (!this->_negate) { return ct; }
492
493 switch (ct) {
494 case cut::Internal_False: return cut::Internal_True;
495 case cut::Internal_True: return cut::Internal_False;
496 default: return ct;
497 }
498 }
499
501 // Friends
502 friend class __dd;
503 };
504
505 inline __dd::__dd(const dd& dd)
506 : _union(dd._file)
507 , _negate(dd._negate)
508 , _shift(dd._shift)
509 {}
510
512 template <typename DD, typename __DD>
513 class dd_policy
514 {
517 public:
521 using dd_type = DD;
522
526 using __dd_type = __DD;
527
531 using node_type = typename dd_type::node_type;
532
536 using pointer_type = typename dd_type::pointer_type;
537
541 using children_type = typename node_type::children_type;
542
546 using label_type = typename dd_type::label_type;
547
551 using signed_label_type = typename dd_type::label_type;
552
556 static constexpr label_type max_label = dd_type::max_label;
557
561 using id_type = typename dd_type::id_type;
562
566 static constexpr id_type max_id = dd_type::max_id;
567
571 using terminal_type = typename dd_type::terminal_type;
572
576 using shared_node_file_type = typename __dd_type::shared_node_file_type;
577
581 using shared_arc_file_type = typename __dd_type::shared_arc_file_type;
582
585 public:
591 static inline pointer_type
592 reduction_rule(const node_type& n);
593
600 static inline children_type
601 reduction_rule_inv(const pointer_type& child);
602 };
603
605}
606
607#endif // ADIAR_INTERNAL_DD_H
Settings to dictate the execution of Adiar's algorithms.
Definition exec_policy.h:35
Definition dd.h:45
exec_policy _policy
Copy of the execution policy given to the top-down algorithm.
Definition dd.h:101
shared_levelized_file< arc_type > shared_arc_file_type
Type of the file object arc-based representation of a diagram.
Definition dd.h:80
shared_levelized_file< node_type > shared_node_file_type
Type of the file object node-based representation of a diagram.
Definition dd.h:55
node_type::signed_label_type signed_label_type
Type for difference between variable labels.
Definition dd.h:70
__dd()=default
Default construction to nothing.
arc arc_type
Type of nodes of this diagram.
Definition dd.h:75
__dd(const shared_arc_file_type &f, const exec_policy &ep)
Conversion for algorithms returning to-be reduced arcs.
Definition dd.h:121
std::variant< no_file, shared_node_file_type, shared_arc_file_type > _union
Union of levelized node or arc files to reflect the possible return types of a function and a 'no_fil...
Definition dd.h:86
bool has() const
Whether the union currently holds a certain file type.
Definition dd.h:141
__dd(const shared_node_file_type &f)
Conversion for algorithms returning already-reduced nodes.
Definition dd.h:114
cut::size_type max_2level_cut(const cut ct) const
Obtain the 2-level cut of the desired type, i.e. of the sub-graph including the desired type of arcs.
Definition dd.h:211
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:244
bool _negate
Propagation of the dd.negate flag.
Definition dd.h:91
node node_type
Type of nodes of this diagram.
Definition dd.h:50
node_type::pointer_type pointer_type
Type of pointers of this diagram.
Definition dd.h:60
size_t size() const
Number of nodes.
Definition dd.h:176
const file_t & get() const
Get the content of a certain type.
Definition dd.h:153
cut::size_type max_1level_cut(const cut ct) const
Obtain the 1-level cut of the desired type, i.e. of the sub-graph including the desired type of arcs.
Definition dd.h:193
bool empty() const
Whether it currently holds no content.
Definition dd.h:164
node_type::label_type label_type
Type of this node's variable label.
Definition dd.h:65
signed_label_type _shift
Propagation of the dd.negate flag.
Definition dd.h:96
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:229
Container for the files that represent a Decision Diagram.
Definition dd.h:265
static constexpr id_type max_id
The maximal possible value for this nodes level identifier.
Definition dd.h:302
levelized_file< node_type > node_file_type
File type for the file object representing the diagram.
Definition dd.h:312
bool _negate
Whether to negate the leaves when reading nodes from the file.
Definition dd.h:343
bool is_negated() const
Read-only access to the negation flag.
Definition dd.h:406
signed_label_type _shift
Number of levels to shift by.
Definition dd.h:348
const shared_node_file_type file_ptr() const
Read-only access to the raw files and meta information.
Definition dd.h:387
dd(const shared_node_file_type &f, bool negate=false, signed_label_type shift=0)
Constructor to wrap the node-based result of an algorithm.
Definition dd.h:356
shared_file_ptr< node_file_type > shared_node_file_type
File type for the shared file object representing the diagram.
Definition dd.h:317
static constexpr label_type max_label
The maximal possible value for a unique identifier's label.
Definition dd.h:292
node_type::signed_label_type signed_label_type
Type for difference between variable labels.
Definition dd.h:287
node_type::label_type label_type
Type of this node's variable label.
Definition dd.h:282
node_type::pointer_type pointer_type
Type of pointers of this diagram.
Definition dd.h:277
void deref()
Release the claim on the underlying file, thereby decreasing its reference counter....
Definition dd.h:333
signed_label_type shift() const
Read-only access to the number of levels to shift.
Definition dd.h:415
dd(dd &&dd)=default
Move construction, taking over ownership of the files underneath.
shared_node_file_type _file
The file describing the actual DAG of the decision diagram.
Definition dd.h:325
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:469
const node_file_type * operator->() const
Read-only access to the members of the raw files and meta information, i.e. this is similar to writin...
Definition dd.h:397
typename node_type::terminal_type terminal_type
Type of a terminal value.
Definition dd.h:307
node_type::id_type id_type
Type of this node's level identifier.
Definition dd.h:297
size_t size() const
The number of elements in the node file.
Definition dd.h:451
dd(const dd &dd)=default
Copy construction, incrementing the reference count on the file underneath.
size_t width() const
The number of nodes on the widest level.
Definition dd.h:460
node node_type
Type of nodes of this diagram.
Definition dd.h:272
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:478
consumer< ValueType > make_consumer(OutputIt &iter)
Wrap an iterator into a consumer function.
Definition functional.h:67