1 #ifndef ADIAR_BUILDER_H
2 #define ADIAR_BUILDER_H
4 #include <adiar/bdd/bdd_policy.h>
5 #include <adiar/exception.h>
6 #include <adiar/zdd/zdd_policy.h>
8 #include <adiar/internal/assert.h>
9 #include <adiar/internal/data_types/node.h>
10 #include <adiar/internal/data_types/uid.h>
11 #include <adiar/internal/io/node_file.h>
12 #include <adiar/internal/io/node_writer.h>
13 #include <adiar/internal/memory.h>
43 template <
typename dd_policy>
52 template <
typename Policy>
63 internal::node::uid_type uid;
144 template <
typename Policy>
153 using node_type =
typename Policy::node_type;
163 internal::node_writer nw;
168 bool created_terminal;
178 typename Policy::label_type current_label;
183 typename Policy::id_type current_id;
242 if (low.builder_ref != builder_ref || high.builder_ref != builder_ref) {
245 if (label > Policy::max_label) {
throw invalid_argument(
"Nodes must have a valid label"); }
246 if (label > current_label) {
throw invalid_argument(
"Nodes must be added bottom-up"); }
247 if (low.uid.is_node() && low.uid.label() <= label) {
250 if (high.uid.is_node() && high.uid.label() <= label) {
251 throw invalid_argument(
"High child must point to a node with higher label");
255 if (label < current_label) {
256 current_label = label;
257 current_id = Policy::max_id;
261 const node_type n(label, current_id, low.uid, high.uid);
264 const typename node_type::uid_type res_uid = Policy::reduction_rule(n);
266 if (res_uid.is_terminal()) {
267 created_terminal =
true;
268 terminal_val = res_uid.value();
271 if (res_uid == low.uid) {
return low; }
272 if (res_uid == high.uid) {
return high; }
280 bool& low_unref = *low.unreferenced;
281 if (low_unref && !low.uid.is_terminal()) {
286 bool& high_unref = *high.unreferenced;
287 if (high_unref && !high.uid.is_terminal()) {
292 return make_ptr(res_uid);
320 return add_node(label, low_ptr, high);
348 return add_node(label, low, high_ptr);
368 add_node(
const typename Policy::label_type label,
const bool low,
const bool high)
374 return add_node(label, low_ptr, high_ptr);
391 created_terminal =
true;
392 terminal_val = terminal_value;
394 return make_ptr(
typename node_type::pointer_type(terminal_value));
413 typename Policy::dd_type
418 if (!nw.has_pushed()) {
419 if (created_terminal) {
420 nw.push(node_type(terminal_val));
422 throw domain_error(
"There must be at least one node or terminal in the decision diagram");
427 if (unref_nodes > 1) {
throw domain_error(
"Decision diagram has more than one root"); }
429 const typename Policy::dd_type res(nf);
452 attach_if_needed() noexcept
455 adiar_assert(!nw.attached(),
456 "`nw`'s attachment should be consistent with existence of `nf`");
459 nf = internal::make_shared_levelized_file<node_type>();
463 current_label = Policy::max_label;
464 current_id = Policy::max_id;
465 created_terminal =
false;
466 terminal_val =
false;
470 builder_ref = make_shared<builder_shared>();
488 make_ptr(
const typename node_type::pointer_type& p) noexcept
490 return builder_ptr<Policy>(p, builder_ref);
The pointer type that builders use to identify the nodes they have constructed in a decision diagram.
Definition: builder.h:54
builder_ptr()=default
Default construction for a pointer to null.
builder_ptr & operator=(builder_ptr &&bp)=default
Move construction.
builder_ptr & operator=(const builder_ptr &bp)=default
Copy construction.
builder_ptr(builder_ptr &&bp)=default
Move construction.
builder_ptr(const builder_ptr &bp)=default
Copy construction.
A builder for decision diagrams.
Definition: builder.h:146
builder_ptr< Policy > add_node(bool terminal_value)
Add a terminal node with a given value.
Definition: builder.h:387
builder_ptr< Policy > add_node(const typename Policy::label_type label, const builder_ptr< Policy > &low, const bool high)
Add an internal node with a given label and its two children.
Definition: builder.h:341
builder() noexcept
Constructor.
Definition: builder.h:199
void clear() noexcept
Clear builder of all its current content, discarding all nodes and invalidating any pointers to them.
Definition: builder.h:442
~builder() noexcept
Destructor.
Definition: builder.h:205
builder_ptr< Policy > add_node(typename Policy::label_type label, const builder_ptr< Policy > &low, const builder_ptr< Policy > &high)
Add an internal node with a given label and its two children.
Definition: builder.h:235
builder_ptr< Policy > add_node(const typename Policy::label_type label, const bool low, const builder_ptr< Policy > &high)
Add an internal node with a given label and its two children.
Definition: builder.h:313
Policy::dd_type build()
Builds the decision diagram with the added nodes. This also clears the builder.
Definition: builder.h:414
builder_ptr< Policy > add_node(const typename Policy::label_type label, const bool low, const bool high)
Add an internal node with a given label and its two children.
Definition: builder.h:368
Core types.
Definition: adiar.h:40
std::domain_error domain_error
Inputs for which an operation is undefined.
Definition: exception.h:38
std::invalid_argument invalid_argument
Inputs that are invalid.
Definition: exception.h:33
std::shared_ptr< T > shared_ptr
Shared ownership of an object on the heap. This smart pointer essentially provides a (thread-safe) re...
Definition: memory.h:52