diff --git a/src/forest.cpp b/src/forest.cpp index 334d848c1..b25622318 100644 --- a/src/forest.cpp +++ b/src/forest.cpp @@ -68,21 +68,46 @@ Constructs a forest with *n* nodes, that is initialised so that the :param n: the number of nodes, defaults to ``0``. :type n: int )pbdoc"); - thing.def(py::init([](std::vector const& parents, - std::vector const& labels) { - return make(parents, labels); - }), - py::arg("parents"), - py::arg("labels"), - R"pbdoc( -:sig=(self: Forest, parents:List[int], labels:List[int]) -> None: + thing.def( + py::init( + [](std::vector> const& + parents, + std::vector> const& + labels) { + using node_type = Forest::node_type; + std::vector parents_as_ints; + std::vector labels_as_ints; + for (auto const& val : parents) { + if (std::holds_alternative(val)) { + parents_as_ints.push_back(std::get<0>(val)); + } else { + parents_as_ints.push_back( + static_cast(std::get<1>(val))); + } + } + // TODO there's something like this in transf.cpp too, we should + // avoid code dupl + for (auto const& val : labels) { + if (std::holds_alternative(val)) { + labels_as_ints.push_back(std::get<0>(val)); + } else { + labels_as_ints.push_back( + static_cast(std::get<1>(val))); + } + } + return make(parents_as_ints, labels_as_ints); + }), + py::arg("parents"), + py::arg("labels"), + R"pbdoc( +:sig=(self: Forest, parents:List[int | Undefined], labels:List[int | Undefined]) -> None: Construct a :any:`Forest` from list of *parents* and *labels*. :param parent: the list of parents of nodes. -:type parent: List[int] +:type parent: List[int | Undefined] :param labels: the list of edge labels. -:type labels: List[int] +:type labels: List[int | Undefined] :raises LibsemigroupsError: if *parent* and *labels* have different sizes; @@ -138,7 +163,8 @@ the same state as if it had just be constructed as ``Forest(n)``. )pbdoc"); thing.def( "label", - [](Forest const& self, size_t i) -> std::variant { + [](Forest const& self, + Forest::node_type i) -> std::variant { if (self.label(i) != UNDEFINED) { return {self.label(i)}; } @@ -168,8 +194,9 @@ Returns the label of the edge from a node to its parent. )pbdoc"); thing.def( "labels", - [](Forest const& self) -> std::vector> { - std::vector> result; + [](Forest const& self) + -> std::vector> { + std::vector> result; for (auto node : self.labels()) { if (node != UNDEFINED) { result.emplace_back(node); @@ -213,7 +240,8 @@ in the forest. thing.def(py::self == py::self, py::arg("that")); thing.def( "parent", - [](Forest const& self, size_t i) -> std::variant { + [](Forest const& self, + Forest::node_type i) -> std::variant { if (self.parent(i) != UNDEFINED) { return {self.parent(i)}; } @@ -242,8 +270,9 @@ Returns the parent of a node. )pbdoc"); thing.def( "parents", - [](Forest const& self) -> std::vector> { - std::vector> result; + [](Forest const& self) + -> std::vector> { + std::vector> result; for (auto node : self.parents()) { if (node != UNDEFINED) { result.emplace_back(node); diff --git a/src/todd-coxeter.cpp b/src/todd-coxeter.cpp index 3a3746ed3..7c80e20d8 100644 --- a/src/todd-coxeter.cpp +++ b/src/todd-coxeter.cpp @@ -62,7 +62,7 @@ execution of (any version of) the Todd-Coxeter algorithm. >>> presentation.add_rule(p, "aa", "") >>> presentation.add_rule(p, "a", "b") >>> tc.init(congruence_kind.onesided, p).strategy(options.strategy.felsch) - with 1/1 active/nodes> + <1-sided ToddCoxeter over with 0 gen. pairs + 1 node> >>> tc.number_of_classes() 2 >>> tc.contains("aaaa", "aa") @@ -84,11 +84,11 @@ execution of (any version of) the Todd-Coxeter algorithm. >>> presentation.add_rule(p, "bcbdbcbdbcbdbcbdbcbdbcbdbcbdbcbd", "a"); >>> tc = ToddCoxeter(congruence_kind.twosided, p) >>> tc.strategy(options.strategy.hlt).lookahead_extent(options.lookahead_extent.partial).save(False) - with 1/2 active/nodes> + <2-sided ToddCoxeter over with 0 gen. pairs + 1 node> >>> tc.number_of_classes() 10752 >>> tc - with 10753/2097153 active/nodes> + <2-sided ToddCoxeter over with 0 gen. pairs + 10,753 nodes> >>> tc.word_graph() >>> it = todd_coxeter.normal_forms(tc) diff --git a/tests/test_word_graph.py b/tests/test_word_graph.py index 5e39b3798..524b8c153 100644 --- a/tests/test_word_graph.py +++ b/tests/test_word_graph.py @@ -239,7 +239,7 @@ def test_spanning_tree(word_graph_fixture): wg1, _ = word_graph_fixture assert word_graph.spanning_tree(wg1, 0) == Forest( - [int(UNDEFINED), 0, 1, 2, 3], [int(UNDEFINED), 0, 0, 0, 0] + [UNDEFINED, 0, 1, 2, 3], [UNDEFINED, 0, 0, 0, 0] ) f = Forest(0) @@ -305,10 +305,7 @@ def test_joiner(word_graph_fixture): def test_str(word_graph_fixture): wg1, wg2 = word_graph_fixture assert str(wg1) == "WordGraph(5, [[1], [2], [3], [4], [0]])" - assert ( - str(wg2) - == "WordGraph(10, [[1], [2], [3], [4], [0], [6], [7], [8], [9], [5]])" - ) + assert str(wg2) == "WordGraph(10, [[1], [2], [3], [4], [0], [6], [7], [8], [9], [5]])" def test_copy(word_graph_fixture):