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
92 changes: 55 additions & 37 deletions src/todd-coxeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ semigroup.
:rtype: ToddCoxeter
)pbdoc");

////////////////////////////////////////////////////////////////////////

thing.def(
"current_index_of",
[](ToddCoxeter_ const& self, Word const& w) {
Expand Down Expand Up @@ -377,39 +379,14 @@ node corresponding to index *i* back to the root of that tree.
)pbdoc");

////////////////////////////////////////////////////////////////////////
// Helpers from cong-common.hpp . . .
// Lookahead/behind
////////////////////////////////////////////////////////////////////////

auto raises = R"pbdoc(
:raises LibsemigroupsError:
if the number of classes in *tc* is infinite. In this case, the
enumeration of *tc* will not terminate successfully.)pbdoc"sv;

def_partition<ToddCoxeter<Word>>(
m,
"ToddCoxeter",
"todd_coxeter",
doc{.only_document_once = true, .raises = raises, .var = "tc"});

def_non_trivial_classes<ToddCoxeter<Word>>(
m,
"ToddCoxeter",
"todd_coxeter",
doc{.only_document_once = true, .raises = raises, .var = "tc"});

def_normal_forms<ToddCoxeter<Word>>(m,
"ToddCoxeter",
"todd_coxeter",
doc{.detail = R"pbdoc(
The order of the classes, and the normal forms, that are returned are
controlled by :any:`ToddCoxeter.standardize`. This function triggers a full
enumeration of ``tc``.)pbdoc",
.only_document_once = true,
.raises = raises,
.var = "tc"});
thing.def(
"perform_lookahead",
[](ToddCoxeter_& self) { return self.perform_lookahead(); },
[](ToddCoxeter_& self) -> detail::ToddCoxeterImpl& {
return self.perform_lookahead();
},
R"pbdoc(
:sig=(self: ToddCoxeter) -> ToddCoxeter:

Expand All @@ -429,7 +406,8 @@ style and extent of this lookahead are controlled by the settings

thing.def(
"perform_lookahead_for",
[](ToddCoxeter_& self, std::chrono::nanoseconds t) {
[](ToddCoxeter_& self,
std::chrono::nanoseconds t) -> detail::ToddCoxeterImpl& {
return self.perform_lookahead_for(t);
},
py::arg("t"),
Expand All @@ -451,7 +429,8 @@ happens first.

thing.def(
"perform_lookahead_until",
[](ToddCoxeter_& self, std::function<bool()> const& pred) {
[](ToddCoxeter_& self,
std::function<bool()> const& pred) -> detail::ToddCoxeterImpl& {
return self.perform_lookahead_until(pred);
},
py::arg("pred"),
Expand All @@ -472,7 +451,9 @@ This function runs a lookahead until the nullary predicate *pred* returns

thing.def(
"perform_lookbehind",
[](ToddCoxeter_& self) { return self.perform_lookbehind(); },
[](ToddCoxeter_& self) -> detail::ToddCoxeterImpl& {
return self.perform_lookbehind();
},
R"pbdoc(
:sig=(self: ToddCoxeter) -> ToddCoxeter:

Expand Down Expand Up @@ -535,7 +516,8 @@ Pro).
thing.def(
"perform_lookbehind_no_checks",
[](ToddCoxeter_& self,
std::function<Word(Word const&)> const& collapser) {
std::function<Word(Word const&)> const& collapser)
-> detail::ToddCoxeterImpl& {
auto wrap = [&collapser](auto d_it, auto first, auto last) {
Word copy(first, last);
// Shame to do so much copying here but couldn't figure out how to
Expand Down Expand Up @@ -603,7 +585,8 @@ function :any:`ToddCoxeter.reduce_no_run`.

thing.def(
"perform_lookbehind_for",
[](ToddCoxeter_& self, std::chrono::nanoseconds t) {
[](ToddCoxeter_& self,
std::chrono::nanoseconds t) -> detail::ToddCoxeterImpl& {
return self.perform_lookbehind_for(t);
},
py::arg("t"),
Expand Down Expand Up @@ -631,7 +614,8 @@ happens first.
"perform_lookbehind_for_no_checks",
[](ToddCoxeter_& self,
std::chrono::nanoseconds t,
std::function<Word(Word const&)> const& collapser) {
std::function<Word(Word const&)> const& collapser)
-> detail::ToddCoxeterImpl& {
auto wrap = [&collapser](auto d_it, auto first, auto last) {
Word copy(first, last);
// Shame to do so much copying here but couldn't figure out how to
Expand Down Expand Up @@ -674,7 +658,8 @@ happens first. See :any:`perform_lookbehind_no_checks` for more details.

thing.def(
"perform_lookbehind_until",
[](ToddCoxeter_& self, std::function<bool()> const& pred) {
[](ToddCoxeter_& self,
std::function<bool()> const& pred) -> detail::ToddCoxeterImpl& {
return self.perform_lookbehind_until(pred);
},
py::arg("pred"),
Expand All @@ -701,7 +686,8 @@ This function runs a lookbehind until the nullary predicate *pred* returns
"perform_lookbehind_until_no_checks",
[](ToddCoxeter_& self,
std::function<bool()> const& pred,
std::function<Word(Word const&)> const& collapser) {
std::function<Word(Word const&)> const& collapser)
-> detail::ToddCoxeterImpl& {
auto wrap = [&collapser](auto d_it, auto first, auto last) {
Word copy(first, last);
// Shame to do so much copying here but couldn't figure out how to
Expand Down Expand Up @@ -739,6 +725,38 @@ whichever happens first.
does nothing but still might take some time to run).
)pbdoc");

////////////////////////////////////////////////////////////////////////
// Helpers from cong-common.hpp . . .
////////////////////////////////////////////////////////////////////////

auto raises = R"pbdoc(
:raises LibsemigroupsError:
if the number of classes in *tc* is infinite. In this case, the
enumeration of *tc* will not terminate successfully.)pbdoc"sv;

def_partition<ToddCoxeter<Word>>(
m,
"ToddCoxeter",
"todd_coxeter",
doc{.only_document_once = true, .raises = raises, .var = "tc"});

def_non_trivial_classes<ToddCoxeter<Word>>(
m,
"ToddCoxeter",
"todd_coxeter",
doc{.only_document_once = true, .raises = raises, .var = "tc"});

def_normal_forms<ToddCoxeter<Word>>(m,
"ToddCoxeter",
"todd_coxeter",
doc{.detail = R"pbdoc(
The order of the classes, and the normal forms, that are returned are
controlled by :any:`ToddCoxeter.standardize`. This function triggers a full
enumeration of ``tc``.)pbdoc",
.only_document_once = true,
.raises = raises,
.var = "tc"});

////////////////////////////////////////////////////////////////////////
// Helper functions - specific to ToddCoxeter
////////////////////////////////////////////////////////////////////////
Expand Down
36 changes: 23 additions & 13 deletions tests/test_todd_coxeter.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,22 +420,24 @@ def test_todd_coxeter_return_policy():
def test_todd_coxeter_perform_lookahead():
p = examples.full_transformation_monoid_Aiz58(10)
tc = ToddCoxeter(congruence_kind.twosided, p)
tc.perform_lookahead()
assert tc.perform_lookahead() is tc
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
tc.perform_lookahead()
# Check the return type is correct
assert tc.perform_lookahead() is tc
assert tc.number_of_nodes_active() < num_nodes


def test_todd_coxeter_perform_lookahead_for():
p = examples.full_transformation_monoid_Aiz58(10)
tc = ToddCoxeter(congruence_kind.twosided, p)
tc.perform_lookahead()
assert tc.perform_lookahead() is tc
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
start_time = time.time()
tc.perform_lookahead_for(timedelta(seconds=0.1))
assert time.time() - start_time <= 0.2
# Check the return type is correct
assert tc.perform_lookahead_for(timedelta(seconds=0.1)) is tc
assert time.time() - start_time <= 1.0
assert tc.number_of_nodes_active() < num_nodes


Expand All @@ -445,7 +447,8 @@ def test_todd_coxeter_perform_lookahead_until():
tc.perform_lookahead()
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
tc.perform_lookahead_until(lambda: tc.number_of_nodes_active() < num_nodes)
# Check the return type is correct
assert tc.perform_lookahead_until(lambda: tc.number_of_nodes_active() < num_nodes) is tc
assert tc.number_of_nodes_active() < num_nodes


Expand All @@ -456,8 +459,9 @@ def test_todd_coxeter_perform_lookbehind_for():
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
start_time = time.time()
tc.perform_lookbehind_for(timedelta(seconds=0.1))
assert time.time() - start_time <= 0.2
# Run and check the return type is correct
assert tc.perform_lookbehind_for(timedelta(seconds=0.1)) is tc
assert time.time() - start_time <= 1.0
assert tc.number_of_nodes_active() < num_nodes


Expand All @@ -467,7 +471,8 @@ def test_todd_coxeter_perform_lookbehind_until():
tc.perform_lookbehind()
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
tc.perform_lookbehind_until(lambda: tc.number_of_nodes_active() < num_nodes)
# Run and check the return type is correct
assert tc.perform_lookbehind_until(lambda: tc.number_of_nodes_active() < num_nodes) is tc
assert tc.number_of_nodes_active() < num_nodes


Expand All @@ -478,8 +483,9 @@ def test_todd_coxeter_perform_lookbehind_for_no_checks():
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
start_time = time.time()
tc.perform_lookbehind_for_no_checks(timedelta(seconds=0.1), lambda w: [])
assert time.time() - start_time <= 0.2
# Run and check the return type is correct
assert tc.perform_lookbehind_for_no_checks(timedelta(seconds=0.1), lambda w: []) is tc
assert time.time() - start_time <= 1.0
assert tc.number_of_nodes_active() < num_nodes


Expand All @@ -489,7 +495,11 @@ def test_todd_coxeter_perform_lookbehind_until_no_checks():
tc.perform_lookbehind()
tc.run_for(timedelta(seconds=0.01))
num_nodes = tc.number_of_nodes_active()
tc.perform_lookbehind_until_no_checks(
lambda: tc.number_of_nodes_active() < num_nodes, lambda w: []
# Run and check the return type is correct
assert (
tc.perform_lookbehind_until_no_checks(
lambda: tc.number_of_nodes_active() < num_nodes, lambda w: []
)
is tc
)
assert tc.number_of_nodes_active() < num_nodes
Loading