Skip to content

Commit 969ebb8

Browse files
c++: only bind redundant rule once
1 parent 252b70a commit 969ebb8

1 file changed

Lines changed: 62 additions & 73 deletions

File tree

src/knuth-bendix.cpp

Lines changed: 62 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -274,78 +274,6 @@ Check if the all rules are reduced with respect to each other.
274274
within the :any:`KnuthBendix` instance, :math:`C` is neither a
275275
subword of :math:`A` nor :math:`B`. Returns ``False`` otherwise.
276276
:rtype: bool
277-
)pbdoc");
278-
279-
m.def(
280-
"knuth_bendix_redundant_rule",
281-
[](Presentation<word_type> const& p, std::chrono::milliseconds t)
282-
-> std::optional<std::pair<word_type, word_type>> {
283-
auto it = knuth_bendix::redundant_rule(p, t);
284-
if (it != p.rules.cend()) {
285-
return std::make_pair(*it, *(it + 1));
286-
}
287-
return {};
288-
},
289-
R"pbdoc(
290-
:sig=(p: Presentation, t: datetime.timedelta) -> tuple[list[int], list[int]] | tuple[str, str] | None:
291-
:only-document-once:
292-
293-
Return a redundant rule or ``None``.
294-
295-
Starting with the last rule in the presentation, this function attempts
296-
to run the Knuth-Bendix algorithm on the rules of the presentation
297-
except for a given omitted rule. For every such omitted rule,
298-
Knuth-Bendix is run for the length of time indicated by the second
299-
parameter *t*, and then it is checked if the omitted rule can be shown
300-
to be redundant. If the omitted rule can be shown to be redundant in
301-
this way, then this rule is returned. If no rule can be shown to be
302-
redundant in this way, then ``None`` is returned.
303-
304-
:param p: the presentation.
305-
:type p: Presentation
306-
307-
:param t: time to run Knuth-Bendix for every omitted rule.
308-
:type t: datetime.timedelta
309-
310-
:returns: A redundant rule or ``None``.
311-
:rtype: tuple[list[int], list[int]] | tuple[str, str] | None
312-
313-
.. warning::
314-
The progress of the Knuth-Bendix algorithm may differ between
315-
different calls to this function even if the parameters are identical.
316-
As such this is non-deterministic, and may produce different results
317-
with the same input.
318-
319-
.. doctest::
320-
321-
>>> from libsemigroups_pybind11 import (knuth_bendix, presentation,
322-
... Presentation)
323-
>>> from datetime import timedelta
324-
>>> p = Presentation("ab")
325-
>>> presentation.add_rule(p, "ab", "ba")
326-
>>> presentation.add_rule(p, "bab", "abb")
327-
>>> t = timedelta(seconds = 1)
328-
>>> p.rules
329-
['ab', 'ba', 'bab', 'abb']
330-
>>> knuth_bendix.redundant_rule(p, t)
331-
('bab', 'abb')
332-
)pbdoc");
333-
334-
// Documented above
335-
m.def(
336-
"knuth_bendix_redundant_rule",
337-
[](Presentation<std::string> const& p, std::chrono::milliseconds t)
338-
-> std::optional<std::pair<std::string, std::string>> {
339-
auto it = knuth_bendix::redundant_rule(p, t);
340-
if (it != p.rules.cend()) {
341-
return std::make_pair(*it, *(it + 1));
342-
}
343-
return {};
344-
},
345-
// Signature required to avoid generating any doc
346-
R"pbdoc(
347-
:sig=(p: Presentation, t: datetime.timedelta) -> tuple[list[int], list[int]] | tuple[str, str] | None:
348-
:only-document-once:
349277
)pbdoc");
350278
} // bind_knuth_bendix
351279

@@ -408,7 +336,65 @@ Copy a :any:`NormalFormRange` object.
408336
});
409337
thing.def("next", [](NormalFormRange& nfr) { nfr.next(); });
410338
} // bind_normal_form_range
411-
} // namespace
339+
} // namespace
340+
341+
template <typename Word>
342+
void bind_redundant_rule(py::module& m) {
343+
m.def(
344+
"knuth_bendix_redundant_rule",
345+
[](Presentation<Word> const& p, std::chrono::milliseconds t)
346+
-> std::optional<std::pair<Word, Word>> {
347+
auto it = knuth_bendix::redundant_rule(p, t);
348+
if (it != p.rules.cend()) {
349+
return std::make_pair(*it, *(it + 1));
350+
}
351+
return {};
352+
},
353+
R"pbdoc(
354+
:sig=(p: Presentation, t: datetime.timedelta) -> tuple[list[int], list[int]] | tuple[str, str] | None:
355+
:only-document-once:
356+
357+
Return a redundant rule or ``None``.
358+
359+
Starting with the last rule in the presentation, this function attempts
360+
to run the Knuth-Bendix algorithm on the rules of the presentation
361+
except for a given omitted rule. For every such omitted rule,
362+
Knuth-Bendix is run for the length of time indicated by the second
363+
parameter *t*, and then it is checked if the omitted rule can be shown
364+
to be redundant. If the omitted rule can be shown to be redundant in
365+
this way, then this rule is returned. If no rule can be shown to be
366+
redundant in this way, then ``None`` is returned.
367+
368+
:param p: the presentation.
369+
:type p: Presentation
370+
371+
:param t: time to run Knuth-Bendix for every omitted rule.
372+
:type t: datetime.timedelta
373+
374+
:returns: A redundant rule or ``None``.
375+
:rtype: tuple[list[int], list[int]] | tuple[str, str] | None
376+
377+
.. warning::
378+
The progress of the Knuth-Bendix algorithm may differ between
379+
different calls to this function even if the parameters are identical.
380+
As such this is non-deterministic, and may produce different results
381+
with the same input.
382+
383+
.. doctest::
384+
385+
>>> from libsemigroups_pybind11 import (knuth_bendix, presentation,
386+
... Presentation)
387+
>>> from datetime import timedelta
388+
>>> p = Presentation("ab")
389+
>>> presentation.add_rule(p, "ab", "ba")
390+
>>> presentation.add_rule(p, "bab", "abb")
391+
>>> t = timedelta(seconds = 1)
392+
>>> p.rules
393+
['ab', 'ba', 'bab', 'abb']
394+
>>> knuth_bendix.redundant_rule(p, t)
395+
('bab', 'abb')
396+
)pbdoc");
397+
}
412398

413399
void init_knuth_bendix(py::module& m) {
414400
using RewriteTrie = detail::RewriteTrie;
@@ -430,6 +416,9 @@ Copy a :any:`NormalFormRange` object.
430416
m, "KnuthBendixNormalFormRangeStringRewriteTrie");
431417
bind_normal_form_range<std::string, RewriteFromLeft>(
432418
m, "KnuthBendixNormalFormRangeStringRewriteFromLeft");
419+
420+
bind_redundant_rule<std::string>(m);
421+
bind_redundant_rule<word_type>(m);
433422
}
434423

435424
} // namespace libsemigroups

0 commit comments

Comments
 (0)