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 level_type = node_type::level_type;
71
75 using signed_level_type = node_type::signed_level_type;
76
81
86
90 using arc_type = arc;
91
96
101 std::variant<no_file, shared_node_file_type, shared_arc_file_type> _union;
102
106 bool _negate = false;
107
112
117
119 // Constructors
120
124 __dd() = default;
125
130 : _union(f)
131 {}
132
137 : _union(f)
138 , _policy(ep)
139 {}
140
145 __dd(const dd& dd);
146
148 // Accessors
149 // TODO: change from 'file_t' to 'file::value_type'.
150
154 template <typename file_t>
155 bool
156 has() const
157 {
158 return std::holds_alternative<file_t>(_union);
159 }
160
166 template <typename file_t>
167 const file_t&
168 get() const
169 {
170 return std::get<file_t>(_union);
171 }
172
178 bool
179 empty() const
180 {
181 return has<no_file>();
182 }
183
184 // TODO (optimisation):
185 // Add precondition to be with 'arcs' only?
186
190 size_t
191 size() const
192 {
194 // TODO (QMDD): Divide by node::outdegree instead of 2u
195 return get<shared_arc_file_type>()->size() / 2u;
196 }
197 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->size(); }
198 return 0u;
199 }
200
207 cut::size_type
208 max_1level_cut(const cut ct) const
209 {
212 return af->max_1level_cut + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
213 + (ct.includes(true) ? af->number_of_terminals[true] : 0u);
214 }
215 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_1level_cut[ct]; }
216 return 0u;
217 }
218
225 cut::size_type
226 max_2level_cut(const cut ct) const
227 {
230 return std::min( // 3/2 times the 1-level cut
231 (3 * af->max_1level_cut) / 2 + (ct.includes(false) ? af->number_of_terminals[false] : 0u)
232 + (ct.includes(true) ? af->number_of_terminals[true] : 0u),
233 // At most the number of nodes + 1
234 (af->size() / 2u) + 1);
235 }
236 if (has<shared_node_file_type>()) { return get<shared_node_file_type>()->max_2level_cut[ct]; }
237 return 0u;
238 }
239
243 size_t
244 number_of_terminals(const bool value) const
245 {
247 return get<shared_arc_file_type>()->number_of_terminals[this->_negate ^ value];
248 }
250 return get<shared_node_file_type>()->number_of_terminals[this->_negate ^ value];
251 }
252 return 0u;
253 }
254
258 size_t
260 {
263 return af->number_of_terminals[false] + af->number_of_terminals[true];
264 }
267 return nf->number_of_terminals[false] + nf->number_of_terminals[true];
268 }
269 return 0u;
270 }
271 };
272
279 class dd
280 {
282 // Constants
283 public:
288
292 using pointer_type = node_type::pointer_type;
293
297 using uid_type = node_type::uid_type;
298
302 using level_type = node_type::level_type;
303
307 using signed_level_type = node_type::signed_level_type;
308
313
318
322 static constexpr label_type max_label = node_type::max_label;
323
327 using id_type = node_type::id_type;
328
332 static constexpr id_type max_id = node_type::max_id;
333
337 using terminal_type = typename node_type::terminal_type;
338
343
348
350 // Internal state
351 protected:
356
362 void
364 {
365 this->_file.reset();
366 }
367
370 //
371 // TODO: move to 'bdd' or generalize to 'attribute'?
373 bool _negate = false;
374
379
381 // Constructors
382 public:
387 : _file(f)
388 , _negate(negate)
389 , _shift(shift)
390 {}
391
396 dd(const dd& dd) = default;
397
401 dd(dd&& dd) = default;
402
404 // NOTE:
405 //
406 // To implement the specific DD, add the following move-conversion that runs the Reduce
407 // algorithm.
408 //
409 // dd(__dd &&dd)
411
412 public:
417 file_ptr() const
418 {
419 return this->_file;
420 }
421
426 const node_file_type*
428 {
429 return this->_file.get();
430 }
431
435 bool
437 {
438 return this->_negate;
439 }
440
445 shift() const
446 {
447 return this->_shift;
448 }
449
457 cut::size_type
458 max_1level_cut(const cut ct) const
459 {
460 return this->_file->max_1level_cut[negate_cut_type(ct)];
461 }
462
469 cut::size_type
470 max_2level_cut(const cut ct) const
471 {
472 return this->_file->max_2level_cut[negate_cut_type(ct)];
473 }
474
476
480 size_t
481 size() const
482 {
483 return this->_file->size();
484 }
485
489 size_t
490 width() const
491 {
492 return this->_file->width;
493 }
494
498 size_t
499 number_of_terminals(const bool value) const
500 {
501 return this->_file->number_of_terminals[this->_negate ^ value];
502 }
503
507 size_t
509 {
510 return this->number_of_terminals(false) + this->number_of_terminals(true);
511 }
512
513 private:
518 cut
519 negate_cut_type(const cut ct) const
520 {
521 if (!this->_negate) { return ct; }
522
523 switch (ct) {
524 case cut::Internal_False: return cut::Internal_True;
525 case cut::Internal_True: return cut::Internal_False;
526 default: return ct;
527 }
528 }
529 };
530
531 inline __dd::__dd(const dd& dd)
532 : _union(dd.file_ptr())
533 , _negate(dd.is_negated())
534 , _shift(dd.shift())
535 {}
536
538 template <typename DD, typename __DD>
539 class dd_policy
540 {
543 public:
547 using dd_type = DD;
548
552 using __dd_type = __DD;
553
557 using node_type = typename dd_type::node_type;
558
562 using pointer_type = typename dd_type::pointer_type;
563
567 using uid_type = typename dd_type::uid_type;
568
572 using children_type = typename node_type::children_type;
573
577 using level_type = typename dd_type::level_type;
578
582 using signed_level_type = typename dd_type::signed_level_type;
583
587 using label_type = typename dd_type::label_type;
588
592 using signed_label_type = typename dd_type::signed_label_type;
593
597 static constexpr label_type max_label = dd_type::max_label;
598
602 using id_type = typename dd_type::id_type;
603
607 static constexpr id_type max_id = dd_type::max_id;
608
612 using terminal_type = typename dd_type::terminal_type;
613
617 using shared_node_file_type = typename __dd_type::shared_node_file_type;
618
622 using shared_arc_file_type = typename __dd_type::shared_arc_file_type;
623
626 public:
632 static inline pointer_type
633 reduction_rule(const node_type& n);
634
641 static inline children_type
642 reduction_rule_inv(const pointer_type& child);
643 };
644
646}
647
648#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:116
shared_levelized_file< arc_type > shared_arc_file_type
Type of the file object arc-based representation of a diagram.
Definition dd.h:95
shared_levelized_file< node_type > shared_node_file_type
Type of the file object node-based representation of a diagram.
Definition dd.h:55
signed_level_type signed_label_type
Type for difference between variable labels.
Definition dd.h:85
__dd()=default
Default construction to nothing.
arc arc_type
Type of nodes of this diagram.
Definition dd.h:90
__dd(const shared_arc_file_type &f, const exec_policy &ep)
Conversion for algorithms returning to-be reduced arcs.
Definition dd.h:136
node_type::signed_level_type signed_level_type
Type for difference between node levels.
Definition dd.h:75
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:101
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:156
level_type label_type
Type of variable labels.
Definition dd.h:80
__dd(const shared_node_file_type &f)
Conversion for algorithms returning already-reduced nodes.
Definition dd.h:129
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:226
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:259
bool _negate
Propagation of the dd.negate flag.
Definition dd.h:106
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:191
node_type::level_type level_type
Type of the level of nodes.
Definition dd.h:70
const file_t & get() const
Get the content of a certain type.
Definition dd.h:168
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:208
bool empty() const
Whether it currently holds no content.
Definition dd.h:179
signed_label_type _shift
Propagation of the dd.shift value.
Definition dd.h:111
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:244
Container for the files that represent a Decision Diagram.
Definition dd.h:280
static constexpr id_type max_id
The maximal possible value for this nodes level identifier.
Definition dd.h:332
levelized_file< node_type > node_file_type
File type for the file object representing the diagram.
Definition dd.h:342
level_type label_type
Type of variable labels.
Definition dd.h:312
signed_level_type signed_label_type
Type for difference between variable labels.
Definition dd.h:317
bool _negate
Whether to negate the leaves when reading nodes from the file.
Definition dd.h:373
bool is_negated() const
Read-only access to the negation flag.
Definition dd.h:436
signed_label_type _shift
Number of levels to shift by.
Definition dd.h:378
node_type::uid_type uid_type
Type of unique identifiers (pointers without metadata) of this diagram.
Definition dd.h:297
const shared_node_file_type file_ptr() const
Read-only access to the raw files and meta information.
Definition dd.h:417
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:386
shared_file_ptr< node_file_type > shared_node_file_type
File type for the shared file object representing the diagram.
Definition dd.h:347
static constexpr label_type max_label
The maximal possible value for a unique identifier's label.
Definition dd.h:322
node_type::level_type level_type
Type of the level of nodes.
Definition dd.h:302
node_type::pointer_type pointer_type
Type of pointers of this diagram.
Definition dd.h:292
void deref()
Release the claim on the underlying file, thereby decreasing its reference counter....
Definition dd.h:363
signed_label_type shift() const
Read-only access to the number of levels to shift.
Definition dd.h:445
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:355
size_t number_of_terminals(const bool value) const
Number of terminals of a certain value.
Definition dd.h:499
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:427
typename node_type::terminal_type terminal_type
Type of a terminal value.
Definition dd.h:337
node_type::signed_level_type signed_level_type
Type for difference between node levels.
Definition dd.h:307
node_type::id_type id_type
Type of this node's level identifier.
Definition dd.h:327
size_t size() const
The number of elements in the node file.
Definition dd.h:481
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:490
node node_type
Type of nodes of this diagram.
Definition dd.h:287
size_t number_of_terminals() const
Number of terminals.
Definition dd.h:508
consumer< ValueType > make_consumer(OutputIt &&iter)
Wrap an iterator into a consumer function.
Definition functional.h:71