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 uid_type = node_type::uid_type;
66
70 using label_type = node_type::label_type;
71
75 using signed_label_type = node_type::signed_label_type;
76
80 using arc_type = arc;
81
86
91 std::variant<no_file, shared_node_file_type, shared_arc_file_type> _union;
92
96 bool _negate = false;
97
102
107
109 // Constructors
110
114 __dd() = default;
115
120 : _union(f)
121 {}
122
127 : _union(f)
128 , _policy(ep)
129 {}
130
135 __dd(const dd& dd);
136
138 // Accessors
139 // TODO: change from 'file_t' to 'file::value_type'.
140
144 template <typename file_t>
145 bool
146 has() const
147 {
148 return std::holds_alternative<file_t>(_union);
149 }
150
156 template <typename file_t>
157 const file_t&
158 get() const
159 {
160 return std::get<file_t>(_union);
161 }
162
168 bool
169 empty() const
170 {
171 return has<no_file>();
172 }
173
174 // TODO (optimisation):
175 // Add precondition to be with 'arcs' only?
176
180 size_t
181 size() const
182 {
184 // TODO (QMDD): Divide by node::outdegree instead of 2u
185 return get<shared_arc_file_type>()->size() / 2u;
186 }
187 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->size(); }
188 return 0u;
189 }
190
197 cut::size_type
198 max_1level_cut(const cut ct) const
199 {
202 return af->max_1level_cut + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
203 + (ct.includes(true) ? af->number_of_terminals[true] : 0u);
204 }
205 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_1level_cut[ct]; }
206 return 0u;
207 }
208
215 cut::size_type
216 max_2level_cut(const cut ct) const
217 {
220 return std::min( // 3/2 times the 1-level cut
221 (3 * af->max_1level_cut) / 2 + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
222 + (ct.includes(true) ? af->number_of_terminals[true] : 0u),
223 // At most the number of nodes + 1
224 (af->size() / 2u) + 1);
225 }
226 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_2level_cut[ct]; }
227 return 0u;
228 }
229
233 size_t
234 number_of_terminals(const bool value) const
235 {
237 return get<shared_arc_file_type>()->number_of_terminals[this->_negate ^ value];
238 }
240 return get<shared_node_file_type>()->number_of_terminals[this->_negate ^ value];
241 }
242 return 0u;
243 }
244
248 size_t
250 {
253 return af->number_of_terminals[false] + af->number_of_terminals[true];
254 }
257 return nf->number_of_terminals[false] + nf->number_of_terminals[true];
258 }
259 return 0u;
260 }
261 };
262
269 class dd
270 {
272 // Constants
273 public:
278
282 using pointer_type = node_type::pointer_type;
283
287 using uid_type = node_type::uid_type;
288
292 using label_type = node_type::label_type;
293
297 using signed_label_type = node_type::signed_label_type;
298
302 static constexpr label_type max_label = node_type::max_label;
303
307 using id_type = node_type::id_type;
308
312 static constexpr id_type max_id = node_type::max_id;
313
317 using terminal_type = typename node_type::terminal_type;
318
323
328
330 // Internal state
331 protected:
336
342 void
344 {
345 this->_file.reset();
346 }
347
350 //
351 // TODO: move to 'bdd' or generalize to 'attribute'?
353 bool _negate = false;
354
359
361 // Constructors
362 public:
367 : _file(f)
368 , _negate(negate)
369 , _shift(shift)
370 {}
371
376 dd(const dd& dd) = default;
377
381 dd(dd&& dd) = default;
382
384 // NOTE:
385 //
386 // To implement the specific DD, add the following move-conversion that runs the Reduce
387 // algorithm.
388 //
389 // dd(__dd &&dd)
391
392 public:
397 file_ptr() const
398 {
399 return this->_file;
400 }
401
406 const node_file_type*
408 {
409 return this->_file.get();
410 }
411
415 bool
417 {
418 return this->_negate;
419 }
420
425 shift() const
426 {
427 return this->_shift;
428 }
429
437 cut::size_type
438 max_1level_cut(const cut ct) const
439 {
440 return this->_file->max_1level_cut[negate_cut_type(ct)];
441 }
442
449 cut::size_type
450 max_2level_cut(const cut ct) const
451 {
452 return this->_file->max_2level_cut[negate_cut_type(ct)];
453 }
454
456
460 size_t
461 size() const
462 {
463 return this->_file->size();
464 }
465
469 size_t
470 width() const
471 {
472 return this->_file->width;
473 }
474
478 size_t
479 number_of_terminals(const bool value) const
480 {
481 return this->_file->number_of_terminals[this->_negate ^ value];
482 }
483
487 size_t
489 {
490 return this->number_of_terminals(false) + this->number_of_terminals(true);
491 }
492
493 private:
498 cut
499 negate_cut_type(const cut ct) const
500 {
501 if (!this->_negate) { return ct; }
502
503 switch (ct) {
504 case cut::Internal_False: return cut::Internal_True;
505 case cut::Internal_True: return cut::Internal_False;
506 default: return ct;
507 }
508 }
509
511 // Friends
512 friend class __dd;
513 };
514
515 inline __dd::__dd(const dd& dd)
516 : _union(dd._file)
517 , _negate(dd._negate)
518 , _shift(dd._shift)
519 {}
520
522 template <typename DD, typename __DD>
523 class dd_policy
524 {
527 public:
531 using dd_type = DD;
532
536 using __dd_type = __DD;
537
541 using node_type = typename dd_type::node_type;
542
546 using pointer_type = typename dd_type::pointer_type;
547
551 using uid_type = typename dd_type::uid_type;
552
556 using children_type = typename node_type::children_type;
557
561 using label_type = typename dd_type::label_type;
562
566 using signed_label_type = typename dd_type::label_type;
567
571 static constexpr label_type max_label = dd_type::max_label;
572
576 using id_type = typename dd_type::id_type;
577
581 static constexpr id_type max_id = dd_type::max_id;
582
586 using terminal_type = typename dd_type::terminal_type;
587
591 using shared_node_file_type = typename __dd_type::shared_node_file_type;
592
596 using shared_arc_file_type = typename __dd_type::shared_arc_file_type;
597
600 public:
606 static inline pointer_type
607 reduction_rule(const node_type& n);
608
615 static inline children_type
616 reduction_rule_inv(const pointer_type& child);
617 };
618
620}
621
622#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:106
shared_levelized_file< arc_type > shared_arc_file_type
Type of the file object arc-based representation of a diagram.
Definition dd.h:85
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:75
__dd()=default
Default construction to nothing.
arc arc_type
Type of nodes of this diagram.
Definition dd.h:80
__dd(const shared_arc_file_type &f, const exec_policy &ep)
Conversion for algorithms returning to-be reduced arcs.
Definition dd.h:126
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:91
node_type::uid_type uid_type
Type of unique identifiers (pointers without metadata) of this diagram.
Definition dd.h:65
bool has() const
Whether the union currently holds a certain file type.
Definition dd.h:146
__dd(const shared_node_file_type &f)
Conversion for algorithms returning already-reduced nodes.
Definition dd.h:119
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:216
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:249
bool _negate
Propagation of the dd.negate flag.
Definition dd.h:96
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:181
const file_t & get() const
Get the content of a certain type.
Definition dd.h:158
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:198
bool empty() const
Whether it currently holds no content.
Definition dd.h:169
node_type::label_type label_type
Type of this node's variable label.
Definition dd.h:70
signed_label_type _shift
Propagation of the dd.negate flag.
Definition dd.h:101
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:234
Container for the files that represent a Decision Diagram.
Definition dd.h:270
static constexpr id_type max_id
The maximal possible value for this nodes level identifier.
Definition dd.h:312
levelized_file< node_type > node_file_type
File type for the file object representing the diagram.
Definition dd.h:322
bool _negate
Whether to negate the leaves when reading nodes from the file.
Definition dd.h:353
bool is_negated() const
Read-only access to the negation flag.
Definition dd.h:416
signed_label_type _shift
Number of levels to shift by.
Definition dd.h:358
node_type::uid_type uid_type
Type of unique identifiers (pointers without metadata) of this diagram.
Definition dd.h:287
const shared_node_file_type file_ptr() const
Read-only access to the raw files and meta information.
Definition dd.h:397
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:366
shared_file_ptr< node_file_type > shared_node_file_type
File type for the shared file object representing the diagram.
Definition dd.h:327
static constexpr label_type max_label
The maximal possible value for a unique identifier's label.
Definition dd.h:302
node_type::signed_label_type signed_label_type
Type for difference between variable labels.
Definition dd.h:297
node_type::label_type label_type
Type of this node's variable label.
Definition dd.h:292
node_type::pointer_type pointer_type
Type of pointers of this diagram.
Definition dd.h:282
void deref()
Release the claim on the underlying file, thereby decreasing its reference counter....
Definition dd.h:343
signed_label_type shift() const
Read-only access to the number of levels to shift.
Definition dd.h:425
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:335
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:479
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:407
typename node_type::terminal_type terminal_type
Type of a terminal value.
Definition dd.h:317
node_type::id_type id_type
Type of this node's level identifier.
Definition dd.h:307
size_t size() const
The number of elements in the node file.
Definition dd.h:461
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:470
node node_type
Type of nodes of this diagram.
Definition dd.h:277
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:488
consumer< ValueType > make_consumer(OutputIt &&iter)
Wrap an iterator into a consumer function.
Definition functional.h:71