Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions src/forest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<size_t> const& parents,
std::vector<size_t> const& labels) {
return make<Forest>(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<std::variant<Forest::node_type, Undefined>> const&
parents,
std::vector<std::variant<Forest::node_type, Undefined>> const&
labels) {
using node_type = Forest::node_type;
std::vector<node_type> parents_as_ints;
std::vector<node_type> labels_as_ints;
for (auto const& val : parents) {
if (std::holds_alternative<node_type>(val)) {
parents_as_ints.push_back(std::get<0>(val));
} else {
parents_as_ints.push_back(
static_cast<node_type>(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<node_type>(val)) {
labels_as_ints.push_back(std::get<0>(val));
} else {
labels_as_ints.push_back(
static_cast<node_type>(std::get<1>(val)));
}
}
return make<Forest>(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;
Expand Down Expand Up @@ -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<size_t, Undefined> {
[](Forest const& self,
Forest::node_type i) -> std::variant<Forest::node_type, Undefined> {
if (self.label(i) != UNDEFINED) {
return {self.label(i)};
}
Expand Down Expand Up @@ -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::variant<size_t, Undefined>> {
std::vector<std::variant<size_t, Undefined>> result;
[](Forest const& self)
-> std::vector<std::variant<Forest::node_type, Undefined>> {
std::vector<std::variant<Forest::node_type, Undefined>> result;
for (auto node : self.labels()) {
if (node != UNDEFINED) {
result.emplace_back(node);
Expand Down Expand Up @@ -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<size_t, Undefined> {
[](Forest const& self,
Forest::node_type i) -> std::variant<Forest::node_type, Undefined> {
if (self.parent(i) != UNDEFINED) {
return {self.parent(i)};
}
Expand Down Expand Up @@ -242,8 +270,9 @@ Returns the parent of a node.
)pbdoc");
thing.def(
"parents",
[](Forest const& self) -> std::vector<std::variant<size_t, Undefined>> {
std::vector<std::variant<size_t, Undefined>> result;
[](Forest const& self)
-> std::vector<std::variant<Forest::node_type, Undefined>> {
std::vector<std::variant<Forest::node_type, Undefined>> result;
for (auto node : self.parents()) {
if (node != UNDEFINED) {
result.emplace_back(node);
Expand Down
6 changes: 3 additions & 3 deletions src/todd-coxeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
<ToddCoxeter over <monoid presentation with 2 letters, 2 rules, and length 4> with 1/1 active/nodes>
<1-sided ToddCoxeter over <monoid presentation with 2 letters, 2 rules, and length 4> with 0 gen. pairs + 1 node>
>>> tc.number_of_classes()
2
>>> tc.contains("aaaa", "aa")
Expand All @@ -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)
<ToddCoxeter over <semigroup presentation with 4 letters, 12 rules, and length 79> with 1/2 active/nodes>
<2-sided ToddCoxeter over <semigroup presentation with 4 letters, 12 rules, and length 79> with 0 gen. pairs + 1 node>
>>> tc.number_of_classes()
10752
>>> tc
<ToddCoxeter over <semigroup presentation with 4 letters, 12 rules, and length 79> with 10753/2097153 active/nodes>
<2-sided ToddCoxeter over <semigroup presentation with 4 letters, 12 rules, and length 79> with 0 gen. pairs + 10,753 nodes>
>>> tc.word_graph()
<WordGraph with 10,753 nodes, 43,012 edges, & out-degree 4>
>>> it = todd_coxeter.normal_forms(tc)
Expand Down
7 changes: 2 additions & 5 deletions tests/test_word_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down