@@ -1272,6 +1272,103 @@ checks that :math:`v_i = x_j`, and therefore that :math:`(x_i^{-1})^{-1} = x`.
12721272:raises LibsemigroupsError:
12731273 if the values in *vals* do not serve as semigroup inverses.
12741274)pbdoc" );
1275+
1276+ m.def (
1277+ " presentation_balance" ,
1278+ [](Presentation<Word>& p) { return presentation::balance (p); },
1279+ py::arg (" p" ),
1280+ R"pbdoc(
1281+ :sig=(p: Presentation) -> None:
1282+ :only-document-once:
1283+
1284+ Detect inverses and balance the length of the left-hand and right-hand sides.
1285+
1286+ This function calls the 3-argument version of ``balance`` where the 2nd and 3rd
1287+ arguments are deduced from the rules in the presentation if possible as
1288+ follows: the rules of the presentation where one side has length
1289+ ``2`` and the other has length ``0`` are detected. For any such rule we remember
1290+ that the first letter is the inverse of the second and vice versa. If there
1291+ are no such rules, then no changes are made. If there are multiple different
1292+ such rules and we deduce conflicting values for the inverse of a letter, then
1293+ an exception is thrown.
1294+
1295+ :param p: the presentation.
1296+ :type p: Presentation
1297+
1298+ :raises LibsemigroupsError: if :any:`throw_if_bad_alphabet_or_rules` throws.
1299+ :raises LibsemigroupsError: if conflicting inverses for any letter are detected.)pbdoc" );
1300+
1301+ m.def (
1302+ " presentation_balance" ,
1303+ [](Presentation<Word>& p, Word const & inverses) {
1304+ return presentation::balance (p, inverses);
1305+ },
1306+ py::arg (" p" ),
1307+ py::arg (" inverses" ),
1308+ R"pbdoc(
1309+ :sig=(p: Presentation, inverses : Word) -> None:
1310+ :only-document-once:
1311+
1312+ Balance the length of the left-hand and right-hand sides.
1313+
1314+ This function calls the 3-argument version of :any:`balance` where the 2nd
1315+ parameter is defined to be ``p.alphabet()``.
1316+
1317+ :param p: the presentation.
1318+ :type p: Presentation
1319+
1320+ :param inverses: the inverses of the letters.
1321+ :type inverses: :ref:`Word<pseudo_word_type_helper>`
1322+
1323+ :raises LibsemigroupsError: if :any:`throw_if_bad_alphabet_or_rules` throws.
1324+
1325+ :raises LibsemigroupsError:
1326+ if :any:`throw_if_bad_inverses` throws when called with ``p.alphabet()`` and
1327+ ``inverses``. This function does not check that the values in ``inverses``
1328+ are actually inverses for the values in ``p.alphabet()``, and balances the
1329+ relations as described in :any:`balance` assuming that this is the
1330+ case.)pbdoc" );
1331+
1332+ m.def (
1333+ " presentation_balance" ,
1334+ [](Presentation<Word>& p, Word const & letters, Word const & inverses) {
1335+ return presentation::balance (p, letters, inverses);
1336+ },
1337+ py::arg (" p" ),
1338+ py::arg (" letters" ),
1339+ py::arg (" inverses" ),
1340+ R"pbdoc(
1341+ :sig=(p: Presentation, letters: Word, inverses : Word) -> None:
1342+ :only-document-once:
1343+
1344+ Balance the length of the left-hand and right-hand sides.
1345+
1346+ This function first sorts the sides of each rules so that the larger
1347+ side of the rule is on the left. Then for each rule, while the last
1348+ letter of the left-hand side is in *letters*, the last letter of the
1349+ left-hand side is removed and the corresponding value in *inverses* is
1350+ appended to the end of the right-hand side. Next, while the first
1351+ letter of the left-hand side is in *letters*, the first letter of the
1352+ left-hand side is removed and the corresponding value in *inverses* is
1353+ appended to the front of the right-hand side.
1354+
1355+ :param p: the presentation.
1356+ :type p: Presentation
1357+
1358+ :param letters: the letters that can be replaced in the left-hand side.
1359+ :type letters: :ref:`Word<pseudo_word_type_helper>`
1360+
1361+ :param inverses: the inverses of the letters.
1362+ :type inverses: :ref:`Word<pseudo_word_type_helper>`
1363+
1364+ :raises LibsemigroupsError: if throw_if_bad_alphabet_or_rules throws.
1365+
1366+ :raises LibsemigroupsError:
1367+ if :any:`throw_if_bad_inverses` throws when called with *letters* and
1368+ *inverses*. This does not check that the values in *inverses* are
1369+ actually inverses for the values in *letters*, and balances the relations
1370+ as described above.
1371+ )pbdoc" );
12751372 } // bind_present
12761373
12771374 template <typename Word>
@@ -1410,7 +1507,7 @@ defined in the alphabet, and that the inverses act as semigroup inverses.
14101507 * :any:`presentation.throw_if_bad_inverses`
14111508)pbdoc" );
14121509 } // bind_inverse_present
1413- } // namespace
1510+ } // namespace
14141511
14151512 void init_present (py::module & m) {
14161513 bind_present<word_type>(m, " PresentationWord" );
0 commit comments