Skip to content

Commit c8aa2b3

Browse files
presentation: add to_ace_string
1 parent a8d51c1 commit c8aa2b3

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

docs/source/data-structures/presentations/present-helpers.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Contents
7777
sort_rules
7878
strongly_compress
7979
throw_if_bad_inverses
80+
to_ace_string
8081
to_gap_string
8182
try_detect_inverses
8283

src/libsemigroups_pybind11/presentation/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
presentation_sort_rules as _sort_rules,
5757
presentation_strongly_compress as _strongly_compress,
5858
presentation_throw_if_bad_inverses as _throw_if_bad_inverses,
59+
presentation_to_ace_string as _to_ace_string,
5960
presentation_to_gap_string as _to_gap_string,
6061
presentation_try_detect_inverses as _try_detect_inverses,
6162
)
@@ -272,6 +273,7 @@ def __init__(self: _Self, *args, **kwargs) -> None:
272273
sort_rules = _wrap_cxx_free_fn(_sort_rules)
273274
strongly_compress = _wrap_cxx_free_fn(_strongly_compress)
274275
throw_if_bad_inverses = _wrap_cxx_free_fn(_throw_if_bad_inverses)
276+
to_ace_string = _wrap_cxx_free_fn(_to_ace_string)
275277
to_gap_string = _wrap_cxx_free_fn(_to_gap_string)
276278
balance = _wrap_cxx_free_fn(_balance)
277279
add_cyclic_conjugates = _wrap_cxx_free_fn(_add_cyclic_conjugates)
@@ -321,6 +323,7 @@ def __init__(self: _Self, *args, **kwargs) -> None:
321323
"sort_rules",
322324
"strongly_compress",
323325
"throw_if_bad_inverses",
326+
"to_ace_string",
324327
"to_gap_string",
325328
"balance",
326329
"add_cyclic_conjugates",

src/present.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,38 @@ are created by taking quotients of free semigroups or monoids.
16051605
16061606
:returns: The GAP string.
16071607
:rtype: str
1608+
)pbdoc");
1609+
m.def(
1610+
"presentation_to_ace_string",
1611+
[](Presentation_ const& p) { return presentation::to_ace_string(p); },
1612+
py::arg("p"),
1613+
R"pbdoc(
1614+
:sig=(p: Presentation) -> str:
1615+
:only-document-once:
1616+
Return the code that would create a presentation to be used with ACE.
1617+
1618+
This function returns the string of ACE input that could be used to create an
1619+
object with the same alphabet and rules as *p*.
1620+
1621+
:param p: the presentation.
1622+
:type p: Presentation
1623+
1624+
:returns: The ACE string.
1625+
:rtype: str
1626+
1627+
:raises LibsemigroupsError: if ``p.alphabet()`` contains any duplicate letters.
1628+
:raises LibsemigroupsError: if any of the letters in the alphabet of
1629+
*p* are not lowercase, or do not correspond to a lowercase letter when
1630+
transformed to a string using :any:`words.human_readable_letter`.
1631+
1632+
.. note::
1633+
1634+
ACE assumes that presentations are group presentations, where the the alphabet
1635+
consists of lowercase letters, and inverses correspond to the equivalent
1636+
uppercase letters. Therefore, a valid ACE presentation may not be a valid
1637+
libsemigroups presentation; for example, it is possible for relations in an
1638+
ACE presentation to contain uppercase letters that are not explicitly named as
1639+
generators, as long as their lowercase counterparts are listed as generators.
16081640
)pbdoc");
16091641
m.def(
16101642
"presentation_throw_if_bad_inverses",

tests/test_present.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,22 @@ def letter(x):
803803
p.remove_generator(letter(11))
804804

805805

806+
def check_to_ace_string(W):
807+
p = Presentation(W([0, 1]))
808+
p.contains_empty_word(True)
809+
presentation.add_rule(p, W([0, 0]), W([]))
810+
presentation.add_rule(p, W([1, 1, 1]), W([]))
811+
presentation.add_rule(p, W([0, 1, 0, 1]), W([]))
812+
assert (
813+
presentation.to_ace_string(p)
814+
== """Group: a, b;
815+
wo: 4g; # workspace size, adjust as necessary
816+
Rel: aa, bbb, abab;
817+
Mess: 100000; # message frequency, adjust as necessary
818+
End;"""
819+
)
820+
821+
806822
###############################################################################
807823
# Test functions begin
808824
###############################################################################
@@ -1759,3 +1775,8 @@ def test_add_involution_rules():
17591775
def test_add_idempotent_rules():
17601776
check_add_idempotent_rules(to_word)
17611777
check_add_idempotent_rules(to_string)
1778+
1779+
1780+
def test_to_ace_string():
1781+
check_to_ace_string(to_word)
1782+
check_to_ace_string(to_string)

0 commit comments

Comments
 (0)