From 155344da02c030b91c2b6ab43b3840e79fd4eac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffan=20S=C3=B8lvsten?= Date: Sun, 24 Sep 2023 10:13:12 -0400 Subject: [PATCH] Update 'zdd_contains' API to use Generators/Iterators --- src/adiar/zdd.h | 28 +- src/adiar/zdd/contains.cpp | 17 +- test/adiar/zdd/test_change.cpp | 1746 +++++++++++++++--------------- test/adiar/zdd/test_contains.cpp | 353 +++--- 4 files changed, 1041 insertions(+), 1103 deletions(-) diff --git a/src/adiar/zdd.h b/src/adiar/zdd.h index 12775bcf9..8a253fda9 100644 --- a/src/adiar/zdd.h +++ b/src/adiar/zdd.h @@ -558,7 +558,6 @@ namespace adiar __zdd zdd_project(zdd &&A, const std::function &dom); /// \endcond - ////////////////////////////////////////////////////////////////////////////// /// \brief Project family of sets onto a domain, i.e. remove from every /// set all variables not within the domain. @@ -575,7 +574,7 @@ namespace adiar template __zdd zdd_project(const zdd &A, IT begin, IT end) { - return zdd_project(A, internal::iterator_gen(begin, end)); + return zdd_project(A, internal::iterator_gen(begin, end)); } /// \cond @@ -583,7 +582,7 @@ namespace adiar __zdd zdd_project(zdd &&A, IT begin, IT end) { return zdd_project(std::forward(A), - internal::iterator_gen(begin, end)); + internal::iterator_gen(begin, end)); } /// \endcond @@ -772,9 +771,30 @@ namespace adiar ////////////////////////////////////////////////////////////////////////////// /// \brief Whether the family includes the given set of labels /// + /// \param A Set of interest + /// + /// \param a Generator of a bit-vector in *ascending* order. + /// /// \returns Whether \f$ a \in A \f$ ////////////////////////////////////////////////////////////////////////////// - bool zdd_contains(const zdd &A, const shared_file &a); + bool zdd_contains(const zdd &A, const std::function &a); + + ////////////////////////////////////////////////////////////////////////////// + /// \brief Whether the family includes the given set of labels + /// + /// \param A Set of interest + /// + /// \param begin Iterator that provides the variables in *ascending* order. + /// + /// \param end Iterator that marks the end for `begin`. + /// + /// \returns Whether \f$ \{\mathit{begin}, \dots, \mathit{end}\} \in A \f$ + ////////////////////////////////////////////////////////////////////////////// + template + bool zdd_contains(const zdd &A, IT begin, IT end) + { + return zdd_contains(A, internal::iterator_gen(begin, end)); + } ////////////////////////////////////////////////////////////////////////////// /// \brief Retrieves the lexicographically smallest set a in A. diff --git a/src/adiar/zdd/contains.cpp b/src/adiar/zdd/contains.cpp index 90626785c..42e5b6aed 100644 --- a/src/adiar/zdd/contains.cpp +++ b/src/adiar/zdd/contains.cpp @@ -8,7 +8,7 @@ namespace adiar { class zdd_contains_visitor { - internal::file_stream ls; + const std::function &gen; bool has_l = false; zdd::label_t l; @@ -22,10 +22,11 @@ namespace adiar bool terminal_val = false; public: - zdd_contains_visitor(const shared_file &labels) : ls(labels) + zdd_contains_visitor(const std::function &a) + : gen(a) { - has_l = ls.can_pull(); - l = has_l ? ls.pull() : 0; + l = gen(); + has_l = l <= zdd::MAX_LABEL; } inline zdd::ptr_t visit(const zdd::node_t &n) @@ -39,7 +40,7 @@ namespace adiar if (is_first_visit && l < visited_label) { return zdd::ptr_t::NIL(); } // Will we miss a label? - if (l == visited_label && ls.can_pull()) { l = ls.pull(); } + if (l == visited_label && l <= zdd::MAX_LABEL) { l = gen(); } if (next_ptr.is_node() && visited_label < l && l < next_ptr.label()) { return zdd::ptr_t::NIL(); } @@ -53,12 +54,12 @@ namespace adiar { terminal_val = s; } inline bool get_result() - { return terminal_val && (!has_l || l <= visited_label) && !ls.can_pull(); } + { return terminal_val && zdd::MAX_LABEL < l; } }; - bool zdd_contains(const zdd &zdd, const shared_file &labels) + bool zdd_contains(const zdd &zdd, const std::function &a) { - zdd_contains_visitor v(labels); + zdd_contains_visitor v(a); internal::traverse(zdd, v); return v.get_result(); } diff --git a/test/adiar/zdd/test_change.cpp b/test/adiar/zdd/test_change.cpp index 6378ce98a..38cffbd7a 100644 --- a/test/adiar/zdd/test_change.cpp +++ b/test/adiar/zdd/test_change.cpp @@ -63,1336 +63,1342 @@ go_bandit([]() { nw << n1_5 << n1_4 << n1_3 << n1_2 << n1_1; } - it("returns same file for Ø on empty labels", [&]() { - const std::vector vars = { }; - - __zdd out = zdd_change(zdd_F, vars.begin(), vars.end()); - AssertThat(out.get>(), Is().EqualTo(zdd_F)); + describe("zdd_change(A, vars)", [&]() { + // TODO }); - it("returns same file for { Ø } on empty labels", [&]() { - const std::vector vars = { }; + describe("zdd_change(A, begin, end)", [&]() { + it("returns same file for Ø on empty labels", [&]() { + const std::vector vars = { }; - __zdd out = zdd_change(zdd_T, vars.begin(), vars.end()); - AssertThat(out.get>(), Is().EqualTo(zdd_T)); - }); + __zdd out = zdd_change(zdd_F, vars.begin(), vars.end()); + AssertThat(out.get>(), Is().EqualTo(zdd_F)); + }); - it("returns same file for { {1} } on empty labels", [&]() { - const std::vector vars = { }; + it("returns same file for { Ø } on empty labels", [&]() { + const std::vector vars = { }; - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(out.get>(), Is().EqualTo(zdd_x1)); - }); + __zdd out = zdd_change(zdd_T, vars.begin(), vars.end()); + AssertThat(out.get>(), Is().EqualTo(zdd_T)); + }); - it("returns same file for Ø on (1,2)", [&]() { - const std::vector vars = { 1, 2 }; + it("returns same file for { {1} } on empty labels", [&]() { + const std::vector vars = { }; - __zdd out = zdd_change(zdd_F, vars.begin(), vars.end()); - AssertThat(out.get>(), Is().EqualTo(zdd_F)); - }); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get>(), Is().EqualTo(zdd_x1)); + }); - it("returns { {1,2} } for { Ø } on (1,2)", [&]() { - const std::vector vars = { 1, 2 }; + it("returns same file for Ø on (1,2)", [&]() { + const std::vector vars = { 1, 2 }; - __zdd out = zdd_change(zdd_T, vars.begin(), vars.end()); + __zdd out = zdd_change(zdd_F, vars.begin(), vars.end()); + AssertThat(out.get>(), Is().EqualTo(zdd_F)); + }); - node_test_stream ns(out); + it("returns { {1,2} } for { Ø } on (1,2)", [&]() { + const std::vector vars = { 1, 2 }; - AssertThat(ns.can_pull(), Is().True()); - AssertThat(ns.pull(), Is().EqualTo(node(2, node::MAX_ID, terminal_F, terminal_T))); + __zdd out = zdd_change(zdd_T, vars.begin(), vars.end()); - AssertThat(ns.can_pull(), Is().True()); - AssertThat(ns.pull(), Is().EqualTo(node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)))); + node_test_stream ns(out); - AssertThat(ns.can_pull(), Is().False()); + AssertThat(ns.can_pull(), Is().True()); + AssertThat(ns.pull(), Is().EqualTo(node(2, node::MAX_ID, terminal_F, terminal_T))); - level_info_test_stream levels(out); + AssertThat(ns.can_pull(), Is().True()); + AssertThat(ns.pull(), Is().EqualTo(node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)))); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(ns.can_pull(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(2u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(3u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds new root for { {1} } on (0)", [&]() { - const std::vector vars = { 0 }; + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(2u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(3u)); - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - arc_test_stream arcs(out); + it("adds new root for { {1} } on (0)", [&]() { + const std::vector vars = { 0 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds new root chain for { {2} } on (0,1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_T, terminal_T); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 0, 1 }; + it("adds new root chain for { {2} } on (0,1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_T, terminal_T); + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_T })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds new nodes after root for { {1} } on (2,3)", [&]() { - const std::vector vars = { 2, 3 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - arc_test_stream arcs(out); + it("adds new nodes after root for { {1} } on (2,3)", [&]() { + const std::vector vars = { 2, 3 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(3,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds a new node before and after root for { {1} } on (0,2)", [&]() { - const std::vector vars = { 0, 2 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - arc_test_stream arcs(out); + it("adds a new node before and after root for { {1} } on (0,2)", [&]() { + const std::vector vars = { 0, 2 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds new nodes before and after root for { {1} } on (0,2,4)", [&]() { - const std::vector vars = { 0, 2, 4 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - arc_test_stream arcs(out); + it("adds new nodes before and after root for { {1} } on (0,2,4)", [&]() { + const std::vector vars = { 0, 2, 4 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(4,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(4,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(4,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(4,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(4,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(4,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(4,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(4,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(4u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("adds node between root and child for { {1}, {3} } on (2)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(3, node::MAX_ID, terminal_F, terminal_T) - << node(1, node::MAX_ID, ptr_uint64(3, ptr_uint64::MAX_ID), terminal_T) - ; - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(4u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 2 }; + it("adds node between root and child for { {1}, {3} } on (2)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(3, node::MAX_ID, terminal_F, terminal_T) + << node(1, node::MAX_ID, ptr_uint64(3, ptr_uint64::MAX_ID), terminal_T) + ; + } - arc_test_stream arcs(out); + const std::vector vars = { 2 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), true, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("returns { Ø } for { {0} } on (0)", [&]() { - const std::vector vars = { 0 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); - __zdd out = zdd_change(zdd_x0, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(3u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - node_test_stream ns(out); + it("returns { Ø } for { {0} } on (0)", [&]() { + const std::vector vars = { 0 }; - AssertThat(ns.can_pull(), Is().True()); - AssertThat(ns.pull(), Is().EqualTo(node(true))); + __zdd out = zdd_change(zdd_x0, vars.begin(), vars.end()); - AssertThat(ns.can_pull(), Is().False()); + node_test_stream ns(out); - level_info_test_stream levels(out); + AssertThat(ns.can_pull(), Is().True()); + AssertThat(ns.pull(), Is().EqualTo(node(true))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(ns.can_pull(), Is().False()); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); + level_info_test_stream levels(out); - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("returns { Ø } for { {1} } on (1)", [&]() { - const std::vector vars = { 1 }; + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); - __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - node_test_stream ns(out); + it("returns { Ø } for { {1} } on (1)", [&]() { + const std::vector vars = { 1 }; - AssertThat(ns.can_pull(), Is().True()); - AssertThat(ns.pull(), Is().EqualTo(node(true))); + __zdd out = zdd_change(zdd_x1, vars.begin(), vars.end()); - AssertThat(ns.can_pull(), Is().False()); + node_test_stream ns(out); - level_info_test_stream levels(out); + AssertThat(ns.can_pull(), Is().True()); + AssertThat(ns.pull(), Is().EqualTo(node(true))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(ns.can_pull(), Is().False()); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); + level_info_test_stream levels(out); - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("shortcuts root for { {0,1} } on (0)", [&]() { - shared_levelized_file in; + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(1, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); - } + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 0 }; + it("shortcuts root for { {0,1} } on (0)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(1, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); + } - arc_test_stream arcs(out); + const std::vector vars = { 0 }; - AssertThat(arcs.can_pull_internal(), Is().False()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().False()); + level_info_test_stream levels(out); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("shortcuts root for { {0,2} } on (0,1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 0, 1 }; + it("shortcuts root for { {0,2} } on (0,1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)); + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("shortcuts root and its child for { {0,2}, {0,2,3} } on (0,2)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(3, node::MAX_ID, terminal_T, terminal_T) - << node(2, node::MAX_ID, terminal_F, ptr_uint64(3, ptr_uint64::MAX_ID)) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - std::vector vars = { 0, 2 }; + it("shortcuts root and its child for { {0,2}, {0,2,3} } on (0,2)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(3, node::MAX_ID, terminal_T, terminal_T) + << node(2, node::MAX_ID, terminal_F, ptr_uint64(3, ptr_uint64::MAX_ID)) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)); + } - arc_test_stream arcs(out); + std::vector vars = { 0, 2 }; - AssertThat(arcs.can_pull_internal(), Is().False()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_T })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_T })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().False()); + level_info_test_stream levels(out); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips root for { Ø, {0} } on (0)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(0, node::MAX_ID, terminal_T, terminal_T); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - const std::vector vars = { 0 }; + it("flips root for { Ø, {0} } on (0)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(0, node::MAX_ID, terminal_T, terminal_T); + } - arc_test_stream arcs(out); + const std::vector vars = { 0 }; - AssertThat(arcs.can_pull_internal(), Is().False()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_T })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_T })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().False()); + level_info_test_stream levels(out); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips root for { {0}, {1} } on (0)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(1, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - const std::vector vars = { 0 }; + it("flips root for { {0}, {1} } on (0)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(1, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T); + } - arc_test_stream arcs(out); + const std::vector vars = { 0 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips root for [1] on (0)", [&]() { - const std::vector vars = { 0 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - arc_test_stream arcs(out); + it("flips root for [1] on (0)", [&]() { + const std::vector vars = { 0 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(4u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips node in the middle for { Ø, {0}, {1,2} } on (1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_F, terminal_T) - << node(1, node::MAX_ID, terminal_T, ptr_uint64(2, ptr_uint64::MAX_ID)) - << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(4u)); + }); - const std::vector vars = { 1 }; + it("flips node in the middle for { Ø, {0}, {1,2} } on (1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_F, terminal_T) + << node(1, node::MAX_ID, terminal_T, ptr_uint64(2, ptr_uint64::MAX_ID)) + << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T); + } - arc_test_stream arcs(out); + const std::vector vars = { 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,1) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,1) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,2u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,2u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(3u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips and adds a node for [1] on (1)", [&]() { - const std::vector vars = { 1 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); - __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(3u)); + }); - arc_test_stream arcs(out); + it("flips and adds a node for [1] on (1)", [&]() { + const std::vector vars = { 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,1) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,1) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,1), true, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,1), true, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,1), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), false, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,1), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,2u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,2u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(4u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("collapses to a terminal for { {0,1} } on (0,1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(1, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(4u)); + }); - const std::vector vars = { 0, 1 }; + it("collapses to a terminal for { {0,1} } on (0,1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(1, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); + } - node_test_stream ns(out); + const std::vector vars = { 0, 1 }; - AssertThat(ns.can_pull(), Is().True()); - AssertThat(ns.pull(), Is().EqualTo(node(true))); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(ns.can_pull(), Is().False()); + node_test_stream ns(out); - level_info_test_stream levels(out); + AssertThat(ns.can_pull(), Is().True()); + AssertThat(ns.pull(), Is().EqualTo(node(true))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(ns.can_pull(), Is().False()); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); + level_info_test_stream levels(out); - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("bridges over a deleted node for { {0,1,2} } on (1)", [&]() { - shared_levelized_file in; + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_FALSE], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut_type::INTERNAL_TRUE], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut_type::ALL], Is().EqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_F, terminal_T) - << node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)) - ; - } + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 1 }; + it("bridges over a deleted node for { {0,1,2} } on (1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_F, terminal_T) + << node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)) + ; + } - arc_test_stream arcs(out); + const std::vector vars = { 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("bridges over a deleted node for { {1,2}, {0,1,2} } on (1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_F, terminal_T) - << node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)) - << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), ptr_uint64(1, ptr_uint64::MAX_ID)) - ; - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 1 }; + it("bridges over a deleted node for { {1,2}, {0,1,2} } on (1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_F, terminal_T) + << node(1, node::MAX_ID, terminal_F, ptr_uint64(2, ptr_uint64::MAX_ID)) + << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), ptr_uint64(1, ptr_uint64::MAX_ID)) + ; + } - arc_test_stream arcs(out); + const std::vector vars = { 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(2,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("only adds a one node when cutting arcs to the same node for { {2}, {0,2} } on (1)", [&]() { - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(2, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, ptr_uint64(2, ptr_uint64::MAX_ID), ptr_uint64(2, ptr_uint64::MAX_ID)) - ; - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 1 }; + it("only adds a one node when cutting arcs to the same node for { {2}, {0,2} } on (1)", [&]() { + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(2, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, ptr_uint64(2, ptr_uint64::MAX_ID), ptr_uint64(2, ptr_uint64::MAX_ID)) + ; + } - arc_test_stream arcs(out); + const std::vector vars = { 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("bridges node before the last label and a terminal for { {0}, {1} } on (0,1)", [&]() { - /* - // 1 ---- x0 - // / \ - // 2 T ---- x1 - // / \ - // F T - // - // When resoving for (2) the label is at x1, but as it is pruned then the - // source is still at x0 from (1). Hence, if one looks at source.label() - // rather than the current level then this edge is by mistake placed into - // the "cut edge with a new node" queue. - */ - shared_levelized_file in; + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(2u)); - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(1, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T) - ; - } + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - const std::vector vars = { 0, 1 }; + it("bridges node before the last label and a terminal for { {0}, {1} } on (0,1)", [&]() { + /* + // 1 ---- x0 + // / \ + // 2 T ---- x1 + // / \ + // F T + // + // When resoving for (2) the label is at x1, but as it is pruned then the + // source is still at x0 from (1). Hence, if one looks at source.label() + // rather than the current level then this edge is by mistake placed into + // the "cut edge with a new node" queue. + */ + shared_levelized_file in; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { // Garbage collect writer to free write-lock + node_writer w(in); + w << node(1, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, ptr_uint64(1, ptr_uint64::MAX_ID), terminal_T) + ; + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("flips, adds and bridges nodes for [1] on (2,3)", [&]() { - /* - // 1 ---- x0 - // / \ - // 2 \ ---- x1 - // / \ / - // 3 4 ---- x2 - // / \ || - // | F || (The F is the shortcutting on 5) - // \_ _// - // * ---- x3 (From the T terminal) - // / \ - // F T - */ + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - const std::vector vars = { 2, 3 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); + it("flips, adds and bridges nodes for [1] on (2,3)", [&]() { + /* + // 1 ---- x0 + // / \ + // 2 \ ---- x1 + // / \ / + // 3 4 ---- x2 + // / \ || + // | F || (The F is the shortcutting on 5) + // \_ _// + // * ---- x3 (From the T terminal) + // / \ + // F T + */ - arc_test_stream arcs(out); + const std::vector vars = { 2, 3 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); + __zdd out = zdd_change(zdd_1, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), false, ptr_uint64(1,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), false, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,1), false, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(1,0), true, ptr_uint64(2,1) })); - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,1), true, ptr_uint64(3,0) })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,0), false, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,1), false, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(2,1), true, ptr_uint64(3,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(3,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,2u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(3,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("correctly connects pre-root chain with skipped root for { { 1 }, { 1,2 } } on (0,1)", [&]() { - shared_levelized_file in; - /* - // 1 ---- x1 - // / \ - // F 2 ---- x2 - // / \ - // T T - */ + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(3u)); - const node n2 = node(2, node::MAX_ID, terminal_T, terminal_T); - const node n1 = node(1, node::MAX_ID, terminal_F, n2.uid()); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - { - node_writer nw(in); - nw << n2 << n1; - } + it("correctly connects pre-root chain with skipped root for { { 1 }, { 1,2 } } on (0,1)", [&]() { + shared_levelized_file in; + /* + // 1 ---- x1 + // / \ + // F 2 ---- x2 + // / \ + // T T + */ - const std::vector vars = { 0, 1 }; + const node n2 = node(2, node::MAX_ID, terminal_T, terminal_T); + const node n1 = node(1, node::MAX_ID, terminal_F, n2.uid()); - __zdd out = zdd_change(in, vars.begin(), vars.end()); + { + node_writer nw(in); + nw << n2 << n1; + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1 }; - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_internal(), Is().False()); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { ptr_uint64(0,0), true, ptr_uint64(2,0) })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_T })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("cuts collapse of root to a terminal for { { 0 } } on (0,1)", [&]() { - shared_levelized_file in; - /* - // 1 ---- x0 - // / \ - // F T - */ - { // Garbage collect writer to free write-lock - node_writer nw(in); - nw << node(0, node::MAX_ID, terminal_F, terminal_T); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - const std::vector vars = { 0, 1 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(2u)); + }); - __zdd out = zdd_change(in, vars.begin(), vars.end()); + it("cuts collapse of root to a terminal for { { 0 } } on (0,1)", [&]() { + shared_levelized_file in; + /* + // 1 ---- x0 + // / \ + // F T + */ + { // Garbage collect writer to free write-lock + node_writer nw(in); + nw << node(0, node::MAX_ID, terminal_F, terminal_T); + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1 }; - AssertThat(arcs.can_pull_internal(), Is().False()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(1,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().False()); + level_info_test_stream levels(out); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(1,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); - it("cuts collapse to a terminal for { { 0,1 } } on (0,1,2)", [&]() { - shared_levelized_file in; - /* - // 1 ---- x0 - // / \ - // F 2 ---- x1 - // / \ - // F T - */ - { // Garbage collect writer to free write-lock - node_writer nw(in); - nw << node(1, node::MAX_ID, terminal_F, terminal_T) - << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); - } + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - const std::vector vars = { 0, 1, 2 }; + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - __zdd out = zdd_change(in, vars.begin(), vars.end()); + it("cuts collapse to a terminal for { { 0,1 } } on (0,1,2)", [&]() { + shared_levelized_file in; + /* + // 1 ---- x0 + // / \ + // F 2 ---- x1 + // / \ + // F T + */ + { // Garbage collect writer to free write-lock + node_writer nw(in); + nw << node(1, node::MAX_ID, terminal_F, terminal_T) + << node(0, node::MAX_ID, terminal_F, ptr_uint64(1, ptr_uint64::MAX_ID)); + } - arc_test_stream arcs(out); + const std::vector vars = { 0, 1, 2 }; - AssertThat(arcs.can_pull_internal(), Is().False()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), false, terminal_F })); - level_info_test_stream levels(out); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(2,0), true, terminal_T })); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); + AssertThat(arcs.can_pull_terminal(), Is().False()); - AssertThat(levels.can_pull(), Is().False()); + level_info_test_stream levels(out); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(2,1u))); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); - }); + AssertThat(levels.can_pull(), Is().False()); + + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); - it("keeps pre-root chain despite collapse to a terminal of the root for { { 1 } } on (0,1)", [&]() { - shared_levelized_file in; - /* - // 1 ---- x1 - // / \ - // F T - */ - { // Garbage collect writer to free write-lock - node_writer nw(in); - nw << node(1, node::MAX_ID, terminal_F, terminal_T); - } + it("keeps pre-root chain despite collapse to a terminal of the root for { { 1 } } on (0,1)", [&]() { + shared_levelized_file in; + /* + // 1 ---- x1 + // / \ + // F T + */ + { // Garbage collect writer to free write-lock + node_writer nw(in); + nw << node(1, node::MAX_ID, terminal_F, terminal_T); + } - const std::vector vars = { 0, 1 }; + const std::vector vars = { 0, 1 }; - __zdd out = zdd_change(in, vars.begin(), vars.end()); + __zdd out = zdd_change(in, vars.begin(), vars.end()); - arc_test_stream arcs(out); + arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); + AssertThat(arcs.can_pull_internal(), Is().False()); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), false, terminal_F })); - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { ptr_uint64(0,0), true, terminal_T })); - AssertThat(arcs.can_pull_terminal(), Is().False()); + AssertThat(arcs.can_pull_terminal(), Is().False()); - level_info_test_stream levels(out); + level_info_test_stream levels(out); - AssertThat(levels.can_pull(), Is().True()); - AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); + AssertThat(levels.can_pull(), Is().True()); + AssertThat(levels.pull(), Is().EqualTo(level_info(0,1u))); - AssertThat(levels.can_pull(), Is().False()); + AssertThat(levels.can_pull(), Is().False()); - AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arcs_t>()->number_of_terminals[true], Is().EqualTo(1u)); + }); }); }); }); diff --git a/test/adiar/zdd/test_contains.cpp b/test/adiar/zdd/test_contains.cpp index b9c48e7de..0a7a224a5 100644 --- a/test/adiar/zdd/test_contains.cpp +++ b/test/adiar/zdd/test_contains.cpp @@ -13,39 +13,16 @@ go_bandit([]() { nw_T << node(true); } - it("returns false for Ø on Ø", [&]() { - adiar::shared_file labels; - - AssertThat(zdd_contains(zdd_F, labels), Is().False()); - }); - - it("returns true for { Ø } on Ø", [&]() { - adiar::shared_file labels; - - AssertThat(zdd_contains(zdd_T, labels), Is().True()); - }); - - it("returns false for { Ø } on { 1, 42 }", [&]() { - adiar::shared_file labels; - - { - label_writer lw(labels); - lw << 1 << 42; - } - - AssertThat(zdd_contains(zdd_T, labels), Is().False()); - }); - const ptr_uint64 terminal_F = ptr_uint64(false); const ptr_uint64 terminal_T = ptr_uint64(true); shared_levelized_file zdd_x0; // { { 0 } } /* - 1 ---- x0 - / \ - F T - */ + // 1 ---- x0 + // / \ + // F T + */ { // Garbage collect writers to free write-lock node_writer nw(zdd_x0); nw << node(0, node::MAX_ID, terminal_F, terminal_T); @@ -56,10 +33,10 @@ go_bandit([]() { shared_levelized_file zdd_x1_null; // { Ø, { 1 } } /* - 1 ---- x1 - / \ - T T - */ + // 1 ---- x1 + // / \ + // T T + */ { // Garbage collect writers to free write-lock node_writer nw(zdd_x1_null); nw << node(1, node::MAX_ID, terminal_T, terminal_T); @@ -70,16 +47,16 @@ go_bandit([]() { shared_levelized_file zdd_1; // { Ø, { 0,2 }, { 0,3 } { 1,2 }, { 1,3 }, { 1,2,3 }, { 0,2,3 } } /* - 1 ---- x0 - / \ - 2 \ ---- x1 - / \ / - T 3 ---- x2 - / \ - 4 5 ---- x3 - / \/ \ - F T T - */ + // 1 ---- x0 + // / \ + // 2 \ ---- x1 + // / \ / + // T 3 ---- x2 + // / \ + // 4 5 ---- x3 + // / \/ \ + // F T T + */ const node n1_5 = node(3, node::MAX_ID, terminal_T, terminal_T); const node n1_4 = node(3, node::MAX_ID-1, terminal_F, terminal_T); const node n1_3 = node(2, node::MAX_ID, n1_4.uid(), n1_5.uid()); @@ -91,235 +68,169 @@ go_bandit([]() { nw << n1_5 << n1_4 << n1_3 << n1_2 << n1_1; } - it("returns visited root for [1] on Ø", [&]() { - adiar::shared_file labels; - - AssertThat(zdd_contains(zdd_1, labels), Is().True()); - }); - - it("returns visited terminal for [1] on { 0 }", [&]() { - adiar::shared_file labels; - - { - label_writer w(labels); - w << 0; - } - - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); - - it("returns visited terminal for [1] on { 1 }", [&]() { - adiar::shared_file labels; - - { - label_writer w(labels); - w << 1; - } - - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); - - it("returns visited terminal for [1] on { 0, 2 }", [&]() { - adiar::shared_file labels; - - { - label_writer w(labels); - w << 0 << 2; - } - - AssertThat(zdd_contains(zdd_1, labels), Is().True()); - }); - - it("returns visited terminal for [1] on { 1, 3 }", [&]() { - adiar::shared_file labels; + shared_levelized_file zdd_2; + // { { 6 }, { 2,4 }, { 2,6 }, { 2,4,6 } } + /* + // 1 ---- x2 + // / \ + // | 2 ---- x4 + // |/ \ + // 3 4 ---- x6 + // / \/ \ + // F T T + */ + const node n2_4 = node(6, node::MAX_ID, terminal_T, terminal_T); + const node n2_3 = node(6, node::MAX_ID-1, terminal_F, terminal_T); + const node n2_2 = node(4, node::MAX_ID, n2_3.uid(), n2_4.uid()); + const node n2_1 = node(2, node::MAX_ID, n2_3.uid(), n2_2.uid()); - { - label_writer w(labels); - w << 1 << 3; - } + { // Garbage collect writers to free write-lock + node_writer nw(zdd_2); + nw << n2_4 << n2_3 << n2_2 << n2_1; + } - AssertThat(zdd_contains(zdd_1, labels), Is().True()); + describe("zdd_contains(A, a_gen)", [&]() { + // TODO }); - it("returns visited terminal for [1] on { 0, 2, 3 }", [&]() { - adiar::shared_file labels; + describe("zdd_contains(A, begin, end)", [&]() { + it("returns false for Ø on Ø", [&]() { + const std::vector a = { }; - { - label_writer w(labels); - w << 0 << 2 << 3; - } + AssertThat(zdd_contains(zdd_F, a.begin(), a.end()), Is().False()); + }); - AssertThat(zdd_contains(zdd_1, labels), Is().True()); - }); + it("returns true for { Ø } on Ø", [&]() { + const std::vector a = { }; - it("fails on missed label for [1] on { 0, 1, 2 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_T, a.begin(), a.end()), Is().True()); + }); - { - label_writer w(labels); - w << 0 << 1 << 2; - } + it("returns false for { Ø } on { 1, 42 }", [&]() { + const std::vector a = { 1, 42 }; - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); + AssertThat(zdd_contains(zdd_T, a.begin(), a.end()), Is().False()); + }); - it("fails on terminal with unread labels for [1] on { 2 }", [&]() { - adiar::shared_file labels; + it("returns visited root for [1] on Ø", [&]() { + const std::vector a = { }; - { - label_writer w(labels); - w << 2; - } + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().True()); + }); - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); + it("returns visited terminal for [1] on { 0 }", [&]() { + const std::vector a = { 0 }; - it("fails on terminal with unread labels for [1] on { 0, 2, 4 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - { - label_writer w(labels); - w << 0 << 2 << 4; - } + it("returns visited terminal for [1] on { 1 }", [&]() { + const std::vector a = { 1 }; - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - it("fails on terminal with unread labels for [1] on { 0, 2, 3, 4 }", [&]() { - adiar::shared_file labels; + it("returns visited terminal for [1] on { 0, 2 }", [&]() { + const std::vector a = { 0, 2 }; - { - label_writer w(labels); - w << 0 << 2 << 3 << 4; - } + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().True()); + }); - AssertThat(zdd_contains(zdd_1, labels), Is().False()); - }); + it("returns visited terminal for [1] on { 1, 3 }", [&]() { + const std::vector a = { 1, 3 }; - shared_levelized_file zdd_2; - // { { 6 }, { 2,4 }, { 2,6 }, { 2,4,6 } } - /* - 1 ---- x2 - / \ - | 2 ---- x4 - |/ \ - 3 4 ---- x6 - / \/ \ - F T T - */ - const node n2_4 = node(6, node::MAX_ID, terminal_T, terminal_T); - const node n2_3 = node(6, node::MAX_ID-1, terminal_F, terminal_T); - const node n2_2 = node(4, node::MAX_ID, n2_3.uid(), n2_4.uid()); - const node n2_1 = node(2, node::MAX_ID, n2_3.uid(), n2_2.uid()); + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().True()); + }); - { // Garbage collect writers to free write-lock - node_writer nw(zdd_2); - nw << n2_4 << n2_3 << n2_2 << n2_1; - } + it("returns visited terminal for [1] on { 0, 2, 3 }", [&]() { + const std::vector a = { 0, 2, 3 }; - it("returns visited root for [2] on Ø", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().True()); + }); - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + it("fails on missed label for [1] on { 0, 1, 2 }", [&]() { + const std::vector a = { 0, 1, 2 }; - it("returns visited terminal for [2] on { 2 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - { - label_writer w(labels); - w << 2; - } + it("fails on terminal with unread labels for [1] on { 2 }", [&]() { + const std::vector a = { 2 }; - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - it("returns visited terminal for [2] on { 6 }", [&]() { - adiar::shared_file labels; + it("fails on terminal with unread labels for [1] on { 0, 2, 4 }", [&]() { + const std::vector a = { 0, 2, 4 }; - { - label_writer w(labels); - w << 6; - } + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - AssertThat(zdd_contains(zdd_2, labels), Is().True()); - }); + it("fails on terminal with unread labels for [1] on { 0, 2, 3, 4 }", [&]() { + const std::vector a = { 0, 2, 3, 4 }; - it("returns visited terminal for [2] on { 2, 4 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_1, a.begin(), a.end()), Is().False()); + }); - { - label_writer w(labels); - w << 2 << 4; - } + it("returns visited root for [2] on Ø", [&]() { + const std::vector a = { }; - AssertThat(zdd_contains(zdd_2, labels), Is().True()); - }); + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - it("returns visited terminal for [2] on { 2, 4, 6 }", [&]() { - adiar::shared_file labels; + it("returns visited terminal for [2] on { 2 }", [&]() { + const std::vector a = { 2 }; - { - label_writer w(labels); - w << 2 << 4 << 6; - } + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - AssertThat(zdd_contains(zdd_2, labels), Is().True()); - }); + it("returns visited terminal for [2] on { 6 }", [&]() { + const std::vector a = { 6 }; - it("fails on missed label for [2] on { 4, 6 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().True()); + }); - { - label_writer w(labels); - w << 4 << 6; - } + it("returns visited terminal for [2] on { 2, 4 }", [&]() { + const std::vector a = { 2, 4 }; - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().True()); + }); - it("fails on missed label for [2] on { 2, 3, 4 }", [&]() { - adiar::shared_file labels; + it("returns visited terminal for [2] on { 2, 4, 6 }", [&]() { + const std::vector a = { 2, 4, 6 }; - { - label_writer w(labels); - w << 2 << 3 << 4; - } + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().True()); + }); - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + it("fails on missed label for [2] on { 4, 6 }", [&]() { + const std::vector a = { 4, 6 }; - it("fails on missed label for [2] on { 2, 4, 6, 8 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - { - label_writer w(labels); - w << 2 << 4 << 6 << 8; - } + it("fails on missed label for [2] on { 2, 3, 4 }", [&]() { + const std::vector a = { 2, 3, 4 }; - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - it("fails on label before root for [2] on { 0, 2, 4 }", [&]() { - adiar::shared_file labels; + it("fails on missed label for [2] on { 2, 4, 6, 8 }", [&]() { + const std::vector a = { 2, 4, 6, 8 }; - { - label_writer w(labels); - w << 0 << 2 << 4; - } + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - AssertThat(zdd_contains(zdd_2, labels), Is().False()); - }); + it("fails on label before root for [2] on { 0, 2, 4 }", [&]() { + const std::vector a = { 0, 2, 4 }; - it("fails on labels before root for [2] on { 0, 1, 2, 4 }", [&]() { - adiar::shared_file labels; + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); - { - label_writer w(labels); - w << 0 << 1 << 2 << 4; - } + it("fails on labels before root for [2] on { 0, 1, 2, 4 }", [&]() { + const std::vector a = { 0, 1, 2, 4 }; - AssertThat(zdd_contains(zdd_2, labels), Is().False()); + AssertThat(zdd_contains(zdd_2, a.begin(), a.end()), Is().False()); + }); }); }); });