diff --git a/src/adiar/zdd.h b/src/adiar/zdd.h index a07793b8e..4c657f5ae 100644 --- a/src/adiar/zdd.h +++ b/src/adiar/zdd.h @@ -659,6 +659,20 @@ namespace adiar ForwardIt end) { return zdd_offset(ep, A, make_generator(begin, end)); } + ////////////////////////////////////////////////////////////////////////////// + /// \brief Subset that do \em not include the given element. + /// + /// \param A Family of set + /// + /// \param var Variable to include. + ////////////////////////////////////////////////////////////////////////////// + __zdd zdd_offset(const zdd &A, zdd::label_type var); + + ////////////////////////////////////////////////////////////////////////////// + /// \brief Subset that do \em not include the given element. + ////////////////////////////////////////////////////////////////////////////// + __zdd zdd_offset(const exec_policy &ep, const zdd &A, zdd::label_type var); + ////////////////////////////////////////////////////////////////////////////// /// \brief Subset that \em do include the given set of variables. /// @@ -707,6 +721,20 @@ namespace adiar ForwardIt end) { return zdd_onset(ep, A, make_generator(begin, end)); } + ////////////////////////////////////////////////////////////////////////////// + /// \brief Subset that \em do include the given element. + /// + /// \param A Family of set + /// + /// \param var Variable to include. + ////////////////////////////////////////////////////////////////////////////// + __zdd zdd_onset(const zdd &A, zdd::label_type var); + + ////////////////////////////////////////////////////////////////////////////// + /// \brief Subset that \em do include the given element. + ////////////////////////////////////////////////////////////////////////////// + __zdd zdd_onset(const exec_policy &ep, const zdd &A, zdd::label_type var); + ////////////////////////////////////////////////////////////////////////////// /// \brief Project family of sets onto a domain, i.e. remove from every /// set all variables not within the domain. diff --git a/src/adiar/zdd/subset.cpp b/src/adiar/zdd/subset.cpp index 96479cb2a..602ec36e7 100644 --- a/src/adiar/zdd/subset.cpp +++ b/src/adiar/zdd/subset.cpp @@ -8,6 +8,20 @@ namespace adiar { + // TODO: Merge with the generator in `bdd_restrict(f, var, val)`. + inline auto make_generator(const zdd::label_type &var, bool &gen_called) + { + adiar_assert(!gen_called); + + return [&gen_called, &var]() -> zdd::label_type { + if (gen_called) { + return generator_end::value; + } + gen_called = true; + return var; + }; + } + template class zdd_subset_labels { @@ -135,6 +149,17 @@ namespace adiar return zdd_offset(exec_policy(), A, vars); } + __zdd zdd_offset(const exec_policy &ep, const zdd &A, zdd::label_type var) + { + bool gen_called = false; + return zdd_offset(ep, A, make_generator(var, gen_called)); + } + + __zdd zdd_offset(const zdd &A, zdd::label_type var) + { + return zdd_offset(exec_policy(), A, var); + } + ////////////////////////////////////////////////////////////////////////////// template class zdd_onset_policy : public zdd_policy @@ -212,4 +237,15 @@ namespace adiar { return zdd_onset(exec_policy(), A, xs); } + + __zdd zdd_onset(const exec_policy &ep, const zdd &A, zdd::label_type var) + { + bool gen_called = false; + return zdd_onset(ep, A, make_generator(var, gen_called)); + } + + __zdd zdd_onset(const zdd &A, zdd::label_type var) + { + return zdd_onset(exec_policy(), A, var); + } } diff --git a/test/adiar/zdd/test_subset.cpp b/test/adiar/zdd/test_subset.cpp index 3f584289e..9e16aeb40 100644 --- a/test/adiar/zdd/test_subset.cpp +++ b/test/adiar/zdd/test_subset.cpp @@ -18,18 +18,18 @@ go_bandit([]() { // { {3}, {0,3}, {3,4}, {0,3,4}, {1,2,4}, {1,2,3}, {1,3,4}, {0,1,2,4}, {0,1,2,3}, {0,1,3,4} } /* - 1 ---- x0 - || - 2 ---- x1 - / \ - | 3 ---- x2 - |/ \ - 4 5 ---- x3 - / \/ \ - F 6 T ---- x4 - / \ - T T - */ + // 1 ---- x0 + // || + // 2 ---- x1 + // / \ + // | 3 ---- x2 + // |/ \ + // 4 5 ---- x3 + // / \/ \ + // F 6 T ---- x4 + // / \ + // T T + */ shared_levelized_file zdd_1; node n1_6 = node(4, node::max_id, terminal_T, terminal_T); @@ -46,16 +46,16 @@ go_bandit([]() { // { Ø, {0}, {0,2}, {1,2}, {0,2,3}, {1,2,3} } /* - 1 ---- x0 - / \ - 2 | ---- x1 - / \| - T 3 ---- x2 - / \ - T 4 ---- x3 - / \ - F T - */ + // 1 ---- x0 + // / \ + // 2 | ---- x1 + // / \| + // T 3 ---- x2 + // / \ + // T 4 ---- x3 + // / \ + // F T + */ shared_levelized_file zdd_2; const node n2_4 = node(3, node::max_id, terminal_F, terminal_T); @@ -68,11 +68,103 @@ go_bandit([]() { w << n2_4 << n2_3 << n2_2 << n2_1; } - describe("zdd_offset(A, vars)", [&]() { + // { Ø, {1}, {2,3} } + /* + // 1 ---- x1 + // / \ + // 2 T ---- x2 + // / \ + // T 3 ---- x3 + // / \ + // F T + */ + shared_levelized_file zdd_3; + + const node n3_3(3, node::max_id, terminal_F, terminal_T); + const node n3_2(2, node::max_id, terminal_T, n3_3.uid()); + const node n3_1(1, node::max_id, n3_2.uid(), terminal_T); + + { + node_writer w(zdd_3); + w << n3_3 << n3_2 << n3_1; + } + + // { Ø, {1,2} } + /* + // 1 ---- x1 + // / \ + // T 2 ---- x2 + // / \ + // F T + */ + shared_levelized_file zdd_4; + + const node n4_2(2, node::max_id, terminal_F, terminal_T); + const node n4_1(1, node::max_id, terminal_T, n4_2.uid()); + + { + node_writer nw(zdd_4); + nw << n4_2 << n4_1; + } + + // { Ø, {1}, {2}, {1,2} } + /* + // 1 ---- x1 + // || + // 2 ---- x2 + // / \ + // T T + */ + shared_levelized_file zdd_5; + + const node n5_2(2, node::max_id, terminal_T, terminal_T); + const node n5_1(1, node::max_id, n5_2.uid(), n5_2.uid());; + + { + node_writer nw(zdd_5); + nw << n5_2 << n5_1; + } + + // { Ø, {1}, {1,2} } + /* + // 1 ---- x0 + // / \ + // T 2 ---- x2 + // / \ + // T T + */ + shared_levelized_file zdd_6; + + const node n6_2(2, node::max_id, terminal_T, terminal_T); + const node n6_1(0, node::max_id, terminal_T, n6_2.uid()); + + { + node_writer w(zdd_6); + w << n6_2 << n6_1; + } + + // { Ø, {0} } + /* + // 1 ---- x0 + // / \ + // T T + */ + shared_levelized_file zdd_7; + + const node n7_1(0, node::max_id, terminal_T, terminal_T); + + { + node_writer w(zdd_7); + w << n7_1; + } + + describe("zdd_offset(const zdd&, const generator<...>&)", [&]() { // TODO }); - describe("zdd_offset(A, begin, end)", [&]() { + describe("zdd_offset(const zdd&, IT, IT)", [&]() { + // TODO: unit tests for behaviour only tested with 'zdd_offset(A, var)' + it("should return input unchanged when given Ø", [&]() { std::vector labels = { 21, 42 }; @@ -94,44 +186,110 @@ go_bandit([]() { AssertThat(out.get>(), Is().EqualTo(zdd_1)); }); - it("should return input unchanged when given { { 2 }, { 1,2 } } without (0,3,4,5,6)", [&]() { + it("should return input unchanged for [4] without (0,3,4,5,6)", [&]() { std::vector labels = { 0, 3, 4, 5, 6 }; - shared_levelized_file in; + __zdd out = zdd_offset(zdd_4, labels.begin(), labels.end()); + AssertThat(out.get>(), Is().EqualTo(zdd_4)); + }); - { - node_writer nw(in); - nw << node(2, node::max_id, terminal_F, terminal_T) - << node(1, node::max_id, terminal_T, ptr_uint64(2, ptr_uint64::max_id)); - } + it("should restrict to a terminal in [1] without (0,1,3)", [&]() { + std::vector labels = { 0, 1, 3 }; + + __zdd out = zdd_offset(zdd_1, labels.begin(), labels.end()); + + node_test_stream out_nodes(out); + + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); - __zdd out = zdd_offset(in, labels.begin(), labels.end()); - AssertThat(out.get>(), Is().EqualTo(in)); + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); }); - it("should return { Ø } when given { Ø, { 1,2 } } without (0,2)", [&]() { - std::vector labels = { 0, 2 }; + it("should restrict to a terminal in [3] without (1,2)", [&]() { + std::vector labels = { 1,2 }; - shared_levelized_file in; + __zdd out = zdd_offset(zdd_3, labels.begin(), labels.end()); - node n2 = node(2, node::max_id, terminal_F, terminal_T); - node n1 = node(1, node::max_id, terminal_T, n2.uid());; + node_test_stream out_nodes(out); - { - node_writer nw(in); - nw << n2 << n1; - } + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(true))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); + + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); + + it("should restrict to a (reduced) terminal in [6] without (1,2)", [&]() { + std::vector labels = { 0,2 }; + + __zdd out = zdd_offset(zdd_6, labels.begin(), labels.end()); + + node_test_stream out_nodes(out); - __zdd out = zdd_offset(in, labels.begin(), labels.end()); + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(true))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); + + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); + }); + }); + + describe("zdd_offset(const zdd&, zdd::label_type)", [&]() { + it("should return input unchanged when given Ø", [&]() { + __zdd out = zdd_offset(zdd_F, 42); + AssertThat(out.get>(), Is().EqualTo(zdd_F)); + }); + + it("should return input unchanged when given { Ø }", [&]() { + __zdd out = zdd_offset(zdd_T, 42); + AssertThat(out.get>(), Is().EqualTo(zdd_T)); + }); + + it("should return input unchanged when given [4] without 0", [&]() { + __zdd out = zdd_offset(zdd_4, 0); + AssertThat(out.get>(), Is().EqualTo(zdd_4)); + }); + + it("should return { Ø } for [4] without 2", [&]() { + __zdd out = zdd_offset(zdd_4, 2); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().False()); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), false, terminal_T })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n4_1.uid(), false, terminal_T })); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), true, terminal_F })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n4_1.uid(), true, terminal_F })); AssertThat(arcs.can_pull_terminal(), Is().False()); @@ -148,29 +306,17 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); }); - it("should return { Ø, { 1 } } when given { Ø, { 1 }, { 2 }, { 1, 2 } } without (0,2)", [&]() { - std::vector labels = { 0, 2 }; - - shared_levelized_file in; - - node n2 = node(2, node::max_id-1, terminal_T, terminal_T); - node n1 = node(1, node::max_id, n2.uid(), n2.uid());; - - { - node_writer nw(in); - nw << n2 << n1; - } - - __zdd out = zdd_offset(in, labels.begin(), labels.end()); + it("should return { Ø, { 1 } } for [5] without 2", [&]() { + __zdd out = zdd_offset(zdd_5, 2); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().False()); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), false, terminal_T })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_1.uid(), false, terminal_T })); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), true, terminal_T })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_1.uid(), true, terminal_T })); AssertThat(arcs.can_pull_terminal(), Is().False()); @@ -187,29 +333,44 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); }); - it("should return { Ø, { 2 } } when given { Ø, { 1 }, { 2 }, { 1, 2 } } without (1,3)", [&]() { - std::vector labels = { 1, 3}; + it("should return { Ø, { 2 } } for [5] without 1", [&]() { + __zdd out = zdd_offset(zdd_5, 1); - shared_levelized_file in; + arc_test_stream arcs(out); + AssertThat(arcs.can_pull_internal(), Is().False()); - node n2 = node(2, node::max_id, terminal_T, terminal_T); - node n1 = node(1, node::max_id, n2.uid(), n2.uid());; + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_2.uid(), false, terminal_T })); - { - node_writer nw(in); - nw << n2 << n1; - } + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_2.uid(), true, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().False()); + + level_info_test_stream meta_arcs(out); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); + + AssertThat(meta_arcs.can_pull(), Is().False()); - __zdd out = zdd_offset(in, labels.begin(), labels.end()); + AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(0u)); + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); + }); + + it("should return { Ø, { 2 } } for [5] without 1", [&]() { + __zdd out = zdd_offset(zdd_5, 1); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().False()); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2.uid(), false, terminal_T })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_2.uid(), false, terminal_T })); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2.uid(), true, terminal_T })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n5_2.uid(), true, terminal_T })); AssertThat(arcs.can_pull_terminal(), Is().False()); @@ -226,10 +387,8 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); }); - it("should skip root of [1] without (0,42)", [&]() { - std::vector labels = { 0, 42 }; - - __zdd out = zdd_offset(zdd_1, labels.begin(), labels.end()); + it("should skip root of [1] without 0", [&]() { + __zdd out = zdd_offset(zdd_1, 0); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); @@ -290,10 +449,8 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(3u)); }); - it("should skip 'dead' nodes in [1] without (1)", [&]() { - std::vector labels = { 1 }; - - __zdd out = zdd_offset(zdd_1, labels.begin(), labels.end()); + it("should skip 'dead' nodes in [1] without 1", [&]() { + __zdd out = zdd_offset(zdd_1, 1); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); @@ -339,89 +496,8 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); }); - it("should restrict to a terminal in [1] without (0,1,3)", [&]() { - std::vector labels = { 0, 1, 3 }; - - __zdd out = zdd_offset(zdd_1, labels.begin(), labels.end()); - - node_test_stream out_nodes(out); - - AssertThat(out_nodes.can_pull(), Is().True()); - AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); - AssertThat(out_nodes.can_pull(), Is().False()); - - level_info_test_stream meta_arcs(out); - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); - - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); - }); - - it("should restrict to a terminal in { Ø, { 1 }, { 2, 3 } } without (1,2)", [&]() { - /* - 1 ---- x1 - / \ - 2 T ---- x2 - / \ - T 3 - / \ - F T - */ - shared_levelized_file in; - - { - node_writer w(in); - w << node(3, node::max_id, terminal_F, terminal_T) - << node(2, node::max_id, terminal_T, ptr_uint64(3, ptr_uint64::max_id)) - << node(1, node::max_id, ptr_uint64(2, ptr_uint64::max_id), terminal_T); - } - - std::vector labels = { 1,2 }; - - __zdd out = zdd_offset(in, labels.begin(), labels.end()); - - node_test_stream out_nodes(out); - - AssertThat(out_nodes.can_pull(), Is().True()); - AssertThat(out_nodes.pull(), Is().EqualTo(node(true))); - AssertThat(out_nodes.can_pull(), Is().False()); - - level_info_test_stream meta_arcs(out); - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); - - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(0u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); - }); - - it("should restrict to a terminal from root", [&]() { - /* - 1 ---- x1 - / \ - T 2 ---- x2 - / \ - T T - */ - shared_levelized_file in; - - { - node_writer w(in); - w << node(2, node::max_id, terminal_T, terminal_T) - << node(1, node::max_id, terminal_T, ptr_uint64(2, ptr_uint64::max_id)); - } - - std::vector labels = { 1 }; - - __zdd out = zdd_offset(in, labels.begin(), labels.end()); + it("should restrict to a (reduced) terminal in [6] without 1", [&]() { + __zdd out = zdd_offset(zdd_6, 0); node_test_stream out_nodes(out); @@ -441,10 +517,8 @@ go_bandit([]() { AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(1u)); }); - it("should bridge levels in [2] on (3)", [&]() { - std::vector labels = { 3 }; - - __zdd out = zdd_offset(zdd_2, labels.begin(), labels.end()); + it("should bridge levels in [2] without 3", [&]() { + __zdd out = zdd_offset(zdd_2, 3); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); @@ -491,10 +565,13 @@ go_bandit([]() { }); }); - describe("zdd_onset(A, vars)", [&]() { + describe("zdd_onset(const zdd&, const generator<...>&)", [&]() { + // TODO }); - describe("zdd_onset(A, begin, end)", [&]() { + describe("zdd_onset(const zdd&, IT, IT)", [&]() { + // TODO: unit tests for behaviour only tested with 'zdd_onset(A, var)' + it("should return input unchanged when given Ø", [&]() { std::vector labels = { 21, 42 }; @@ -516,29 +593,6 @@ go_bandit([]() { AssertThat(out.get>(), Is().EqualTo(zdd_1)); }); - it("should return Ø when given { Ø } for (0)", [&]() { - std::vector labels = { 0 }; - - __zdd out = zdd_onset(zdd_T, labels.begin(), labels.end()); - - node_test_stream out_nodes(out); - - AssertThat(out_nodes.can_pull(), Is().True()); - AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); - AssertThat(out_nodes.can_pull(), Is().False()); - - level_info_test_stream meta_arcs(out); - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); - AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); - AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); - - AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); - }); - it("should return Ø when given { Ø } for (21,42)", [&]() { std::vector labels = { 21, 42 }; @@ -585,56 +639,10 @@ go_bandit([]() { AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); }); - it("should return { { 0 } } when given { Ø, { 0 } } for (0)", [&]() { - shared_levelized_file in; - - const node n = node(0, node::max_id, terminal_T, terminal_T); - - { // Garbage collect writer to free write-lock - node_writer w(in); - w << n; - } - - std::vector labels = { 0 }; - - __zdd out = zdd_onset(in, labels.begin(), labels.end()); - - arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().False()); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n.uid(), true, terminal_T })); - - AssertThat(arcs.can_pull_terminal(), Is().False()); - - level_info_test_stream meta_arcs(out); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(0,1u))); - - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(1u)); - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); - }); - it("should return Ø when given { Ø, { 0 } } for (0,1)", [&]() { - shared_levelized_file in; - - { // Garbage collect writer to free write-lock - node_writer w(in); - w << node(0, node::max_id, terminal_T, terminal_T); - } - - std::vector labels = { 0, 1 }; - __zdd out = zdd_onset(in, labels.begin(), labels.end()); + __zdd out = zdd_onset(zdd_7, labels.begin(), labels.end()); node_test_stream out_nodes(out); @@ -752,14 +760,17 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(0u)); }); - it("should keep root of [1] but shortcut its low for (0)", [&]() { - std::vector labels = { 0 }; + it("should skip 'dead' nodes of [1] for (1,2)", [&]() { + std::vector labels = { 1, 2 }; __zdd out = zdd_onset(zdd_1, labels.begin(), labels.end()); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_1.uid(), false, n1_2.uid() })); + AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_1.uid(), true, n1_2.uid() })); @@ -767,16 +778,7 @@ go_bandit([]() { AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_2.uid(), true, n1_3.uid() })); AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_2.uid(), false, n1_4.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_3.uid(), false, n1_4.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_3.uid(), true, n1_5.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_4.uid(), true, n1_6.uid() })); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_3.uid(), true, n1_5.uid() })); AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_5.uid(), false, n1_6.uid() })); @@ -784,10 +786,10 @@ go_bandit([]() { AssertThat(arcs.can_pull_internal(), Is().False()); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_1.uid(), false, terminal_F })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_2.uid(), false, terminal_F })); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_4.uid(), false, terminal_F })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_3.uid(), false, terminal_F })); AssertThat(arcs.can_pull_terminal(), Is().True()); AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_5.uid(), true, terminal_T })); @@ -812,7 +814,7 @@ go_bandit([]() { AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,2u))); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); AssertThat(meta_arcs.can_pull(), Is().True()); AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(4,1u))); @@ -825,16 +827,240 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(3u)); }); - it("should skip 'dead' nodes of [1] for (1,2)", [&]() { + it("should skip root in [2] due to cut on high edge for (1,3)", [&]() { + std::vector labels = { 1 }; + + __zdd out = zdd_onset(zdd_2, labels.begin(), labels.end()); + + arc_test_stream arcs(out); + AssertThat(arcs.can_pull_internal(), Is().True()); + + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n2_2.uid(), true, n2_3.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n2_3.uid(), true, n2_4.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().False()); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_2.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_3.uid(), false, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_4.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_4.uid(), true, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().False()); + + level_info_test_stream meta_arcs(out); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(1,1u))); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); + + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(2u)); + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); + }); + + it("should cut high edge on restricted node, if it goes past the next label", [&]() { + /* + _1_ ---- x0 + / \ + 2 3 ---- x1 + / \ / \ + T | 4 ---- x2 + \ / \ + 5 6 ---- x3 + / \/ \ + F T T + */ + shared_levelized_file in; + + node n6 = node(3, node::max_id, terminal_T, terminal_T); + node n5 = node(3, node::max_id-1, terminal_F, terminal_T); + node n4 = node(2, node::max_id, n5.uid(), n6.uid()); + node n3 = node(1, node::max_id, n5.uid(), n4.uid()); + node n2 = node(1, node::max_id-1, terminal_T, n5.uid()); + node n1 = node(0, node::max_id, n2.uid(), n3.uid()); + + { // Garbage collect writer to free write-lock + node_writer w(in); + w << n6 << n5 << n4 << n3 << n2 << n1; + } + std::vector labels = { 1, 2 }; - __zdd out = zdd_onset(zdd_1, labels.begin(), labels.end()); + __zdd out = zdd_onset(in, labels.begin(), labels.end()); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_1.uid(), false, n1_2.uid() })); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1.uid(), true, n3.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n3.uid(), true, n4.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n4.uid(), true, n6.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().False()); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n3.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n4.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n6.uid(), false, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n6.uid(), true, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().False()); + + level_info_test_stream meta_arcs(out); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(0,1u))); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(1,1u))); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); + + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(3u)); + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); + }); + }); + + describe("zdd_onset(const zdd&, zdd::label_type)", [&]() { + it("should return input unchanged when given Ø", [&]() { + __zdd out = zdd_onset(zdd_F, 0); + AssertThat(out.get>(), Is().EqualTo(zdd_F)); + }); + + it("should return Ø when given { Ø } for 0", [&]() { + __zdd out = zdd_onset(zdd_T, 0); + + node_test_stream out_nodes(out); + + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); + + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); + }); + + it("should return Ø when given non-existent label (after)", [&]() { + __zdd out = zdd_onset(zdd_1, 5); + + node_test_stream out_nodes(out); + + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); + + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); + }); + + it("should return Ø when given non-existent label (in-between)", [&]() { + __zdd out = zdd_onset(zdd_6, 1); + + node_test_stream out_nodes(out); + + AssertThat(out_nodes.can_pull(), Is().True()); + AssertThat(out_nodes.pull(), Is().EqualTo(node(false))); + AssertThat(out_nodes.can_pull(), Is().False()); + + level_info_test_stream meta_arcs(out); + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get>()->max_1level_cut[cut::Internal], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_False], Is().EqualTo(1u)); + AssertThat(out.get>()->max_1level_cut[cut::Internal_True], Is().EqualTo(0u)); + AssertThat(out.get>()->max_1level_cut[cut::All], Is().EqualTo(1u)); + + AssertThat(out.get>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); + }); + + it("should return { { 0 } } when given [7] with 0", [&]() { + __zdd out = zdd_onset(zdd_7, 0); + + arc_test_stream arcs(out); + AssertThat(arcs.can_pull_internal(), Is().False()); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n7_1.uid(), false, terminal_F })); + + AssertThat(arcs.can_pull_terminal(), Is().True()); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n7_1.uid(), true, terminal_T })); + + AssertThat(arcs.can_pull_terminal(), Is().False()); + + level_info_test_stream meta_arcs(out); + + AssertThat(meta_arcs.can_pull(), Is().True()); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(0,1u))); + + AssertThat(meta_arcs.can_pull(), Is().False()); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(0u)); + + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(1u)); + AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); + }); + + it("should keep root but shortcut its low for [1] with 0", [&]() { + __zdd out = zdd_onset(zdd_1, 0); + + arc_test_stream arcs(out); + AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_1.uid(), true, n1_2.uid() })); @@ -842,19 +1068,28 @@ go_bandit([]() { AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_2.uid(), true, n1_3.uid() })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_2.uid(), false, n1_4.uid() })); + + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_3.uid(), false, n1_4.uid() })); + AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_3.uid(), true, n1_5.uid() })); + AssertThat(arcs.can_pull_internal(), Is().True()); + AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_4.uid(), true, n1_6.uid() })); + AssertThat(arcs.can_pull_internal(), Is().True()); AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1_5.uid(), false, n1_6.uid() })); AssertThat(arcs.can_pull_internal(), Is().False()); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_2.uid(), false, terminal_F })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_1.uid(), false, terminal_F })); AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_3.uid(), false, terminal_F })); + AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_4.uid(), false, terminal_F })); AssertThat(arcs.can_pull_terminal(), Is().True()); AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1_5.uid(), true, terminal_T })); @@ -879,7 +1114,7 @@ go_bandit([]() { AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); + AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,2u))); AssertThat(meta_arcs.can_pull(), Is().True()); AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(4,1u))); @@ -892,16 +1127,16 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(3u)); }); - it("should return Ø in { Ø, {0}, {0,2} } for (1)", [&]() { - /* - 1 ---- x0 - / \ - T | ---- x1 - | - 2 ---- x2 - / \ - T T - */ + it("should return Ø in { Ø, {0}, {0,2} } with 1", [&]() { + /* + // 1 ---- x0 + // / \ + // T | ---- x1 + // | + // 2 ---- x2 + // / \ + // T T + */ shared_levelized_file in; { // Garbage collect writer to free write-lock @@ -910,9 +1145,7 @@ go_bandit([]() { << node(0, node::max_id, terminal_T, ptr_uint64(2, ptr_uint64::max_id)); } - std::vector labels = { 1 }; - - __zdd out = zdd_onset(in, labels.begin(), labels.end()); + __zdd out = zdd_onset(in, 1); node_test_stream out_nodes(out); @@ -932,16 +1165,16 @@ go_bandit([]() { AssertThat(out.get>()->number_of_terminals[true], Is().EqualTo(0u)); }); - it("should cut edge going across onset label in { {2}, {0,1}, {0,2}, {0,1,2} } for (1)", [&]() { - /* - 1 ---- x0 - / \ - | 2 ---- x1 - \ // - 3 ---- x2 - / \ - F T - */ + it("should cut edge going across onset label in { {2}, {0,1}, {0,2}, {0,1,2} } with 1", [&]() { + /* + // 1 ---- x0 + // / \ + // | 2 ---- x1 + // \ // + // 3 ---- x2 + // / \ + // F T + */ shared_levelized_file in; const node n3 = node(2, node::max_id, terminal_F, terminal_T); @@ -953,9 +1186,7 @@ go_bandit([]() { w << n3 << n2 << n1; } - std::vector labels = { 1 }; - - __zdd out = zdd_onset(in, labels.begin(), labels.end()); + __zdd out = zdd_onset(in, 1); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); @@ -1001,15 +1232,15 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); }); - it("should cut edge and ignore 'dead' node in { {2}, {0,1}, {0,2} } for (1)", [&]() { + it("should cut edge and ignore 'dead' node in { {2}, {0,1}, {0,2} } with 1", [&]() { /* - 1 ---- x0 - / \ - | 2 ---- x1 - \ / \ - 3 T ---- x2 - / \ - F T + // 1 ---- x0 + // / \ + // | 2 ---- x1 + // \ / \ + // 3 T ---- x2 + // / \ + // F T */ shared_levelized_file in; @@ -1022,9 +1253,7 @@ go_bandit([]() { w << n3 << n2 << n1; } - std::vector labels = { 1 }; - - __zdd out = zdd_onset(in, labels.begin(), labels.end()); + __zdd out = zdd_onset(in, 1); arc_test_stream arcs(out); @@ -1118,59 +1347,8 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); }); - it("should skip root in [2] due to cut on high edge for (1,3)", [&]() { - std::vector labels = { 1 }; - - __zdd out = zdd_onset(zdd_2, labels.begin(), labels.end()); - - arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n2_2.uid(), true, n2_3.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n2_3.uid(), true, n2_4.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().False()); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_2.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_3.uid(), false, terminal_T })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_4.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n2_4.uid(), true, terminal_T })); - - AssertThat(arcs.can_pull_terminal(), Is().False()); - - level_info_test_stream meta_arcs(out); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(1,1u))); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); - - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(2u)); - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); - }); - - it("should falsify early terminal and bridge over removed node in [1] for (4)", [&]() { - std::vector labels = { 4 }; - - __zdd out = zdd_onset(zdd_1, labels.begin(), labels.end()); + it("should falsify early terminal and bridge over removed node in [1] with 4", [&]() { + __zdd out = zdd_onset(zdd_1, 4); arc_test_stream arcs(out); AssertThat(arcs.can_pull_internal(), Is().True()); @@ -1233,89 +1411,6 @@ go_bandit([]() { AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(2u)); AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(1u)); }); - - it("should cut high edge on restricted node, if it goes past the next label", [&]() { - /* - _1_ ---- x0 - / \ - 2 3 ---- x1 - / \ / \ - T | 4 ---- x2 - \ / \ - 5 6 ---- x3 - / \/ \ - F T T - */ - shared_levelized_file in; - - node n6 = node(3, node::max_id, terminal_T, terminal_T); - node n5 = node(3, node::max_id-1, terminal_F, terminal_T); - node n4 = node(2, node::max_id, n5.uid(), n6.uid()); - node n3 = node(1, node::max_id, n5.uid(), n4.uid()); - node n2 = node(1, node::max_id-1, terminal_T, n5.uid()); - node n1 = node(0, node::max_id, n2.uid(), n3.uid()); - - { // Garbage collect writer to free write-lock - node_writer w(in); - w << n6 << n5 << n4 << n3 << n2 << n1; - } - - std::vector labels = { 1, 2 }; - - __zdd out = zdd_onset(in, labels.begin(), labels.end()); - - arc_test_stream arcs(out); - AssertThat(arcs.can_pull_internal(), Is().True()); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n1.uid(), true, n3.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n3.uid(), true, n4.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().True()); - AssertThat(arcs.pull_internal(), Is().EqualTo(arc { n4.uid(), true, n6.uid() })); - - AssertThat(arcs.can_pull_internal(), Is().False()); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n1.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n3.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n4.uid(), false, terminal_F })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n6.uid(), false, terminal_T })); - - AssertThat(arcs.can_pull_terminal(), Is().True()); - AssertThat(arcs.pull_terminal(), Is().EqualTo(arc { n6.uid(), true, terminal_T })); - - AssertThat(arcs.can_pull_terminal(), Is().False()); - - level_info_test_stream meta_arcs(out); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(0,1u))); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(1,1u))); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(2,1u))); - - AssertThat(meta_arcs.can_pull(), Is().True()); - AssertThat(meta_arcs.pull(), Is().EqualTo(level_info(3,1u))); - - AssertThat(meta_arcs.can_pull(), Is().False()); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->max_1level_cut, Is().GreaterThanOrEqualTo(1u)); - - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[false], Is().EqualTo(3u)); - AssertThat(out.get<__zdd::shared_arc_file_type>()->number_of_terminals[true], Is().EqualTo(2u)); - }); }); }); });