@@ -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