diff --git a/docs/source/conf.py b/docs/source/conf.py index d85408a4..51ec0357 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -189,7 +189,7 @@ # Python code that is treated like it were put in a testsetup directive for # every file that is tested, and for every group. doctest_global_setup = """from libsemigroups_pybind11 import ReportGuard -ReportGuard(False)""" +rg = ReportGuard(False)""" ############ intersphinx ############ diff --git a/docs/source/data-structures/presentations/alphabet-helpers.rst b/docs/source/data-structures/presentations/alphabet-helpers.rst new file mode 100644 index 00000000..81e7eaac --- /dev/null +++ b/docs/source/data-structures/presentations/alphabet-helpers.rst @@ -0,0 +1,21 @@ +Alphabet Helpers +---------------- + +.. currentmodule:: libsemigroups_pybind11.alphabet + +This page contains the documentation for the ``alphabet`` subpackage, that contains +helper functions for the :any:`Alphabet` class. + +.. TODO "validate" is really in libsemigroups namespace and as such should be + on its own page probably, like "to" + +.. autosummary:: + :signatures: short + + first_unused_letter + validate + +.. automodule:: libsemigroups_pybind11.alphabet + :members: + :imported-members: + :exclude-members: Alphabet diff --git a/docs/source/data-structures/presentations/alphabet.rst b/docs/source/data-structures/presentations/alphabet.rst new file mode 100644 index 00000000..b70f176c --- /dev/null +++ b/docs/source/data-structures/presentations/alphabet.rst @@ -0,0 +1,53 @@ +.. + Copyright (c) 2026 J. D. Mitchell + + Distributed under the terms of the GPL license version 3. + + The full license is in the file LICENSE, distributed with this software. + +.. currentmodule:: libsemigroups_pybind11 + +The Alphabet class +================== + +.. autoclass:: Alphabet + :doc-only: + +.. Types + + ----- + + In what follows, we use the following pseudo-types: + + - ``Letter`` for ``str | int`` + - ``Word`` for ``str | list[int]`` + + Recall that, once an alphabet has been constructed, the type of its letters and + words are fixed. + +Contents +-------- + +.. autosummary:: + :signatures: short + + ~Alphabet + Alphabet.add_letter + Alphabet.copy + Alphabet.contains + Alphabet.empty + Alphabet.index + Alphabet.init + Alphabet.letter + Alphabet.letters + Alphabet.remove_letter + Alphabet.throw_if_duplicate_letters + Alphabet.throw_if_letter_not_in_alphabet + +Full API +-------- + +.. autoclass:: Alphabet + :class-doc-from: init + :members: + diff --git a/docs/source/data-structures/presentations/index.rst b/docs/source/data-structures/presentations/index.rst index 34117135..d2a19bfb 100644 --- a/docs/source/data-structures/presentations/index.rst +++ b/docs/source/data-structures/presentations/index.rst @@ -36,10 +36,13 @@ semigroups and monoids are: .. toctree:: :maxdepth: 1 + alphabet present inverse-present + alphabet-helpers present-helpers examples + to-alphabet to-present to-inverse-present obvinf diff --git a/docs/source/data-structures/presentations/to-alphabet.rst b/docs/source/data-structures/presentations/to-alphabet.rst new file mode 100644 index 00000000..fa1afe52 --- /dev/null +++ b/docs/source/data-structures/presentations/to-alphabet.rst @@ -0,0 +1,85 @@ +.. + Copyright (c) 2026 J. D. Mitchell + + Distributed under the terms of the GPL license version 3. + + The full license is in the file LICENSE, distributed with this software. + +.. currentmodule:: libsemigroups_pybind11 + +Converting to an Alphabet +========================= + +This page contains documentation relating to converting +``libsemigroups_pybind11`` objects into :any:`Alphabet` instances using the +:any:`to` function. + +.. seealso:: + + :doc:`/data-structures/to-function` for an overview of possible conversions + between ``libsemigroups_pybind11`` types. + +Various uses +------------ + +Recall that the signature for the :any:`to` function is ``to(*args, rtype)``. +In what follows, we explain how different values of *args* and *rtype* may be +used to construct :any:`Alphabet` objects. + +.. _alphabet-to-alphabet: + +Converting an :any:`Alphabet` to an :any:`Alphabet` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To construct an :any:`Alphabet` from an :any:`Alphabet`, specify the following +values for *args*: + + - **alphabet** (:any:`Alphabet`) -- the :any:`Alphabet` to convert. + +Additionally, specify one of the following for *rtype*: + + - ``(Alphabet, str)`` for constructing an :any:`Alphabet` over words of type + ``str``. + - ``(Alphabet, list[int])`` for constructing an :any:`Alphabet` over words + of type ``list[int]``. + +This function behaves in one of two ways, depending on the type of words in +*alphabet*, and the type of words specified in *rtype*: + + 1. When the type of words in *alphabet* and type of words specified in + *rtype* are not the same, this function returns an :any:`Alphabet` + equivalent to the input :any:`Alphabet` *alphabet* but with words a + different type (for example, can be used to convert from ``str`` to + ``list[int]``). + 2. When the type of words in *alphabet* and type of words specified in + *rtype* are the same, this function effectively just returns its argument + *alphabet*, and is included solely for the purpose of simplifying certain + client code, where alphabets must be converted from one type to another + sometimes, but not other times. + +If *alphabet* has letters :math:`\{a_0, a_1, \dots a_{n-1}\}`, where each +letter is of type ``str``, then the conversion from one type to another is +:math:`a_i \mapsto` ``human_readable_index(a_i)``. Conversely, if each letter is +of type ``int``, then the conversion from one type to another is +:math:`a_i \mapsto` ``human_readable_letter(a_i)``. + +.. seealso:: + + - :any:`words.human_readable_index`; + - :any:`words.human_readable_letter`; and + - :any:`Alphabet.throw_if_duplicate_letters`. + +.. doctest:: Python + + >>> from libsemigroups_pybind11 import Alphabet, to + + >>> a = Alphabet("abcdef") + >>> a == to(a, rtype=(Alphabet, str)) + True + + >>> b = to(a, rtype=(Alphabet, list[int])) + >>> b.letters() + [0, 1, 2, 3, 4, 5] + + >>> to(b, rtype=(Alphabet, str)) == a + True diff --git a/docs/source/data-structures/presentations/to-inverse-present.rst b/docs/source/data-structures/presentations/to-inverse-present.rst index 5070b987..1348525d 100644 --- a/docs/source/data-structures/presentations/to-inverse-present.rst +++ b/docs/source/data-structures/presentations/to-inverse-present.rst @@ -98,7 +98,7 @@ Additionally, specify one of the following for *rtype*: - ``(InversePresentation, list[int])`` for constructing an :any:`InversePresentation` over words of type ``list[int]``. -This function behaves in one of two ways, depending on type of words in *ip*, and +This function behaves in one of two ways, depending on the type of words in *ip*, and the type of words specified in *rtype*: 1. When the type of words in *ip* and type of words specified in *rtype* diff --git a/docs/source/data-structures/presentations/to-present.rst b/docs/source/data-structures/presentations/to-present.rst index 315f19f6..81acb4a4 100644 --- a/docs/source/data-structures/presentations/to-present.rst +++ b/docs/source/data-structures/presentations/to-present.rst @@ -53,7 +53,7 @@ Additionally, specify one of the following for *rtype*: - ``(Presentation, list[int])`` for constructing a :any:`Presentation` over words of type ``list[int]``. -This function behaves in one of two ways, depending on type of words in *p*, and +This function behaves in one of two ways, depending on the type of words in *p*, and the type of words specified in *rtype*: 1. When the type of words in *p* and type of words specified in *rtype* are diff --git a/src/alphabet.cpp b/src/alphabet.cpp new file mode 100644 index 00000000..03c6448a --- /dev/null +++ b/src/alphabet.cpp @@ -0,0 +1,639 @@ +// +// libsemigroups - C++ library for semigroups and monoids +// Copyright (C) 2026 James D. Mitchell +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// libsemigroups headers +#include + +// pybind11.... +#include +#include +#include + +// libsemigroups_pybind11.... +#include "main.hpp" // for init_alphabet + +namespace py = pybind11; + +namespace libsemigroups { + + namespace { + template + void bind_alphabet(py::module& m, std::string name) { + using Alphabet_ = Alphabet; + + using size_type = typename Alphabet_::size_type; + using native_word_type = typename Alphabet_::native_word_type; + using native_letter_type = typename Alphabet_::native_letter_type; + + py::class_ thing(m, + name.c_str(), + R"pbdoc( +Class for storing and indexing an alphabet. + +An :any:`Alphabet` object stores an ordered list of distinct letters and +maintains a map from each letter to its position in that list. The order of the +letters is significant: it is the order used by :any:`letter` and +:any:`Alphabet.index`. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> list(a) + ['a', 'b', 'c'] + >>> a.index("b") + 1)pbdoc"); + + //////////////////////////////////////////////////////////////////////// + // Operators + //////////////////////////////////////////////////////////////////////// + + thing.def("__repr__", [](Alphabet_ const& thing) { + return to_human_readable_repr(thing); + }); + + thing.def("__str__", [](Alphabet_ const& self) { + return to_input_string(self, "[]"); + }); + + thing.def("__len__", &Alphabet_::size); + + thing.def("__copy__", + [](Alphabet_ const& self) { return Alphabet(self); }); + + thing.def( + "__iter__", + [](Alphabet_ const& self) { + return py::make_iterator(self.letters().begin(), + self.letters().end()); + }, + py::keep_alive<0, 1>()); + + thing.def(py::self == py::self); + thing.def(py::self != py::self); + + //////////////////////////////////////////////////////////////////////// + // Constructors + initializers + //////////////////////////////////////////////////////////////////////// + + thing.def(py::init<>(), R"pbdoc( +:sig=(self: Alphabet, *, word: type) -> None: +::only-document-once: +Create an empty alphabet. + +This function creates an empty alphabet. + +:Keyword Arguments: + * **word** (*type*) -- the type of words to use. Must be either ``str`` or + ``list[int]``. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet(word=str).empty() + True + >>> Alphabet(word=list[int]).empty() + True)pbdoc"); + + thing.def( + "init", + [](Alphabet_& self) -> Alphabet_& { return self.init(); }, + R"pbdoc( +:sig=(self: Alphabet) -> Alphabet: + +Remove all letters. + +This function clears the alphabet, putting it back into the state it would be in +if it was newly created. + +:returns: ``self``. +:rtype: Alphabet + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> a.init() is a + True + >>> a.empty() + True +)pbdoc"); + + thing.def(py::init(), R"pbdoc( +:sig=(self: Alphabet, letters: str | list[int]) -> None: +::only-document-once: +Create from letters. + +This function creates an alphabet with the letters in *letters*. + +:param letters: the alphabet. +:type letters: str | list[int] + +:raises LibsemigroupsError: if there are duplicate letters in *letters*. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").letters() + 'abc' + >>> Alphabet([0, 2]).letters() + [0, 2] +)pbdoc"); + + thing.def( + "init", + [](Alphabet_& self, native_word_type const& letters) -> Alphabet_& { + return self.init(letters); + }, + py::arg("letters"), + R"pbdoc( +:sig=(self: Alphabet, letters: str | list[int]) -> Alphabet: + +Re-initialize from letters. + +This function sets the alphabet to be the letters in *letters*. + +:param letters: the alphabet. +:type letters: str | list[int] + +:returns: ``self``. +:rtype: Alphabet + +:raises LibsemigroupsError: if there are duplicate letters in *letters*. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> a.init("de") is a + True + >>> a.letters() + 'de' +)pbdoc"); + + thing.def(py::init(), R"pbdoc( +:sig=(self: Alphabet, n: int, *, word: type) -> None: +::only-document-once: + +Create an alphabet by size. + +This function creates an alphabet containing the first *n* human-readable +letters if the keyword argument *word* is ``str`` and the integers in the interval :math:`[0, n)` if *word* is ``list[int]``. + +:param n: the size of the alphabet. +:type n: int + +:Keyword Arguments: + * **word** (*type*) -- the type of words to use. Must be either ``str`` or + ``list[int]``. + +:raises LibsemigroupsError: + if the value of *n* is greater than the maximum number of supported + letters. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet(3, word=str).letters() + 'abc' + >>> Alphabet(3, word=list[int]).letters() + [0, 1, 2] +)pbdoc"); + + thing.def( + "init", + [](Alphabet_& self, size_type n) -> Alphabet_& { + return self.init(n); + }, + py::arg("n"), + R"pbdoc( +:sig=(self: Alphabet, n: int) -> Alphabet: + +Re-initialize the alphabet by size. + +This function replaces the alphabet by the first *n* human-readable letters. + +:param n: the size of the alphabet. +:type n: int + +:returns: ``self``. +:rtype: Alphabet + +:raises LibsemigroupsError: + if the value of *n* is greater than the maximum number of supported + letters. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> a.init(2) is a + True + >>> a.letters() + 'ab' +)pbdoc"); + + thing.def( + "copy", + [](Alphabet_ const& self) { return Alphabet(self); }, + R"pbdoc( +:sig=(self: Alphabet) -> Alphabet: + +Copy a :any:`Alphabet` object. + +:returns: A copy. +:rtype: Alphabet + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> b = a.copy() + >>> b == a + True + >>> b is a + False +)pbdoc"); + + //////////////////////////////////////////////////////////////////////// + // Mem fns + //////////////////////////////////////////////////////////////////////// + + thing.def("add_letter", + &Alphabet_::add_letter, + py::arg("x"), + R"pbdoc( +:sig=(self: Alphabet, x: str | int) -> Alphabet: + +Add a letter. + +This function adds the letter *x* to the alphabet. + +:param x: the letter to add. +:type x: str | int + +:returns: ``self``. +:rtype: Alphabet + +:raises LibsemigroupsError: if *x* is in :any:`letters`. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("ab") + >>> a.add_letter("c") is a + True + >>> a.letters() + 'abc' +)pbdoc"); + + thing.def("contains", + &Alphabet_::contains, + py::arg("x"), + R"pbdoc( +:sig=(self: Alphabet, x: str | int) -> bool: + +Check if a letter belongs to the alphabet or not. + +This function checks whether *x* belongs to the alphabet. + +:param x: the letter to check. +:type x: str | int + +:returns: Whether or not *x* belongs to the alphabet. +:rtype: bool + +:complexity: Constant on average, worst case linear in the size of the alphabet. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> a.contains("a") + True + >>> a.contains("d") + False +)pbdoc"); + + thing.def("empty", + &Alphabet_::empty, + R"pbdoc( +:sig=(self: Alphabet) -> bool: + +Check if the alphabet is empty. + +This function returns ``True`` if the alphabet contains no letters, and +``False`` otherwise. + +:returns: Whether or not the alphabet is empty. +:rtype: bool + +:complexity: Constant. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet(word=str).empty() + True + >>> Alphabet("abc").empty() + False +)pbdoc"); + + thing.def("index", + &Alphabet_::index, + py::arg("x"), + R"pbdoc( +:sig=(self: Alphabet, x: str | int) -> int: + +Return the index of a letter in the alphabet. + +After checking that *x* is in the alphabet, this function returns the index +of *x* in the alphabet. + +:param x: the possible letter to check. +:type x: str | int + +:returns: The index of *x* in the alphabet. +:rtype: int + +:raises LibsemigroupsError: if ``x`` does not belong to the alphabet. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").index("b") + 1 + >>> Alphabet([4, 2]).index(2) + 1 +)pbdoc"); + + thing.def("letter", + &Alphabet_::letter, + py::arg("i"), + R"pbdoc( +:sig=(self: Alphabet, i: int) -> str | int: + +Return a letter in the alphabet by index. + +After checking that *i* is in the range :math:`[0, n)`, where :math:`n` is +the length of the alphabet, this function returns the letter with index *i*. + +:param i: the index. +:type i: int + +:returns: The letter with index *i*. +:rtype: str | int + +:raises LibsemigroupsError: if *i* is not in the range :math:`[0, n)`. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").letter(2) + 'c' + >>> Alphabet([4, 2]).letter(0) + 4 +)pbdoc"); + + thing.def("letters", + &Alphabet_::letters, + R"pbdoc( +:sig=(self: Alphabet) -> str | list[int]: +Return the letters of the alphabet. + +This function returns the letters of the alphabet. + +:returns: The letters of the alphabet. +:rtype: str | list[int] + +:complexity: Constant. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").letters() + 'abc' + >>> Alphabet([0, 2]).letters() + [0, 2] +)pbdoc"); + + thing.def("remove_letter", + &Alphabet_::remove_letter, + py::arg("x"), + R"pbdoc( +:sig=(self: Alphabet, x: str | int) -> Alphabet: + +Remove a letter. + +This function removes the letter *x* from the alphabet. + +:param x: the letter to remove. +:type x: str | int + +:returns: ``self``. +:rtype: Alphabet + +:raises LibsemigroupsError: if *x* is not in :any`letters`. + +:complexity: + Average case: linear in the length of the alphabet, worst case: quadratic in + the length of the alphabet. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> a = Alphabet("abc") + >>> a.remove_letter("b") is a + True + >>> a.letters() + 'ac' +)pbdoc"); + + thing.def( + "throw_if_duplicate_letters", + [](Alphabet_ const& self) { + return self.throw_if_duplicate_letters(); + }, + R"pbdoc( +:sig=(self: Alphabet) -> None: + +Check if the alphabet contains duplicates. + +This function checks if the alphabet contains duplicates.. + +:raises LibsemigroupsError: if there are duplicate letters in the alphabet. + +:complexity: Linear in the length of the alphabet. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").throw_if_duplicate_letters() is None + True)pbdoc"); + // thing.def( + // "throw_if_letter_not_in_alphabet", + // [](Alphabet_ const& self, Iterator1 first, Iterator2 last) { + // return self.throw_if_letter_not_in_alphabet(first, last); + // }, + // py::arg("first"), + // py::arg("last"), + // R"pbdoc( + // Check if every letter in a range belongs to the alphabet. + // + // :param first: iterator pointing at the first letter to check. + // :type first: Iterator1 + // + // :param last: iterator pointing one beyond the last letter to check. + // :type last: Iterator2 + // Checks whether every letter in the range ``[first, last)`` belongs to + // the alphabet. + // + // :raises LibsemigroupsError: if any letter in ``[first, last)`` does + // not belong to the alphabet. + // + // :complexity: Linear in the length of the range on average, worst case + // proportional to the product of the length of the range and the size of + // the alphabet. + // + // Example + // ------- + // + // .. doctest:: python + // + // >>> from libsemigroups_pybind11 import Alphabet + // >>> Alphabet("abc").throw_if_letter_not_in_alphabet("a") is None + // True)pbdoc"); + thing.def( + "throw_if_letter_not_in_alphabet", + [](Alphabet_ const& self, native_letter_type x) { + return self.throw_if_letter_not_in_alphabet(x); + }, + py::arg("x"), + R"pbdoc( +:sig=(self: Alphabet, x : str | int) -> None: + +Check if a letter belongs to the alphabet or not. + +This function checks whether or not *x* belongs to the alphabet. + +:param x: the letter to check. +:type x: str | int + +:raises LibsemigroupsError: if *x* does not belong to the alphabet. + +:complexity: Constant on average, worst case linear in the size of the alphabet. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet("abc").throw_if_letter_not_in_alphabet("a") is None + True)pbdoc"); + + //////////////////////////////////////////////////////////////////////// + // Helpers in libsemigroups namespace + //////////////////////////////////////////////////////////////////////// + + m.def( + "validate", + [](Alphabet const& alphabet) { return validate(alphabet); }, + py::arg("alphabet"), + R"pbdoc( +:sig=(alphabet: Alphabet) -> None: +::only-document-once: + +Check if an alphabet is valid. + +This function checks whether the parameter *alphabet* is valid. + +:param alphabet: the alphabet to validate. +:type alphabet: Alphabet + +:raises LibsemigroupsError: if *alphabet* contains duplicate letters. + +:complexity: Linear in the size of *alphabet*. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet, alphabet + >>> alphabet.validate(Alphabet("abc")) is None + True)pbdoc"); + + //////////////////////////////////////////////////////////////////////// + // Helpers in alphabet namespace + //////////////////////////////////////////////////////////////////////// + + m.def( + "alphabet_first_unused_letter", + [](Alphabet const& alphabet) { + return alphabet::first_unused_letter(alphabet); + }, + py::arg("alphabet"), + R"pbdoc( +:sig=(alphabet: Alphabet) -> str | int: +::only-document-once: + +Return the first letter not in the alphabet. + +This function returns ``words.human_readable_letter(i)``, where ``i`` is the +least possible value such that the returned letter does not belong to +*alphabet*. + +:param alphabet: the alphabet. +:type alphabet: Alphabet + +:returns: The first unused letter. +:rtype: str | int + +:raises LibsemigroupsError: + if ``alphabet`` already contains the maximum possible number of supported + letters. + +.. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet, alphabet + >>> alphabet.first_unused_letter(Alphabet("abc")) + 'd' +)pbdoc"); + } // bind_alphabet + + template + void bind_to_alphabet(py::module& m, std::string const& name) { + std::string fn_name = std::string("to_alphabet_") + name; + // NOTE: the following prevents the _cxx_obj of a python Alphabet from + // being copied here, but doesn't prevent the python Alphabet itself from + // being copied. + using Result = std::conditional_t, + Alphabet const&, + Alphabet>; + + m.def(fn_name.c_str(), [](Alphabet const& p) -> Result { + return to>(p); + }); + } + } // namespace + + void init_alphabet(py::module& m) { + bind_alphabet(m, "AlphabetString"); + bind_alphabet(m, "AlphabetWord"); + + bind_to_alphabet(m, "string"); + bind_to_alphabet(m, "string"); + bind_to_alphabet(m, "word"); + bind_to_alphabet(m, "word"); + } +} // namespace libsemigroups diff --git a/src/libsemigroups_pybind11/__init__.py b/src/libsemigroups_pybind11/__init__.py index 132396e2..d75c4998 100644 --- a/src/libsemigroups_pybind11/__init__.py +++ b/src/libsemigroups_pybind11/__init__.py @@ -10,6 +10,7 @@ action, adapters, aho_corasick, + alphabet, bipartition, blocks, bmat8, @@ -36,6 +37,7 @@ from ._version import __version__ from .action import Action, LeftAction, RightAction from .adapters import ImageLeftAction, ImageRightAction +from .alphabet import Alphabet, validate from .bipartition import Bipartition from .blocks import Blocks from .congruence import Congruence @@ -169,6 +171,7 @@ "action", "adapters", "aho_corasick", + "alphabet", "bipartition", "blocks", "bmat8", @@ -193,6 +196,7 @@ "words", # Classes defined in submodules "Action", + "Alphabet", "Bipartition", "Blocks", "Congruence", @@ -225,8 +229,9 @@ "ToddCoxeter", "Transf", # Free functions from submodules - "to", "is_obviously_infinite", + "to", + "validate", ] if LIBSEMIGROUPS_HPCOMBI_ENABLED: diff --git a/src/libsemigroups_pybind11/alphabet.py b/src/libsemigroups_pybind11/alphabet.py new file mode 100644 index 00000000..a5aeafde --- /dev/null +++ b/src/libsemigroups_pybind11/alphabet.py @@ -0,0 +1,139 @@ +# Copyright (c) 2026 J. D. Mitchell +# +# Distributed under the terms of the GPL license version 3. +# +# The full license is in the file LICENSE, distributed with this software. + +# No doc string, this file is documented in alphabet-helpers.rst + +# pylint: disable=missing-module-docstring + +import collections + +from typing_extensions import Self as _Self + +from _libsemigroups_pybind11 import ( + AlphabetString as _AlphabetString, + AlphabetWord as _AlphabetWord, + alphabet_first_unused_letter as _alphabet_first_unused_letter, + validate as _validate, +) + +from .detail.cxx_wrapper import ( + CxxWrapper as _CxxWrapper, + copy_cxx_mem_fns as _copy_cxx_mem_fns, + register_cxx_wrapped_type as _register_cxx_wrapped_type, + to_cxx as _to_cxx, + wrap_cxx_free_fn as _wrap_cxx_free_fn, +) +from .detail.decorators import copydoc as _copydoc + + +class Alphabet(_CxxWrapper): + __doc__ = _AlphabetString.__doc__ + + _py_template_params_to_cxx_type = {(str,): _AlphabetString, (list[int],): _AlphabetWord} + + _cxx_type_to_py_template_params = dict( + zip( + _py_template_params_to_cxx_type.values(), + _py_template_params_to_cxx_type.keys(), + strict=True, + ) + ) + + _all_wrapped_cxx_types = {*_py_template_params_to_cxx_type.values()} + + @staticmethod + def _validate_word_type(word: type) -> None: + if word not in (str, list[int]): + raise ValueError( + f'the keyword argument "word" must be str or list[int], but found {word}' + ) + + @_copydoc(_AlphabetString.__init__, _AlphabetWord.__init__) + def __init__(self: _Self, *args, **kwargs) -> None: + """__init__(self: Alphabet, *, word: type) -> None + + Construct an empty alphabet. + + :Keyword Arguments: + * **word** (*type*) -- the type of words to use. Must be either + ``str`` or ``list[int]``. + + .. doctest:: python + + >>> from libsemigroups_pybind11 import Alphabet + >>> Alphabet(word=str).empty() + True + >>> Alphabet(word=list[int]).empty() + True + """ + super().__init__(*args, optional_kwargs=("word",), **kwargs) + if _to_cxx(self) is not None: + return + + if len(args) > 1: + raise TypeError(f"expected at most 1 positional argument, found {len(args)}") + + if len(args) == 1 and "word" in kwargs and not isinstance(args[0], int): + raise TypeError( + 'expected either 1 positional argument or the keyword argument "word" ' + f"but found both, with argument type {type(args[0])}" + ) + + if len(args) == 0: + if "word" not in kwargs: + raise TypeError( + f'expected the keyword argument "word", but found {tuple(kwargs.keys())}' + ) + self._validate_word_type(kwargs["word"]) + self.py_template_params = (kwargs["word"],) + self.init_cxx_obj() + return + + if isinstance(args[0], Alphabet): + self.py_template_params = args[0].py_template_params + elif isinstance(args[0], str): + self.py_template_params = (str,) + elif isinstance(args[0], list): + if not all(isinstance(x, int) for x in args[0]): + raise TypeError("expected the argument to consist of int values") + self.py_template_params = (list[int],) + elif isinstance(args[0], int): + if "word" not in kwargs: + raise TypeError('expected the keyword argument "word" when constructing by size') + self._validate_word_type(kwargs["word"]) + self.py_template_params = (kwargs["word"],) + else: + raise TypeError( + f"expected the argument to have type one of (str, list[int], int) " + f"but found {type(args[0])}" + ) + + self.init_cxx_obj(*args) + + def __contains__(self: _Self, val: str | int) -> bool: + return _to_cxx(self).contains(val) + + def __eq__(self: _Self, other: _Self) -> bool: + return _to_cxx(self) == _to_cxx(other) + + def __len__(self: _Self) -> int: + return len(_to_cxx(self)) + + def __str__(self: _Self) -> str: + return str(_to_cxx(self)) + + def __iter__(self: _Self) -> collections.abc.Iterator[int | str]: + return iter(_to_cxx(self)) + + +_copy_cxx_mem_fns(_AlphabetString, Alphabet) +_register_cxx_wrapped_type(_AlphabetString, Alphabet) +_register_cxx_wrapped_type(_AlphabetWord, Alphabet) + +first_unused_letter = _wrap_cxx_free_fn(_alphabet_first_unused_letter) +validate = _wrap_cxx_free_fn(_validate) + +__all__ = ["Alphabet", "first_unused_letter", "validate"] diff --git a/src/libsemigroups_pybind11/to.py b/src/libsemigroups_pybind11/to.py index 7a1c71cf..f195a4c7 100644 --- a/src/libsemigroups_pybind11/to.py +++ b/src/libsemigroups_pybind11/to.py @@ -12,6 +12,8 @@ from _libsemigroups_pybind11 import ( Order as _Order, + to_alphabet_string as _to_alphabet_string, + to_alphabet_word as _to_alphabet_word, to_congruence_string as _to_congruence_string, to_congruence_word as _to_congruence_word, to_froidure_pin as _to_froidure_pin, @@ -39,6 +41,7 @@ to_todd_coxeter_word as _to_todd_coxeter_word, ) +from .alphabet import Alphabet as _Alphabet from .congruence import Congruence as _Congruence from .detail.cxx_wrapper import to_cxx as _to_cxx from .froidure_pin import FroidurePin as _FroidurePin @@ -70,8 +73,10 @@ def _nice_name(type_list): _RETURN_TYPE_TO_CONVERTER_FUNCTION = { - (_Congruence, str): _to_congruence_string, + (_Alphabet, str): _to_alphabet_string, + (_Alphabet, list[int]): _to_alphabet_word, (_Congruence, list[int]): _to_congruence_word, + (_Congruence, str): _to_congruence_string, (_FroidurePin,): _to_froidure_pin, (_InversePresentation,): _to_inverse_presentation, (_InversePresentation, list[int]): _to_inverse_presentation_word, @@ -118,6 +123,7 @@ def to(*args, rtype: tuple): See the following pages for a detailed description of the various use cases of this function: + * :doc:`/data-structures/presentations/to-alphabet`; * :doc:`/main-algorithms/congruence/to-cong`; * :doc:`/main-algorithms/froidure-pin/to-froidure-pin`; * :doc:`/data-structures/presentations/to-inverse-present`; diff --git a/src/main.cpp b/src/main.cpp index fe397bef..c67bbdcf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,6 +76,7 @@ namespace libsemigroups { init_runner(m); // Must be before cong classes + init_alphabet(m); init_present(m); init_inverse_present(m); diff --git a/src/main.hpp b/src/main.hpp index a098df62..0f9742a4 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -38,6 +38,7 @@ namespace libsemigroups { void init_action(py::module&); void init_aho_corasick(py::module&); + void init_alphabet(py::module&); void init_bipart(py::module&); void init_blocks(py::module&); void init_bmat8(py::module&); diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..e5c6fb4b --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,13 @@ +"""This file contains the configuration for pytest.""" + +import pytest + +from libsemigroups_pybind11 import ReportGuard + + +@pytest.fixture(autouse=True) +def setup_each_test(): + """Avoid having to write ReportGuard(false) in every test case""" + rg = ReportGuard(False) + yield + del rg diff --git a/tests/runner.py b/tests/runner.py index 6af59e25..e974b8f8 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -10,15 +10,12 @@ from datetime import timedelta -from libsemigroups_pybind11 import ReportGuard - N = 0 # pylint: disable=invalid-name def check_runner(x, t=timedelta(microseconds=1000)): # pylint: disable=missing-function-docstring global N # pylint: disable=global-statement N = 0 - ReportGuard(False) assert not x.stopped() assert not x.finished() diff --git a/tests/test_alphabet.py b/tests/test_alphabet.py new file mode 100644 index 00000000..8659c5eb --- /dev/null +++ b/tests/test_alphabet.py @@ -0,0 +1,319 @@ +# Copyright (c) 2026 J. D. Mitchell +# +# Distributed under the terms of the GPL license version 3. +# +# The full license is in the file LICENSE, distributed with this software. + +"""This module contains some tests for the Alphabet class.""" + +# pylint: disable=missing-function-docstring + +import pytest + +from libsemigroups_pybind11 import Alphabet, LibsemigroupsError, alphabet, to + + +def test_string_alphabet(): + a = Alphabet("abc") + + assert len(a) == 3 + assert not a.empty() + assert "a" in a + assert "d" not in a + assert a.letters() == "abc" + assert a.index("b") == 1 + assert a.letter(2) == "c" + assert alphabet.first_unused_letter(a) == "d" + assert alphabet.validate(a) is None + + with pytest.raises(LibsemigroupsError): + Alphabet("aa") + + +def test_word_alphabet(): + a = Alphabet([0, 2]) + + assert len(a) == 2 + assert not a.empty() + assert 0 in a + assert 1 not in a + assert a.letters() == [0, 2] + assert a.index(2) == 1 + assert a.letter(0) == 0 + assert alphabet.first_unused_letter(a) == 1 + assert alphabet.validate(a) is None + + with pytest.raises(LibsemigroupsError): + Alphabet([0, 0]) + + +def test_ambiguous_constructors(): + with pytest.raises(TypeError): + Alphabet() + + assert len(Alphabet(word=str)) == 0 + assert len(Alphabet(word=list[int])) == 0 + assert Alphabet(3, word=str).letters() == "abc" + assert Alphabet(3, word=list[int]).letters() == [0, 1, 2] + + with pytest.raises(TypeError): + Alphabet(3) + with pytest.raises(ValueError): + Alphabet(word=tuple) + + +def test_add_letter(): + a = Alphabet("abc") + + with pytest.raises(LibsemigroupsError): + a.add_letter("a") + with pytest.raises(TypeError): + a.add_letter(10) + assert a.add_letter("e") is a + + a = Alphabet([0, 3]) + + with pytest.raises(LibsemigroupsError): + a.add_letter(0) + with pytest.raises(TypeError): + a.add_letter("a") + assert a.add_letter(1) is a + + +def test_contains(): + a = Alphabet("abc") + + assert "a" in a + assert a.contains("a") + + with pytest.raises(TypeError): + a.contains(0) + + a = Alphabet([0, 1, 2]) + + assert 1 in a + assert a.contains(1) + + with pytest.raises(TypeError): + a.contains("a") + + +def test_empty(): + a = Alphabet("abc") + assert not a.empty() + a.init() + assert a.empty() + + a = Alphabet(3, word=list[int]) + assert not a.empty() + a.init() + assert a.empty() + + +def test_iter(): + a = Alphabet("abc") + assert list(a) == list(a.letters()) + + a = Alphabet([0, 1, 11]) + assert list(a) == a.letters() + + +def test_index(): + a = Alphabet("abc") + assert [a.index(x) for x in a] == [0, 1, 2] + + with pytest.raises(LibsemigroupsError): + a.index("d") + with pytest.raises(TypeError): + a.index(0) + + a = Alphabet([11, 0, 1]) + assert [a.index(x) for x in a] == [0, 1, 2] + + with pytest.raises(LibsemigroupsError): + a.index(2) + with pytest.raises(TypeError): + a.index("a") + + +def test_copy(): + a = Alphabet("abc") + b = a.copy() + + assert b == a + assert b is not a + b.add_letter("d") + assert b != a + assert a.letters() == "abc" + assert b.letters() == "abcd" + + a = Alphabet([0, 2]) + b = a.copy() + + assert b == a + assert b is not a + b.add_letter(1) + assert b != a + assert a.letters() == [0, 2] + assert b.letters() == [0, 2, 1] + + +def test_copy_constructor(): + a = Alphabet("abc") + b = a.copy() + + assert b == a + assert b is not a + assert b.letters() == "abc" + + a = Alphabet([0, 2]) + b = a.copy() + + assert b == a + assert b is not a + assert b.letters() == [0, 2] + + +def test_repr_and_str(): + assert repr(Alphabet("abc")) == '' + assert str(Alphabet("abc")) == 'Alphabet("abc")' + assert repr(Alphabet([0, 1, 2])) == "" + assert str(Alphabet([0, 1, 2])) == "Alphabet([0, 1, 2])" + + +def test_equality(): + assert Alphabet("abc") == Alphabet("abc") + assert Alphabet("abc") != Alphabet("acb") + assert Alphabet([0, 1, 2]) == Alphabet([0, 1, 2]) + assert Alphabet([0, 1, 2]) != Alphabet([0, 2, 1]) + + +def test_init_from_letters(): + a = Alphabet("abc") + + assert a.init("de") is a + assert a.letters() == "de" + with pytest.raises(LibsemigroupsError): + a.init("dd") + with pytest.raises(TypeError): + a.init([0, 1]) + + a = Alphabet([0, 1]) + + assert a.init([3, 2]) is a + assert a.letters() == [3, 2] + with pytest.raises(LibsemigroupsError): + a.init([3, 3]) + with pytest.raises(TypeError): + a.init("ab") + + +def test_init_from_size(): + a = Alphabet("abc") + + assert a.init(2) is a + assert a.letters() == "ab" + + a = Alphabet([10, 11]) + + assert a.init(3) is a + assert a.letters() == [0, 1, 2] + + +def test_letter(): + a = Alphabet("abc") + + assert [a.letter(i) for i in range(len(a))] == ["a", "b", "c"] + with pytest.raises(LibsemigroupsError): + a.letter(3) + with pytest.raises(TypeError): + a.letter("a") + + a = Alphabet([11, 0, 1]) + + assert [a.letter(i) for i in range(len(a))] == [11, 0, 1] + with pytest.raises(LibsemigroupsError): + a.letter(3) + with pytest.raises(TypeError): + a.letter("a") + + +def test_letters_after_mutation(): + a = Alphabet("ab") + + a.add_letter("c") + assert a.letters() == "abc" + a.remove_letter("b") + assert a.letters() == "ac" + + a = Alphabet([0, 1]) + + a.add_letter(3) + assert a.letters() == [0, 1, 3] + a.remove_letter(1) + assert a.letters() == [0, 3] + + +def test_remove_letter(): + a = Alphabet("abc") + + assert a.remove_letter("b") is a + assert a.letters() == "ac" + with pytest.raises(LibsemigroupsError): + a.remove_letter("b") + with pytest.raises(TypeError): + a.remove_letter(0) + + a = Alphabet([0, 1, 2]) + + assert a.remove_letter(1) is a + assert a.letters() == [0, 2] + with pytest.raises(LibsemigroupsError): + a.remove_letter(1) + with pytest.raises(TypeError): + a.remove_letter("a") + + +def test_throw_if_duplicate_letters(): + assert Alphabet("abc").throw_if_duplicate_letters() is None + assert Alphabet([0, 1, 2]).throw_if_duplicate_letters() is None + + +def test_throw_if_letter_not_in_alphabet(): + a = Alphabet("abc") + + assert a.throw_if_letter_not_in_alphabet("a") is None + with pytest.raises(LibsemigroupsError): + a.throw_if_letter_not_in_alphabet("d") + with pytest.raises(TypeError): + a.throw_if_letter_not_in_alphabet(0) + + a = Alphabet([0, 1, 2]) + + assert a.throw_if_letter_not_in_alphabet(1) is None + with pytest.raises(LibsemigroupsError): + a.throw_if_letter_not_in_alphabet(3) + with pytest.raises(TypeError): + a.throw_if_letter_not_in_alphabet("a") + + +def test_validate(): + assert alphabet.validate(Alphabet("abc")) is None + assert alphabet.validate(Alphabet([0, 1, 2])) is None + with pytest.raises(TypeError): + alphabet.validate("abc") + + +def test_to_alphabet(): + a = Alphabet("abc") + assert a.letters() == "abc" + + b = to(a, rtype=(Alphabet, str)) + assert a == b + + # assert b is a + + c = to(a, rtype=(Alphabet, list[int])) + assert c.letters() == [0, 1, 2] + + assert to(c, rtype=(Alphabet, str)) == a diff --git a/tests/test_cong.py b/tests/test_cong.py index ac3bafc3..ea322083 100644 --- a/tests/test_cong.py +++ b/tests/test_cong.py @@ -19,7 +19,6 @@ KnuthBendix, LibsemigroupsError, Presentation, - ReportGuard, StringRange, ToddCoxeter, congruence, @@ -33,7 +32,6 @@ def test_018(): - ReportGuard(False) p = Presentation([0, 1, 2]) presentation.add_rule(p, [0, 0], [0, 0]) presentation.add_rule(p, [0, 1], [1, 0]) diff --git a/tests/test_froidure_pin.py b/tests/test_froidure_pin.py index f0729347..61e45745 100644 --- a/tests/test_froidure_pin.py +++ b/tests/test_froidure_pin.py @@ -27,7 +27,6 @@ Perm, PPerm, Presentation, - ReportGuard, Transf, congruence_kind, froidure_pin, @@ -39,7 +38,6 @@ def check_constructors(coll): - ReportGuard(False) # default constructor S = FroidurePin([coll[0]]) S.add_generators(coll[1:]) @@ -52,7 +50,6 @@ def check_constructors(coll): def check_generators(coll): - ReportGuard(False) S = FroidurePin([coll[0]]) S.add_generators(coll[1:]) for i, x in enumerate(coll): @@ -82,15 +79,12 @@ def check_generators(coll): def check_settings(S): - ReportGuard(False) assert S.batch_size() == 8192 S.batch_size(S.batch_size()) S.reserve(100) def check_mem_compare(S): - ReportGuard(False) - with pytest.raises(RuntimeError): froidure_pin.current_position(S, [0, 0, 0, 0, 0, 0, 0, S.number_of_generators(), 1]) with pytest.raises(RuntimeError): @@ -122,7 +116,6 @@ def check_mem_compare(S): def check_accessors(S): - ReportGuard(False) # current_size assert S.current_size() == S.number_of_generators() S.run() @@ -138,16 +131,12 @@ def check_accessors(S): def check_attributes(S): - ReportGuard(False) - S.contains_one() assert S.is_finite() S.degree() # just check it doesn't throw def check_idempotents(S): - ReportGuard(False) - # Suppress TypeError in case no multiplication is provided with contextlib.suppress(TypeError): assert all(x * x == x for x in S.idempotents()) @@ -160,8 +149,6 @@ def check_idempotents(S): def check_cayley_graphs(S): - ReportGuard(False) - gen_names = "abcdefghijklmnopqrstuvwxyz"[: S.number_of_generators()] d = froidure_pin.dot_current_right_cayley_graph(S) @@ -208,8 +195,6 @@ def check_cayley_graphs(S): def check_factor_prod_rels(S): - ReportGuard(False) - # current_length for i in range(S.number_of_generators()): assert S.current_length(i) == 1 @@ -245,7 +230,6 @@ def check_factor_prod_rels(S): def check_prefix_suffix(S): - ReportGuard(False) S.run() for i in range(S.number_of_generators(), S.size()): @@ -254,7 +238,6 @@ def check_prefix_suffix(S): def check_froidure_pin_transf1(T): - ReportGuard(False) S = FroidurePin(T([1, 7, 2, 6, 0, 4, 1, 5])) S.add_generator(T([2, 4, 6, 1, 4, 5, 2, 7])) @@ -364,7 +347,6 @@ def test_runner_pperm(): def test_froidure_pin_perm(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Perm([1, 0] + list(range(2, 4))), Perm(list(range(1, 4)) + [0])] assert FroidurePin(gens).size() == 24 @@ -382,7 +364,6 @@ def test_runner_perm(): def test_froidure_pin_bipart(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) T = Bipartition gens = [T([0, 1, 1, 0]), T([0, 1, 2, 1]), T([0, 0, 0, 0])] assert FroidurePin(gens).size() == 15 @@ -395,7 +376,6 @@ def test_froidure_pin_bipart(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_pbr(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) T = PBR gens = [T([[], [0]]), T([[0, 1], [0]]), T([[1], []]), T([[1], [0, 1]])] assert FroidurePin(gens).size() == 15 @@ -408,7 +388,6 @@ def test_froidure_pin_pbr(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_bmat(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [ Matrix(MatrixKind.Boolean, [[0, 1], [1, 0]]), Matrix(MatrixKind.Boolean, [[1, 0], [1, 1]]), @@ -424,7 +403,6 @@ def test_froidure_pin_bmat(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_bmat8(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [BMat8([[0, 1], [1, 0]]), BMat8([[1, 0], [1, 1]]), BMat8([[1, 0], [0, 0]])] assert FroidurePin(gens).size() == 16 @@ -436,7 +414,6 @@ def test_froidure_pin_bmat8(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_int_mat(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Matrix(MatrixKind.Integer, [[0, -3], [-2, -10]])] S = FroidurePin(gens) # This example is probably infinite really, here we are using 64 bit @@ -451,7 +428,6 @@ def test_froidure_pin_int_mat(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_max_plus(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Matrix(MatrixKind.MaxPlus, [[0, -3], [-2, -10]])] assert FroidurePin(gens).size() == 2 @@ -463,7 +439,6 @@ def test_froidure_pin_max_plus(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_min_plus(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) x = Matrix(MatrixKind.MinPlus, 2, 2) gens = [Matrix(MatrixKind.MinPlus, [[1, 0], [0, x.scalar_zero()]])] assert FroidurePin(gens).size() == 3 @@ -476,7 +451,6 @@ def test_froidure_pin_min_plus(checks_for_froidure_pin, checks_for_generators): def test_froidure_pin_proj_max_plus(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) x = Matrix(MatrixKind.ProjMaxPlus, 2, 2) gens = [Matrix(MatrixKind.ProjMaxPlus, [[1, 0], [0, x.scalar_zero()]])] assert FroidurePin(gens).size() == 2 @@ -489,7 +463,6 @@ def test_froidure_pin_proj_max_plus(checks_for_froidure_pin, checks_for_generato def test_froidure_pin_max_plus_trunc(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Matrix(MatrixKind.MaxPlusTrunc, 11, [[1, 0], [0, 1]])] assert FroidurePin(gens).size() == 12 @@ -501,7 +474,6 @@ def test_froidure_pin_max_plus_trunc(checks_for_froidure_pin, checks_for_generat def test_froidure_pin_min_plus_trunc(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Matrix(MatrixKind.MinPlusTrunc, 11, [[1, 0], [0, 1]])] assert FroidurePin(gens).size() == 2 @@ -513,7 +485,6 @@ def test_froidure_pin_min_plus_trunc(checks_for_froidure_pin, checks_for_generat def test_froidure_pin_ntp(checks_for_froidure_pin, checks_for_generators): - ReportGuard(False) gens = [Matrix(MatrixKind.NTP, 5, 7, [[1, 1], [1, 1]])] assert FroidurePin(gens).size() == 6 diff --git a/tests/test_kambites.py b/tests/test_kambites.py index af7cac71..d8fb9216 100644 --- a/tests/test_kambites.py +++ b/tests/test_kambites.py @@ -12,7 +12,6 @@ POSITIVE_INFINITY, Kambites, Presentation, - ReportGuard, StringRange, congruence_kind, is_obviously_infinite, @@ -243,7 +242,6 @@ def test_case_006_e(): def test_case_008(): - ReportGuard(False) p = Presentation("abcdefg") presentation.add_rule(p, "abcd", "ce") @@ -275,7 +273,6 @@ def test_case_008(): def test_case_010(): - ReportGuard(False) p = Presentation("cab") presentation.add_rule(p, "aabc", "acba") diff --git a/tests/test_knuth_bendix.py b/tests/test_knuth_bendix.py index 505dc499..0adef14b 100644 --- a/tests/test_knuth_bendix.py +++ b/tests/test_knuth_bendix.py @@ -20,7 +20,6 @@ LibsemigroupsError, Order, Presentation, - ReportGuard, StringRange, congruence_kind, is_obviously_infinite, @@ -39,7 +38,6 @@ def check_initialisation(*args): def test_initialisation(): - ReportGuard(False) kinds = [congruence_kind.twosided, congruence_kind.onesided] p = Presentation("ba") @@ -68,7 +66,6 @@ def test_initialisation(): def test_attributes(): - ReportGuard(False) p = Presentation("abBe") presentation.add_identity_rules(p, "e") presentation.add_inverse_rules(p, "aBbe", "e") @@ -104,7 +101,6 @@ def test_attributes(): def test_operators(): - ReportGuard(False) p = Presentation("abBe") presentation.add_identity_rules(p, "e") presentation.add_inverse_rules(p, "aBbe", "e") @@ -133,8 +129,6 @@ def test_operators(): def test_running_state(): - ReportGuard(False) - p = Presentation("abce") presentation.add_identity_rules(p, "e") presentation.add_rule(p, "aa", "e") diff --git a/tests/test_konieczny.py b/tests/test_konieczny.py index 154c8720..c90c0885 100644 --- a/tests/test_konieczny.py +++ b/tests/test_konieczny.py @@ -20,7 +20,6 @@ Matrix, MatrixKind, PPerm, - ReportGuard, Transf, ) @@ -39,7 +38,6 @@ def BMat(x): def test_case_031(): """transformations""" - ReportGuard(False) k = Konieczny([Transf([1, 0, 2, 3, 4]), Transf([1, 2, 3, 4, 0]), Transf([0, 0, 2, 3, 4])]) assert k.size() == 3125 @@ -56,7 +54,7 @@ def test_case_031(): def test_case_032(): """transformations - JDM favourite example""" - ReportGuard(False) + S = Konieczny( [ Transf([1, 7, 2, 6, 0, 4, 1, 5]), @@ -77,7 +75,7 @@ def test_case_032(): def test_case_033(): """transformations - large example""" - ReportGuard(False) + gens = [ Transf([2, 1, 0, 4, 2, 1, 1, 8, 0]), Transf([1, 7, 6, 2, 5, 1, 1, 4, 3]), @@ -104,7 +102,6 @@ def test_case_033(): def test_case_034(): - ReportGuard(False) S = Konieczny( [ Transf([2, 1, 0, 4, 2, 1, 1, 8, 0]), @@ -120,7 +117,6 @@ def test_case_034(): def test_case_035(): """transformations - large example with run_until""" - ReportGuard(False) S = Konieczny( [ @@ -141,7 +137,7 @@ def test_case_035(): def test_case_038(): """transformations: contains""" - ReportGuard(False) + S = Konieczny([Transf([1, 0, 2, 3, 4]), Transf([1, 2, 3, 4, 0]), Transf([0, 0, 2, 3, 4])]) assert S.contains(Transf([1, 0, 2, 3, 4])) assert S.contains(Transf([1, 2, 3, 4, 0])) @@ -177,8 +173,6 @@ def test_case_039(): """transformations Hall monoid 5 (only the first couple of generators so that the test runs in short amount of time)""" - ReportGuard(False) - K = Konieczny( [ Transf( @@ -257,7 +251,6 @@ def test_case_039(): def test_case_040(): - ReportGuard(False) S = Konieczny( [ Transf([2, 1, 0, 4, 2, 1, 1, 8, 0]), @@ -275,7 +268,7 @@ def test_case_040(): def test_case_041(): """current_number_D_classes""" - ReportGuard(False) + S = Konieczny( [ Transf([2, 1, 0, 4, 2, 1, 1, 8, 0]), @@ -294,7 +287,6 @@ def test_case_041(): def check_case_000(Mat): - ReportGuard(False) gens = [ Mat([[0, 1, 0, 1], [1, 0, 0, 0], [0, 1, 1, 1], [0, 1, 1, 0]]), Mat([[0, 1, 1, 1], [1, 1, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1]]), @@ -310,7 +302,6 @@ def test_case_000(): def check_case_001(Mat): - ReportGuard(False) gens = [ Mat([[1, 0, 0, 0], [0, 0, 1, 0], [1, 0, 0, 1], [0, 1, 0, 0]]), Mat([[1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 1, 1], [0, 1, 1, 0]]), @@ -329,7 +320,6 @@ def test_case_001(): def check_case_003(Mat): - ReportGuard(False) gens = [ Mat([[0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [1, 0, 0, 1, 0], [1, 1, 1, 0, 0], [0, 1, 1, 1, 1]]), Mat([[0, 0, 0, 1, 0], [0, 0, 1, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 0, 1, 1]]), @@ -348,7 +338,7 @@ def test_case_003(): def test_case_028(): """partial perm""" - ReportGuard(False) + gens = [ PPerm([0, 2, 3, 7], [1, 6, 7, 3], 9), PPerm([0, 1, 2, 3, 4, 7], [6, 5, 8, 0, 2, 1], 9), @@ -370,7 +360,7 @@ def test_case_028(): def test_case_029(): """symmetric inverse monoid n = 8""" - ReportGuard(False) + S = Konieczny( [ PPerm([0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], 8), @@ -386,7 +376,7 @@ def test_case_029(): def test_konieczny_init(): """symmetric inverse monoid n = 7""" - ReportGuard(False) + S = Konieczny( [ PPerm([0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], 8), @@ -405,7 +395,6 @@ def test_konieczny_init(): def test_case_030(): """exceptions""" - ReportGuard(False) gens = [ PPerm([0, 2, 3, 7], [1, 6, 7, 3], 9), @@ -454,7 +443,6 @@ def test_konieczny_hpcombi_ptranf16(): def test_froidure_pin_max_plus_trunc(): - ReportGuard(False) K = Konieczny(Matrix(MatrixKind.MaxPlusTrunc, 11, [[1, 0], [0, 1]])) assert K.size() == 12 assert K.number_of_idempotents() == 1 diff --git a/tests/test_obvinf.py b/tests/test_obvinf.py index dedfe68a..4429e116 100644 --- a/tests/test_obvinf.py +++ b/tests/test_obvinf.py @@ -11,7 +11,6 @@ from libsemigroups_pybind11 import ( KnuthBendix, Presentation, - ReportGuard, congruence_kind, is_obviously_infinite, presentation, @@ -40,8 +39,6 @@ def test_is_obviously_infinite_presentation(): def test_is_obviously_infinite_knuth_bendix(): - ReportGuard(False) - p = Presentation("abABe") p.contains_empty_word(True) presentation.add_identity_rules(p, "e") diff --git a/tests/test_presentation_examples.py b/tests/test_presentation_examples.py index c9321190..eac08925 100644 --- a/tests/test_presentation_examples.py +++ b/tests/test_presentation_examples.py @@ -17,7 +17,6 @@ POSITIVE_INFINITY, LibsemigroupsError, Presentation, - ReportGuard, ToddCoxeter, congruence_kind, ) @@ -25,7 +24,6 @@ def check_symmetric_group(min_n, max_n, symmetric_group_implementation): - ReportGuard(False) with pytest.raises(RuntimeError): symmetric_group_implementation(min_n - 1) for i in range(min_n, max_n): @@ -36,7 +34,6 @@ def check_symmetric_group(min_n, max_n, symmetric_group_implementation): def check_full_transformation_monoid(ns, ftm_implementation): - ReportGuard(False) with pytest.raises(RuntimeError): ftm_implementation(ns[0] - 1) for n in ns: @@ -47,7 +44,6 @@ def check_full_transformation_monoid(ns, ftm_implementation): def check_symmetric_inverse_monoid(sim_implementation): - ReportGuard(False) n = 5 p = sim_implementation(n) p.throw_if_bad_alphabet_or_rules() @@ -63,8 +59,6 @@ def test_semigroup_status(): def test_monoid_status(): - ReportGuard(False) - assert examples.alternating_group_Moo97(5).contains_empty_word() assert examples.brauer_monoid_KM07(5).contains_empty_word() assert examples.catalan_monoid(5).contains_empty_word() @@ -136,7 +130,6 @@ def test_symmetric_group_Moo97_b(): def test_alternating_group_Moo97(): - ReportGuard(False) min_n = 4 max_n = 9 with pytest.raises(LibsemigroupsError): @@ -165,7 +158,6 @@ def test_full_transformation_monoid(): def test_catalan_monoid(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.catalan_monoid(0) @@ -178,7 +170,6 @@ def test_catalan_monoid(): def test_partial_transformation_monoid_Shu60(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.partial_transformation_monoid_Shu60(3) @@ -191,7 +182,6 @@ def test_partial_transformation_monoid_Shu60(): def test_partial_transformation_monoid_MW24(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.partial_transformation_monoid_MW24(1) @@ -216,7 +206,6 @@ def test_symmetric_inverse_monoid_MW24(): def test_dual_symmetric_inverse_monoid_EEF07(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.dual_symmetric_inverse_monoid_EEF07(2) @@ -227,7 +216,6 @@ def test_dual_symmetric_inverse_monoid_EEF07(): def test_uniform_block_bijection_monoid_Fit03(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.uniform_block_bijection_monoid_Fit03(2) @@ -237,7 +225,6 @@ def test_uniform_block_bijection_monoid_Fit03(): def test_partition_monoid_Eas11(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.partition_monoid_Eas11(3) @@ -247,7 +234,6 @@ def test_partition_monoid_Eas11(): def test_partition_monoid_HR05(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.partition_monoid_HR05(0) @@ -257,7 +243,6 @@ def test_partition_monoid_HR05(): def test_brauer_monoid_KM07(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.brauer_monoid_KM07(0) @@ -267,7 +252,6 @@ def test_brauer_monoid_KM07(): def test_rectangular_band_ACOR00(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.rectangular_band_ACOR00(1, 0) @@ -284,7 +268,6 @@ def test_rectangular_band_ACOR00(): def test_stellar_monoid_GH19(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.stellar_monoid_GH19(0) @@ -299,7 +282,6 @@ def test_stellar_monoid_GH19(): def test_chinese_monoid_CEKNH01(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.chinese_monoid_CEKNH01(0) @@ -315,7 +297,6 @@ def test_chinese_monoid_CEKNH01(): def test_monogenic_semigroup(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.monogenic_semigroup(4, 0) @@ -328,7 +309,6 @@ def test_monogenic_semigroup(): def test_plactic_monoid_Knu70(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.plactic_monoid_Knu70(0) @@ -343,7 +323,6 @@ def test_plactic_monoid_Knu70(): def test_stylic_monoid_AR22(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.stylic_monoid_AR22(0) @@ -359,7 +338,6 @@ def test_stylic_monoid_AR22(): def test_fibonacci_semigroup_CRRT94(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.fibonacci_semigroup_CRRT94(0, 1) @@ -375,7 +353,6 @@ def test_fibonacci_semigroup_CRRT94(): def test_temperley_lieb_monoid_Eas21(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.temperley_lieb_monoid_Eas21(0) @@ -391,7 +368,6 @@ def test_temperley_lieb_monoid_Eas21(): def test_singular_brauer_monoid_MM07(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.singular_brauer_monoid_MM07(0) @@ -407,7 +383,6 @@ def test_singular_brauer_monoid_MM07(): def test_orientation_preserving_monoid_AR00(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.orientation_preserving_monoid_AR00(0) @@ -423,7 +398,6 @@ def test_orientation_preserving_monoid_AR00(): def test_orientation_preserving_reversing_monoid_AR00(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.orientation_preserving_reversing_monoid_AR00(0) @@ -439,7 +413,6 @@ def test_orientation_preserving_reversing_monoid_AR00(): def test_abacus_jones(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.abacus_jones_monoid(0, 1) with pytest.raises(LibsemigroupsError): @@ -461,7 +434,6 @@ def test_abacus_jones(): def test_braid_group(): - ReportGuard(False) with pytest.raises(LibsemigroupsError): examples.braid_group(0) with pytest.raises(LibsemigroupsError): diff --git a/tests/test_schreier_sims.py b/tests/test_schreier_sims.py index a6e943e9..1563551b 100644 --- a/tests/test_schreier_sims.py +++ b/tests/test_schreier_sims.py @@ -16,12 +16,11 @@ import pytest -from libsemigroups_pybind11 import LibsemigroupsError, Perm, ReportGuard, SchreierSims +from libsemigroups_pybind11 import LibsemigroupsError, Perm, SchreierSims from libsemigroups_pybind11.schreier_sims import intersection def check_constructors(gens): - ReportGuard(False) # default constructor with pytest.raises(TypeError): SchreierSims() @@ -38,7 +37,6 @@ def check_constructors(gens): def check_generators(gens): - ReportGuard(False) S = SchreierSims(gens) for i, gen in enumerate(gens): assert S.generator(i) == gen @@ -56,7 +54,6 @@ def check_generators(gens): def check_empty(gens): - ReportGuard(False) S = SchreierSims(gens) assert not S.empty() S.init() @@ -64,7 +61,6 @@ def check_empty(gens): def check_finished(gens): - ReportGuard(False) S = SchreierSims(gens) assert not S.finished() S.run() @@ -78,7 +74,6 @@ def check_one(n): def check_elements(n): - ReportGuard(False) S = SchreierSims([Perm(range(n))]) S.add_base_point(0) @@ -329,7 +324,6 @@ def check_elements(n): def check_sift(gens): - ReportGuard(False) S = SchreierSims(gens) S.run() for i, gen in enumerate(gens): @@ -338,7 +332,6 @@ def check_sift(gens): def check_sift_inplace(gens): - ReportGuard(False) S = SchreierSims(gens) one = S.one() S.run() @@ -348,7 +341,6 @@ def check_sift_inplace(gens): def check_intersection(n): - ReportGuard(False) gens_S = [ Perm([1, 3, 7, 5, 2, 0, 4, 6] + list(range(8, n))), Perm([2, 4, 3, 6, 5, 7, 0, 1] + list(range(8, n))), @@ -370,7 +362,6 @@ def check_intersection(n): def check_SchreierSims_001(n): - ReportGuard(False) S = SchreierSims([Perm(range(n))]) S.init() assert S.size() == 1 diff --git a/tests/test_sims.py b/tests/test_sims.py index 6344ebf9..e8b36623 100644 --- a/tests/test_sims.py +++ b/tests/test_sims.py @@ -22,7 +22,6 @@ Order, Presentation, RepOrc, - ReportGuard, Sims1, Sims2, SimsRefinerFaithful, @@ -77,7 +76,6 @@ def check_meets_and_joins(_): @pytest.mark.quick def test_sims1_000(): """fp example 1""" - ReportGuard(False) p = Presentation([0, 1]) p.contains_empty_word(True) @@ -144,7 +142,7 @@ def test_sims1_000(): @pytest.mark.quick def test_sims1_001(): """fp example 2""" - ReportGuard(False) + p = Presentation([0, 1, 2]) p.contains_empty_word(True) @@ -186,7 +184,7 @@ def test_sims1_001(): @pytest.mark.quick def test_sims1_002(): """ToddCoxeter failing example (word_type)""" - ReportGuard(False) + p = Presentation([0, 1, 2, 3, 4, 5, 6]) p.contains_empty_word(False) @@ -272,7 +270,7 @@ def test_sims1_002(): @pytest.mark.quick def test_sims1_003(): """ToddCoxeter failing example (std::string)""" - ReportGuard(False) + p = Presentation("aAbBcCe") p.contains_empty_word(False) @@ -290,7 +288,7 @@ def test_sims1_003(): @pytest.mark.quick def test_sims1_004(): """partition_monoid(2) right""" - ReportGuard(False) + p = Presentation([0, 1, 2, 3]) p.contains_empty_word(False) @@ -336,7 +334,6 @@ def test_sims1_004(): @pytest.mark.quick def test_sims_refiner_faithful_128(): - ReportGuard(True) p = Presentation([0, 1]) p.contains_empty_word(True) presentation.add_rule(p, [0, 0, 0], [0]) @@ -364,7 +361,6 @@ def test_sims_refiner_faithful_128(): def test_sims1_901(): - ReportGuard(False) p = Presentation(list(range(4))) presentation.add_rule(p, [1, 2, 1], [1, 1]) presentation.add_rule(p, [3, 3], [1, 1]) @@ -381,7 +377,6 @@ def test_sims1_901(): def test_sims1_902(): - ReportGuard(False) p = Presentation("abcd") presentation.add_rule(p, "bcb", "bb") presentation.add_rule(p, "dd", "bb") @@ -398,7 +393,6 @@ def test_sims1_902(): def test_sims2_901(): - ReportGuard(False) p = Presentation([0, 1]) presentation.add_rule(p, [0, 1], [1, 0]) @@ -422,7 +416,6 @@ def test_sims2_901(): def test_sims2_902(): - ReportGuard(False) p = Presentation("ab") presentation.add_rule(p, "ab", "ba") diff --git a/tests/test_stephen.py b/tests/test_stephen.py index 5a76dd45..ae6d4cba 100644 --- a/tests/test_stephen.py +++ b/tests/test_stephen.py @@ -21,7 +21,6 @@ InversePresentation, LibsemigroupsError, Presentation, - ReportGuard, Stephen, ToddCoxeter, ToWord, @@ -110,7 +109,7 @@ def verify_c4_not_equal_to(p, word1, word2): @pytest.mark.quick def test_stephen_000(): """basic test 1""" - ReportGuard(False) + p = Presentation([0, 1]) presentation.add_rule(p, [0], [0, 1]) s = Stephen(p) @@ -122,7 +121,7 @@ def test_stephen_000(): @pytest.mark.quick def test_stephen_001(): """basic test 2""" - ReportGuard(False) + p = Presentation([0, 1]) presentation.add_rule(p, [0, 0, 0], [0]) presentation.add_rule(p, [1, 1, 1], [1]) @@ -188,7 +187,7 @@ def test_stephen_001(): @pytest.mark.quick def test_stephen_002(): """full transf monoid""" - ReportGuard(False) + n = 5 p = examples.full_transformation_monoid_II74(n) @@ -325,7 +324,7 @@ def test_stephen_002(): @pytest.mark.quick def test_stephen_003(): """from step_hen 002""" - ReportGuard(False) + to_word = ToWord("ab") p = Presentation(to_word("ab")) presentation.add_rule(p, to_word("aaa"), to_word("a")) @@ -354,7 +353,7 @@ def test_stephen_003(): @pytest.mark.quick def test_stephen_003_str(): """from step_hen 002""" - ReportGuard(False) + p = Presentation("ab") presentation.add_rule(p, "aaa", "a") presentation.add_rule(p, "bbb", "b") @@ -382,7 +381,7 @@ def test_stephen_003_str(): @pytest.mark.quick def test_stephen_004(): """from step_hen 003""" - ReportGuard(False) + to_word = ToWord("abcdefg") p = Presentation(to_word("abcdefg")) presentation.add_rule(p, to_word("aaaeaa"), to_word("abcd")) @@ -447,7 +446,7 @@ def test_stephen_004(): @pytest.mark.quick def test_stephen_005(): """from step_hen 004""" - ReportGuard(False) + to_word = ToWord("abc") p = Presentation(to_word("abc")) presentation.add_rule(p, to_word("ab"), to_word("ba")) @@ -482,7 +481,7 @@ def test_stephen_005(): @pytest.mark.quick def test_stephen_005_str(): """from step_hen 004""" - ReportGuard(False) + p = Presentation("abc") presentation.add_rule(p, "ab", "ba") presentation.add_rule(p, "ac", "cc") @@ -516,7 +515,7 @@ def test_stephen_005_str(): @pytest.mark.quick def test_stephen_006(): """from step_hen 005""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("bb"), to_word("c")) @@ -543,7 +542,7 @@ def test_stephen_006(): # def test_stephen_007(): # """Fibonacci(4, 6)""" # # [stephen][extreme]") { -# ReportGuard(False); + # S = Stephen(examples.fibonacci_semigroup(4, 6)) # S.set_word([0, 1, 2, 3]).run_for(timedelta(seconds=10)) # assert not S.finished() @@ -552,7 +551,7 @@ def test_stephen_006(): @pytest.mark.quick def test_stephen_008(): """C(4) monoid normal form (test_case_knuth_bendix_055)""" - ReportGuard(False) + to_word = ToWord("abcdefg") p = Presentation(to_word("abcdefg")) presentation.add_rule(p, to_word("abcd"), to_word("ce")) @@ -614,7 +613,7 @@ def test_stephen_008(): def test_Stephen_009(): """C(4) monoid normal form (test_case_gap_smalloverlap_85)""" # [stephen][quick]") { - ReportGuard(False) + to_word = ToWord("abc") p = Presentation(to_word("cab")) presentation.add_rule(p, to_word("aabc"), to_word("acba")) @@ -639,7 +638,7 @@ def test_Stephen_009(): @pytest.mark.quick def test_stephen_010(): """code coverage""" - ReportGuard(False) + to_word = ToWord("abcdefg") p = Presentation([]) # TODO(2): Once we have make check that this error is thrown @@ -683,7 +682,7 @@ def test_stephen_010(): @pytest.mark.quick def test_Stephen_011(): """C(4) monoid normal form (test_case_gap_smalloverlap_49)""" - ReportGuard(False) + to_word = ToWord("abcdefgh") p = Presentation(to_word("abcdefgh")) @@ -704,7 +703,7 @@ def test_Stephen_011(): @pytest.mark.quick def test_Stephen_012(): """C(4) monoid normal form (test_case_gap_smalloverlap_63)""" - ReportGuard(False) + to_word = ToWord("abcdefgh") p = Presentation(to_word("abcdefgh")) @@ -718,7 +717,7 @@ def test_Stephen_012(): @pytest.mark.quick def test_Stephen_013(): """C(4) monoid equal to (test_case_gap_smalloverlap_70)""" - ReportGuard(False) + to_word = ToWord("abcdefghij") p = Presentation(to_word("abcdefghij")) @@ -733,7 +732,7 @@ def test_Stephen_013(): @pytest.mark.quick def test_stephen_014(): """C(4) monoid normal form (test_case_ex_3_13_14)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abbba"), to_word("cdc")) @@ -748,7 +747,7 @@ def test_stephen_014(): @pytest.mark.quick def test_stephen_015(): """C(4) monoid normal form (test_case_ex_3_15)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("aabc"), to_word("acba")) @@ -769,7 +768,7 @@ def test_stephen_015(): @pytest.mark.quick def test_stephen_016(): """C(4) monoid normal form (test_case_ex_3_16)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abcd"), to_word("acca")) @@ -786,7 +785,7 @@ def test_stephen_016(): @pytest.mark.quick def test_stephen_017(): """C(4) monoid normal form (test_case_mt_3)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abcd"), to_word("accca")) @@ -798,7 +797,7 @@ def test_stephen_017(): @pytest.mark.quick def test_stephen_018(): """C(4) monoid normal form (test_case_mt_5)""" - ReportGuard(False) + to_word = ToWord("abc") p = Presentation(to_word("abc")) presentation.add_rule(p, to_word("ac"), to_word("cbbbbc")) @@ -810,7 +809,7 @@ def test_stephen_018(): @pytest.mark.quick def test_stephen_019(): """C(4) monoid normal form (test_case_mt_6)""" - ReportGuard(False) + to_word = ToWord("abc") p = Presentation(to_word("abc")) presentation.add_rule(p, to_word("ccab"), to_word("cbac")) @@ -824,7 +823,7 @@ def test_stephen_019(): @pytest.mark.quick def test_stephen_020(): """C(4) monoid normal form (test_case_mt_10)""" - ReportGuard(False) + to_word = ToWord("abcdefghij") p = Presentation(to_word("abcdefghij")) presentation.add_rule(p, to_word("afh"), to_word("bgh")) @@ -838,7 +837,7 @@ def test_stephen_020(): @pytest.mark.quick def test_stephen_021(): """C(4) monoid normal form (test_case_mt_13)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abcd"), to_word("dcba")) @@ -850,7 +849,7 @@ def test_stephen_021(): @pytest.mark.quick def test_stephen_022(): """C(4) monoid normal form (test_case_mt_14)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abca"), to_word("dcbd")) @@ -862,7 +861,7 @@ def test_stephen_022(): @pytest.mark.quick def test_stephen_023(): """C(4) monoid normal form (test_case_mt_15)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("abcd"), to_word("dcba")) @@ -875,7 +874,7 @@ def test_stephen_023(): @pytest.mark.quick def test_stephen_024(): """C(4) monoid normal form (test_case_mt_16)""" - ReportGuard(False) + to_word = ToWord("abcdefg") p = Presentation(to_word("abcdefg")) presentation.add_rule(p, to_word("abcd"), to_word("acca")) @@ -888,7 +887,7 @@ def test_stephen_024(): @pytest.mark.quick def test_stephen_025(): """C(4) monoid normal form (test_case_mt_17)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("ababbabbbabbbb"), to_word("abbbbbabbbbbbabbbbbbbabbbbbbbb")) @@ -905,7 +904,7 @@ def test_stephen_025(): @pytest.mark.quick def test_stephen_026(): """C(4) monoid normal form (test_case_weak_1)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("acba"), to_word("aabc")) @@ -924,7 +923,7 @@ def test_stephen_026(): @pytest.mark.quick def test_stephen_027(): """C(4) monoid normal form (test_case_weak_2)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("acba"), to_word("aabc")) @@ -938,7 +937,7 @@ def test_stephen_027(): @pytest.mark.quick def test_stephen_028(): """C(4) monoid normal form (test_case_weak_3)""" - ReportGuard(False) + to_word = ToWord("abcde") p = Presentation(to_word("abcde")) presentation.add_rule(p, to_word("bceac"), to_word("aeebbc")) @@ -950,7 +949,7 @@ def test_stephen_028(): @pytest.mark.quick def test_stephen_029(): """C(4) monoid normal form (test_case_weak_4)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("acba"), to_word("aabc")) @@ -963,7 +962,7 @@ def test_stephen_029(): @pytest.mark.quick def test_stephen_030(): """C(4) monoid normal form (test_case_weak_5)""" - ReportGuard(False) + to_word = ToWord("abcd") p = Presentation(to_word("abcd")) presentation.add_rule(p, to_word("acba"), to_word("aabc")) @@ -975,7 +974,7 @@ def test_stephen_030(): @pytest.mark.quick def test_stephen_031(): """Test behaviour when uninitialised""" - ReportGuard(False) + p = Presentation([]) with pytest.raises(LibsemigroupsError): @@ -1012,7 +1011,7 @@ def test_stephen_031(): @pytest.mark.quick def test_Stephen_034(): """(inverse) step_hen test_schutzenbergergraph 001 (string)""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) @@ -1037,7 +1036,7 @@ def test_Stephen_034(): @pytest.mark.quick def test_Stephen_035(): """(inverse) step_hen test_schutzenbergergraph 001""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) p.inverses(to_word("ABCabc")) @@ -1062,7 +1061,7 @@ def test_Stephen_035(): @pytest.mark.quick def test_Stephen_036(): """(inverse) step_hen test_schutzenbergergraph 002""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) p.inverses(to_word("ABCabc")) @@ -1078,7 +1077,7 @@ def test_Stephen_036(): @pytest.mark.quick def test_Stephen_037(): """(inverse) step_hen test_schutzenbergergraph 003""" - ReportGuard(False) + to_word = ToWord("xyXY") p = InversePresentation(to_word("xyXY")) p.inverses(to_word("XYxy")) @@ -1095,7 +1094,7 @@ def test_Stephen_037(): @pytest.mark.quick def test_Stephen_038(): """(inverse) step_hen test_schutzenbergergraph 004""" - ReportGuard(False) + to_word = ToWord("xyXY") p = InversePresentation(to_word("xyXY")) p.inverses(to_word("XYxy")) @@ -1132,7 +1131,7 @@ def test_Stephen_038(): @pytest.mark.quick def test_Stephen_039(): """(inverse) step_hen test_schutzenbergergraph 005""" - ReportGuard(False) + to_word = ToWord("xyXY") p = InversePresentation(to_word("xyXY")) p.inverses(to_word("XYxy")) @@ -1150,7 +1149,7 @@ def test_Stephen_039(): @pytest.mark.quick def test_Stephen_040(): """(inverse) step_hen test_schutzenbergergraph 006""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) p.inverses(to_word("ABCabc")) @@ -1179,7 +1178,7 @@ def test_Stephen_040(): @pytest.mark.quick def test_stephen_041(): """corner case""" - ReportGuard(False) + to_word = ToWord("x") p = Presentation([]) @@ -1199,7 +1198,7 @@ def test_stephen_041(): @pytest.mark.quick def test_stephen_042(): """empty word""" - ReportGuard(False) + p = examples.symmetric_inverse_monoid(4) assert p.contains_empty_word() assert len(p.alphabet()) == 4 @@ -1220,7 +1219,7 @@ def test_stephen_042(): @pytest.mark.quick def test_stephen_043(): """shared_ptr""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) p.inverses(to_word("ABCabc")) @@ -1249,7 +1248,7 @@ def test_stephen_043(): @pytest.mark.quick def test_stephen_044(): """inverse presentation -- operator==""" - ReportGuard(False) + tc = ToddCoxeter(word=list[int]) p = examples.symmetric_inverse_monoid(4) @@ -1277,7 +1276,7 @@ def test_stephen_044(): @pytest.mark.quick def test_stephen_046(): """non-inverse presentation -- operator==""" - ReportGuard(False) + p = examples.symmetric_inverse_monoid(4) tc = ToddCoxeter(congruence_kind.twosided, p) @@ -1299,7 +1298,7 @@ def test_stephen_046(): @pytest.mark.quick def test_stephen_032(): """Plactic monoid""" - ReportGuard(False) + p = examples.plactic_monoid(4) p.contains_empty_word(True) s = Stephen(p) @@ -1311,7 +1310,7 @@ def test_stephen_032(): # @pytest.mark.fail # def test_stephen_033(): # """Whyte's 4-relation full transf monoid 8""" -# rg = ReportGuard(True); + # p = Presentation([]) # p.rules = [ # [0, 0], @@ -1443,7 +1442,7 @@ def test_stephen_032(): @pytest.mark.quick def test_stephen_045(): """Munn tree products""" - ReportGuard(False) + to_word = ToWord("abcABC") p = InversePresentation(to_word("abcABC")) @@ -1488,7 +1487,7 @@ def test_stephen_045(): @pytest.mark.quick def test_stephen_048(): """chinese monoid""" - ReportGuard(False) + p = examples.chinese_monoid(3) S = Stephen(p) @@ -1500,7 +1499,7 @@ def test_stephen_048(): @pytest.mark.quick def test_stephen_049(): """to_human_readable_repr""" - ReportGuard(False) + p = Presentation([0, 1]) p.contains_empty_word(True) presentation.add_rule(p, [0, 0, 0], [1, 1]) @@ -1572,7 +1571,6 @@ def test_stephen_049(): @pytest.mark.quick def test_stephen_051(): """Incomplete Munn tree products""" - ReportGuard(False) p = InversePresentation("abcABC") p.inverses("ABCabc") @@ -1602,8 +1600,6 @@ def test_stephen_051(): @pytest.mark.quick def test_stephen_return_policy(): - ReportGuard(False) - p = InversePresentation("abcABC") p.inverses("ABCabc") diff --git a/tests/test_to.py b/tests/test_to.py index 8fd2d966..ba9f1ad1 100644 --- a/tests/test_to.py +++ b/tests/test_to.py @@ -37,7 +37,6 @@ KnuthBendix, Order, Presentation, - ReportGuard, Stephen, ToddCoxeter, Transf, @@ -48,8 +47,6 @@ ) from libsemigroups_pybind11.detail.cxx_wrapper import to_cxx -ReportGuard(False) - ############################################################################### # Helper functions ############################################################################### diff --git a/tests/test_todd_coxeter.py b/tests/test_todd_coxeter.py index 1a9a5296..2c9d74cb 100644 --- a/tests/test_todd_coxeter.py +++ b/tests/test_todd_coxeter.py @@ -18,7 +18,6 @@ FroidurePin, Order, Presentation, - ReportGuard, ToddCoxeter, Transf, WordRange, @@ -64,7 +63,6 @@ def test_constructors(): def test_attributes(): - ReportGuard(False) p = Presentation([0]) presentation.add_rule(p, [0, 0, 0, 0, 0, 0], [0, 0, 0]) tc = ToddCoxeter(congruence_kind.onesided, p) @@ -102,7 +100,6 @@ def test_attributes(): def test_operators(): - ReportGuard(False) p = Presentation([0, 1]) presentation.add_rule(p, [0, 0, 0, 0], [1]) presentation.add_rule(p, [1, 1, 1, 1], [1]) @@ -133,7 +130,6 @@ def test_operators(): def test_settings(): - ReportGuard(False) p = Presentation([0]) presentation.add_rule(p, [0, 0, 0, 0], [0, 0]) tc = ToddCoxeter(congruence_kind.onesided, p) @@ -188,7 +184,6 @@ def test_settings(): def test_000_iterators(): - ReportGuard(False) p = Presentation([0, 1]) presentation.add_rule(p, [0, 0, 0, 0], [0]) presentation.add_rule(p, [1, 1, 1, 1], [1]) @@ -237,7 +232,6 @@ def test_000_iterators(): def test_020(): - ReportGuard(False) p = Presentation([0]) tc = ToddCoxeter(congruence_kind.twosided, p) tc.strategy(strategy.hlt) @@ -246,7 +240,6 @@ def test_020(): def test_021(): - ReportGuard(False) p = Presentation([0, 1, 2, 3, 4]) tc = ToddCoxeter(congruence_kind.twosided, p) with pytest.raises(RuntimeError): @@ -254,7 +247,6 @@ def test_021(): def test_033(): - ReportGuard(False) p = Presentation([0, 1]) presentation.add_rule(p, [0, 0, 0], [0]) presentation.add_rule(p, [0], [1, 1]) @@ -270,7 +262,6 @@ def test_033(): def test_036(): - ReportGuard(False) S = FroidurePin(Transf([1, 3, 4, 2, 3]), Transf([3, 2, 1, 3, 3])) tc = ToddCoxeter(congruence_kind.twosided, S.right_cayley_graph()) tc.add_generating_pair([0], [1]) @@ -287,7 +278,6 @@ def test_036(): def test_096(): - ReportGuard(False) p = Presentation([0, 1]) presentation.add_rule(p, [0], [1]) presentation.add_rule(p, [0, 0], [0])