passagemath-gap-pkg-semigroups 10.6.29__cp312-abi3-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-gap-pkg-semigroups might be problematic. Click here for more details.

Files changed (356) hide show
  1. gap/pkg/semigroups/CHANGELOG.md +1699 -0
  2. gap/pkg/semigroups/CONTRIBUTING.md +91 -0
  3. gap/pkg/semigroups/GNUmakefile +110 -0
  4. gap/pkg/semigroups/GNUmakefile.in +110 -0
  5. gap/pkg/semigroups/GPL +674 -0
  6. gap/pkg/semigroups/LICENSE +16 -0
  7. gap/pkg/semigroups/Makefile +26 -0
  8. gap/pkg/semigroups/Makefile.gappkg +225 -0
  9. gap/pkg/semigroups/PackageInfo.g +529 -0
  10. gap/pkg/semigroups/README.md +102 -0
  11. gap/pkg/semigroups/VERSIONS +112 -0
  12. gap/pkg/semigroups/aclocal.m4 +375 -0
  13. gap/pkg/semigroups/autogen.sh +25 -0
  14. gap/pkg/semigroups/bin/x86_64-pc-linux-musl-default64-kv10/semigroups.so +0 -0
  15. gap/pkg/semigroups/config.guess +1807 -0
  16. gap/pkg/semigroups/config.log +1068 -0
  17. gap/pkg/semigroups/config.status +1133 -0
  18. gap/pkg/semigroups/config.sub +1960 -0
  19. gap/pkg/semigroups/configure +9742 -0
  20. gap/pkg/semigroups/configure.ac +71 -0
  21. gap/pkg/semigroups/data/doc/greens.pickle +1 -0
  22. gap/pkg/semigroups/data/gens/fullbool-8.pickle.gz +0 -0
  23. gap/pkg/semigroups/data/gens/fullbool.pickle.gz +0 -0
  24. gap/pkg/semigroups/data/gens/hall.pickle.gz +0 -0
  25. gap/pkg/semigroups/data/gens/reflex-6.pickle.gz +0 -0
  26. gap/pkg/semigroups/data/gens/reflex.pickle.gz +0 -0
  27. gap/pkg/semigroups/data/tst/bipart4 +10 -0
  28. gap/pkg/semigroups/data/tst/pperm10 +1 -0
  29. gap/pkg/semigroups/data/tst/tables.gz +0 -0
  30. gap/pkg/semigroups/data/tst/testdata +1 -0
  31. gap/pkg/semigroups/data/tst/testinstall.pickle +1 -0
  32. gap/pkg/semigroups/data/tst/trans3 +7 -0
  33. gap/pkg/semigroups/data/tst/trans3-old +7 -0
  34. gap/pkg/semigroups/environment.yml +7 -0
  35. gap/pkg/semigroups/gap/attributes/acting.gd +15 -0
  36. gap/pkg/semigroups/gap/attributes/acting.gi +297 -0
  37. gap/pkg/semigroups/gap/attributes/attr.gd +91 -0
  38. gap/pkg/semigroups/gap/attributes/attr.gi +1214 -0
  39. gap/pkg/semigroups/gap/attributes/dual.gd +25 -0
  40. gap/pkg/semigroups/gap/attributes/dual.gi +209 -0
  41. gap/pkg/semigroups/gap/attributes/factor.gd +17 -0
  42. gap/pkg/semigroups/gap/attributes/factor.gi +453 -0
  43. gap/pkg/semigroups/gap/attributes/homomorph.gd +84 -0
  44. gap/pkg/semigroups/gap/attributes/homomorph.gi +591 -0
  45. gap/pkg/semigroups/gap/attributes/inverse.gd +38 -0
  46. gap/pkg/semigroups/gap/attributes/inverse.gi +708 -0
  47. gap/pkg/semigroups/gap/attributes/isomorph.gd +16 -0
  48. gap/pkg/semigroups/gap/attributes/isomorph.gi +377 -0
  49. gap/pkg/semigroups/gap/attributes/isorms.gd +49 -0
  50. gap/pkg/semigroups/gap/attributes/isorms.gi +1383 -0
  51. gap/pkg/semigroups/gap/attributes/maximal.gd +16 -0
  52. gap/pkg/semigroups/gap/attributes/maximal.gi +1876 -0
  53. gap/pkg/semigroups/gap/attributes/properties.gd +109 -0
  54. gap/pkg/semigroups/gap/attributes/properties.gi +1658 -0
  55. gap/pkg/semigroups/gap/attributes/rms-translat.gd +39 -0
  56. gap/pkg/semigroups/gap/attributes/rms-translat.gi +1078 -0
  57. gap/pkg/semigroups/gap/attributes/semifp.gd +12 -0
  58. gap/pkg/semigroups/gap/attributes/semifp.gi +84 -0
  59. gap/pkg/semigroups/gap/attributes/translat.gd +474 -0
  60. gap/pkg/semigroups/gap/attributes/translat.gi +1779 -0
  61. gap/pkg/semigroups/gap/congruences/cong.gd +154 -0
  62. gap/pkg/semigroups/gap/congruences/cong.gi +351 -0
  63. gap/pkg/semigroups/gap/congruences/conginv.gd +38 -0
  64. gap/pkg/semigroups/gap/congruences/conginv.gi +589 -0
  65. gap/pkg/semigroups/gap/congruences/conglatt.gd +101 -0
  66. gap/pkg/semigroups/gap/congruences/conglatt.gi +886 -0
  67. gap/pkg/semigroups/gap/congruences/congpairs.gd +21 -0
  68. gap/pkg/semigroups/gap/congruences/congpairs.gi +272 -0
  69. gap/pkg/semigroups/gap/congruences/congpart.gd +90 -0
  70. gap/pkg/semigroups/gap/congruences/congpart.gi +449 -0
  71. gap/pkg/semigroups/gap/congruences/congrees.gd +20 -0
  72. gap/pkg/semigroups/gap/congruences/congrees.gi +313 -0
  73. gap/pkg/semigroups/gap/congruences/congrms.gd +54 -0
  74. gap/pkg/semigroups/gap/congruences/congrms.gi +1467 -0
  75. gap/pkg/semigroups/gap/congruences/congsemigraph.gd +28 -0
  76. gap/pkg/semigroups/gap/congruences/congsemigraph.gi +289 -0
  77. gap/pkg/semigroups/gap/congruences/congsimple.gd +27 -0
  78. gap/pkg/semigroups/gap/congruences/congsimple.gi +236 -0
  79. gap/pkg/semigroups/gap/congruences/conguniv.gd +20 -0
  80. gap/pkg/semigroups/gap/congruences/conguniv.gi +271 -0
  81. gap/pkg/semigroups/gap/congruences/congwordgraph.gd +21 -0
  82. gap/pkg/semigroups/gap/congruences/congwordgraph.gi +250 -0
  83. gap/pkg/semigroups/gap/elements/bipart.gd +71 -0
  84. gap/pkg/semigroups/gap/elements/bipart.gi +995 -0
  85. gap/pkg/semigroups/gap/elements/blocks.gd +31 -0
  86. gap/pkg/semigroups/gap/elements/blocks.gi +134 -0
  87. gap/pkg/semigroups/gap/elements/boolmat.gd +74 -0
  88. gap/pkg/semigroups/gap/elements/boolmat.gi +726 -0
  89. gap/pkg/semigroups/gap/elements/elements.gd +11 -0
  90. gap/pkg/semigroups/gap/elements/elements.gi +121 -0
  91. gap/pkg/semigroups/gap/elements/ffmat.gd +71 -0
  92. gap/pkg/semigroups/gap/elements/ffmat.gi +311 -0
  93. gap/pkg/semigroups/gap/elements/maxplusmat.gd +131 -0
  94. gap/pkg/semigroups/gap/elements/maxplusmat.gi +782 -0
  95. gap/pkg/semigroups/gap/elements/pbr.gd +51 -0
  96. gap/pkg/semigroups/gap/elements/pbr.gi +740 -0
  97. gap/pkg/semigroups/gap/elements/pperm.gd +11 -0
  98. gap/pkg/semigroups/gap/elements/pperm.gi +14 -0
  99. gap/pkg/semigroups/gap/elements/semiringmat.gd +136 -0
  100. gap/pkg/semigroups/gap/elements/semiringmat.gi +717 -0
  101. gap/pkg/semigroups/gap/elements/star.gd +21 -0
  102. gap/pkg/semigroups/gap/elements/star.gi +21 -0
  103. gap/pkg/semigroups/gap/elements/trans.gd +13 -0
  104. gap/pkg/semigroups/gap/elements/trans.gi +50 -0
  105. gap/pkg/semigroups/gap/fp/freeband.gd +22 -0
  106. gap/pkg/semigroups/gap/fp/freeband.gi +502 -0
  107. gap/pkg/semigroups/gap/fp/freeinverse.gd +30 -0
  108. gap/pkg/semigroups/gap/fp/freeinverse.gi +465 -0
  109. gap/pkg/semigroups/gap/fp/tietze.gd +89 -0
  110. gap/pkg/semigroups/gap/fp/tietze.gi +1578 -0
  111. gap/pkg/semigroups/gap/fp/word.gd +15 -0
  112. gap/pkg/semigroups/gap/fp/word.gi +67 -0
  113. gap/pkg/semigroups/gap/greens/acting-inverse.gi +774 -0
  114. gap/pkg/semigroups/gap/greens/acting-regular.gi +553 -0
  115. gap/pkg/semigroups/gap/greens/acting.gd +81 -0
  116. gap/pkg/semigroups/gap/greens/acting.gi +2433 -0
  117. gap/pkg/semigroups/gap/greens/froidure-pin.gd +25 -0
  118. gap/pkg/semigroups/gap/greens/froidure-pin.gi +741 -0
  119. gap/pkg/semigroups/gap/greens/generic.gd +117 -0
  120. gap/pkg/semigroups/gap/greens/generic.gi +630 -0
  121. gap/pkg/semigroups/gap/ideals/acting.gd +17 -0
  122. gap/pkg/semigroups/gap/ideals/acting.gi +1155 -0
  123. gap/pkg/semigroups/gap/ideals/froidure-pin.gd +11 -0
  124. gap/pkg/semigroups/gap/ideals/froidure-pin.gi +105 -0
  125. gap/pkg/semigroups/gap/ideals/ideals.gd +45 -0
  126. gap/pkg/semigroups/gap/ideals/ideals.gi +442 -0
  127. gap/pkg/semigroups/gap/ideals/lambda-rho.gd +16 -0
  128. gap/pkg/semigroups/gap/ideals/lambda-rho.gi +614 -0
  129. gap/pkg/semigroups/gap/libsemigroups/cong.gd +24 -0
  130. gap/pkg/semigroups/gap/libsemigroups/cong.gi +431 -0
  131. gap/pkg/semigroups/gap/libsemigroups/fpsemi.gd +16 -0
  132. gap/pkg/semigroups/gap/libsemigroups/fpsemi.gi +53 -0
  133. gap/pkg/semigroups/gap/libsemigroups/froidure-pin.gd +17 -0
  134. gap/pkg/semigroups/gap/libsemigroups/froidure-pin.gi +945 -0
  135. gap/pkg/semigroups/gap/libsemigroups/sims1.gd +38 -0
  136. gap/pkg/semigroups/gap/libsemigroups/sims1.gi +308 -0
  137. gap/pkg/semigroups/gap/main/acting.gd +36 -0
  138. gap/pkg/semigroups/gap/main/acting.gi +779 -0
  139. gap/pkg/semigroups/gap/main/froidure-pin.gd +72 -0
  140. gap/pkg/semigroups/gap/main/froidure-pin.gi +655 -0
  141. gap/pkg/semigroups/gap/main/graded.gd +26 -0
  142. gap/pkg/semigroups/gap/main/graded.gi +355 -0
  143. gap/pkg/semigroups/gap/main/lambda-rho.gd +29 -0
  144. gap/pkg/semigroups/gap/main/lambda-rho.gi +514 -0
  145. gap/pkg/semigroups/gap/main/orbits.gd +24 -0
  146. gap/pkg/semigroups/gap/main/orbits.gi +512 -0
  147. gap/pkg/semigroups/gap/main/semiact.gd +20 -0
  148. gap/pkg/semigroups/gap/main/semiact.gi +821 -0
  149. gap/pkg/semigroups/gap/main/setup.gd +61 -0
  150. gap/pkg/semigroups/gap/main/setup.gi +1094 -0
  151. gap/pkg/semigroups/gap/obsolete.gd +9 -0
  152. gap/pkg/semigroups/gap/obsolete.gi +14 -0
  153. gap/pkg/semigroups/gap/options.g +55 -0
  154. gap/pkg/semigroups/gap/semigroups/grpperm.gd +12 -0
  155. gap/pkg/semigroups/gap/semigroups/grpperm.gi +177 -0
  156. gap/pkg/semigroups/gap/semigroups/semibipart.gd +28 -0
  157. gap/pkg/semigroups/gap/semigroups/semibipart.gi +570 -0
  158. gap/pkg/semigroups/gap/semigroups/semiboolmat.gd +20 -0
  159. gap/pkg/semigroups/gap/semigroups/semiboolmat.gi +104 -0
  160. gap/pkg/semigroups/gap/semigroups/semicons.gd +52 -0
  161. gap/pkg/semigroups/gap/semigroups/semicons.gi +1194 -0
  162. gap/pkg/semigroups/gap/semigroups/semidp.gd +13 -0
  163. gap/pkg/semigroups/gap/semigroups/semidp.gi +509 -0
  164. gap/pkg/semigroups/gap/semigroups/semieunit.gd +126 -0
  165. gap/pkg/semigroups/gap/semigroups/semieunit.gi +889 -0
  166. gap/pkg/semigroups/gap/semigroups/semiex.gd +104 -0
  167. gap/pkg/semigroups/gap/semigroups/semiex.gi +1590 -0
  168. gap/pkg/semigroups/gap/semigroups/semiffmat.gd +37 -0
  169. gap/pkg/semigroups/gap/semigroups/semiffmat.gi +565 -0
  170. gap/pkg/semigroups/gap/semigroups/semifp.gd +28 -0
  171. gap/pkg/semigroups/gap/semigroups/semifp.gi +1364 -0
  172. gap/pkg/semigroups/gap/semigroups/semigraph.gd +40 -0
  173. gap/pkg/semigroups/gap/semigroups/semigraph.gi +292 -0
  174. gap/pkg/semigroups/gap/semigroups/semigrp.gd +165 -0
  175. gap/pkg/semigroups/gap/semigroups/semigrp.gi +1225 -0
  176. gap/pkg/semigroups/gap/semigroups/semimaxplus.gd +72 -0
  177. gap/pkg/semigroups/gap/semigroups/semimaxplus.gi +710 -0
  178. gap/pkg/semigroups/gap/semigroups/semintmat.gd +13 -0
  179. gap/pkg/semigroups/gap/semigroups/semintmat.gi +74 -0
  180. gap/pkg/semigroups/gap/semigroups/semipbr.gd +19 -0
  181. gap/pkg/semigroups/gap/semigroups/semipbr.gi +139 -0
  182. gap/pkg/semigroups/gap/semigroups/semipperm.gd +27 -0
  183. gap/pkg/semigroups/gap/semigroups/semipperm.gi +711 -0
  184. gap/pkg/semigroups/gap/semigroups/semiquo.gd +14 -0
  185. gap/pkg/semigroups/gap/semigroups/semiquo.gi +97 -0
  186. gap/pkg/semigroups/gap/semigroups/semiringmat.gd +16 -0
  187. gap/pkg/semigroups/gap/semigroups/semiringmat.gi +21 -0
  188. gap/pkg/semigroups/gap/semigroups/semirms.gd +19 -0
  189. gap/pkg/semigroups/gap/semigroups/semirms.gi +977 -0
  190. gap/pkg/semigroups/gap/semigroups/semitrans.gd +49 -0
  191. gap/pkg/semigroups/gap/semigroups/semitrans.gi +909 -0
  192. gap/pkg/semigroups/gap/tools/display.gd +24 -0
  193. gap/pkg/semigroups/gap/tools/display.gi +749 -0
  194. gap/pkg/semigroups/gap/tools/io.gd +17 -0
  195. gap/pkg/semigroups/gap/tools/io.gi +543 -0
  196. gap/pkg/semigroups/gap/tools/iterators.gd +16 -0
  197. gap/pkg/semigroups/gap/tools/iterators.gi +253 -0
  198. gap/pkg/semigroups/gap/tools/utils.gd +19 -0
  199. gap/pkg/semigroups/gap/tools/utils.gi +756 -0
  200. gap/pkg/semigroups/gapbind14/.ccls +18 -0
  201. gap/pkg/semigroups/gapbind14/.clang-format +104 -0
  202. gap/pkg/semigroups/gapbind14/CPPLINT.cfg +5 -0
  203. gap/pkg/semigroups/gapbind14/LICENSE +674 -0
  204. gap/pkg/semigroups/gapbind14/README.md +76 -0
  205. gap/pkg/semigroups/gapbind14/demo/.gitignore +4 -0
  206. gap/pkg/semigroups/gapbind14/demo/LICENSE +293 -0
  207. gap/pkg/semigroups/gapbind14/demo/Makefile.gappkg +220 -0
  208. gap/pkg/semigroups/gapbind14/demo/Makefile.in +19 -0
  209. gap/pkg/semigroups/gapbind14/demo/PackageInfo.g +87 -0
  210. gap/pkg/semigroups/gapbind14/demo/README.md +17 -0
  211. gap/pkg/semigroups/gapbind14/demo/configure +34 -0
  212. gap/pkg/semigroups/gapbind14/demo/gap/gapbind_demo.gd +19 -0
  213. gap/pkg/semigroups/gapbind14/demo/gap/gapbind_demo.gi +10 -0
  214. gap/pkg/semigroups/gapbind14/demo/init.g +16 -0
  215. gap/pkg/semigroups/gapbind14/demo/makedoc.g +10 -0
  216. gap/pkg/semigroups/gapbind14/demo/read.g +6 -0
  217. gap/pkg/semigroups/gapbind14/demo/src/gapbind_demo.cc +142 -0
  218. gap/pkg/semigroups/gapbind14/demo/tst/testall.g +12 -0
  219. gap/pkg/semigroups/gapbind14/include/gapbind14/cpp_fn.hpp +223 -0
  220. gap/pkg/semigroups/gapbind14/include/gapbind14/gap_include.hpp +26 -0
  221. gap/pkg/semigroups/gapbind14/include/gapbind14/gapbind14.hpp +445 -0
  222. gap/pkg/semigroups/gapbind14/include/gapbind14/tame_free_fn.hpp +420 -0
  223. gap/pkg/semigroups/gapbind14/include/gapbind14/tame_mem_fn.hpp +556 -0
  224. gap/pkg/semigroups/gapbind14/include/gapbind14/to_cpp.hpp +162 -0
  225. gap/pkg/semigroups/gapbind14/include/gapbind14/to_gap.hpp +158 -0
  226. gap/pkg/semigroups/gapbind14/src/.clang-format +108 -0
  227. gap/pkg/semigroups/gapbind14/src/gapbind14.cpp +334 -0
  228. gap/pkg/semigroups/init.g +150 -0
  229. gap/pkg/semigroups/m4/ax_append_flag.m4 +50 -0
  230. gap/pkg/semigroups/m4/ax_check_compile_flag.m4 +53 -0
  231. gap/pkg/semigroups/m4/ax_check_hpcombi.m4 +121 -0
  232. gap/pkg/semigroups/m4/ax_check_libsemigroup.m4 +68 -0
  233. gap/pkg/semigroups/m4/ax_compare_version.m4 +177 -0
  234. gap/pkg/semigroups/m4/ax_cxx_compile_stdcxx.m4 +1009 -0
  235. gap/pkg/semigroups/m4/ax_cxx_compile_stdcxx_14.m4 +34 -0
  236. gap/pkg/semigroups/m4/ax_prefix_config_h.m4 +203 -0
  237. gap/pkg/semigroups/m4/ax_pthread.m4 +522 -0
  238. gap/pkg/semigroups/m4/find_gap.m4 +94 -0
  239. gap/pkg/semigroups/makedoc.g +153 -0
  240. gap/pkg/semigroups/prerequisites.sh +62 -0
  241. gap/pkg/semigroups/read.g +105 -0
  242. gap/pkg/semigroups/release.toml +6 -0
  243. gap/pkg/semigroups/tst/extreme/README +2 -0
  244. gap/pkg/semigroups/tst/extreme/attrinv.tst +703 -0
  245. gap/pkg/semigroups/tst/extreme/bipart.tst +2803 -0
  246. gap/pkg/semigroups/tst/extreme/closure.tst +652 -0
  247. gap/pkg/semigroups/tst/extreme/cong.tst +286 -0
  248. gap/pkg/semigroups/tst/extreme/conginv.tst +43 -0
  249. gap/pkg/semigroups/tst/extreme/examples.tst +2449 -0
  250. gap/pkg/semigroups/tst/extreme/freeband.tst +37 -0
  251. gap/pkg/semigroups/tst/extreme/greens-acting-regular.tst +27 -0
  252. gap/pkg/semigroups/tst/extreme/greens-acting.tst +1999 -0
  253. gap/pkg/semigroups/tst/extreme/ideals.tst +858 -0
  254. gap/pkg/semigroups/tst/extreme/inverse.tst +1025 -0
  255. gap/pkg/semigroups/tst/extreme/maximal.tst +856 -0
  256. gap/pkg/semigroups/tst/extreme/misc.tst +4236 -0
  257. gap/pkg/semigroups/tst/extreme/monoid_pkg.tst +1488 -0
  258. gap/pkg/semigroups/tst/extreme/properties.tst +914 -0
  259. gap/pkg/semigroups/tst/extreme/semibipart.tst +2837 -0
  260. gap/pkg/semigroups/tst/extreme/semieunit.tst +49 -0
  261. gap/pkg/semigroups/tst/extreme/semiffmat.tst +353 -0
  262. gap/pkg/semigroups/tst/extreme/semigroups.tst +245 -0
  263. gap/pkg/semigroups/tst/extreme/semiiter.tst +58 -0
  264. gap/pkg/semigroups/tst/extreme/semirms.tst +1091 -0
  265. gap/pkg/semigroups/tst/extreme/transform.tst +305 -0
  266. gap/pkg/semigroups/tst/extreme/translat.tst +44 -0
  267. gap/pkg/semigroups/tst/standard/README +2 -0
  268. gap/pkg/semigroups/tst/standard/attributes/acting.tst +388 -0
  269. gap/pkg/semigroups/tst/standard/attributes/attr.tst +2404 -0
  270. gap/pkg/semigroups/tst/standard/attributes/dual.tst +308 -0
  271. gap/pkg/semigroups/tst/standard/attributes/factor.tst +629 -0
  272. gap/pkg/semigroups/tst/standard/attributes/homomorph.tst +1134 -0
  273. gap/pkg/semigroups/tst/standard/attributes/inverse.tst +1521 -0
  274. gap/pkg/semigroups/tst/standard/attributes/isomorph.tst +435 -0
  275. gap/pkg/semigroups/tst/standard/attributes/isorms.tst +1147 -0
  276. gap/pkg/semigroups/tst/standard/attributes/maximal.tst +853 -0
  277. gap/pkg/semigroups/tst/standard/attributes/properties.tst +2028 -0
  278. gap/pkg/semigroups/tst/standard/attributes/semifp.tst +53 -0
  279. gap/pkg/semigroups/tst/standard/attributes/translat.tst +796 -0
  280. gap/pkg/semigroups/tst/standard/congruences/cong.tst +1044 -0
  281. gap/pkg/semigroups/tst/standard/congruences/conginv.tst +292 -0
  282. gap/pkg/semigroups/tst/standard/congruences/conglatt.tst +421 -0
  283. gap/pkg/semigroups/tst/standard/congruences/congpairs.tst +1011 -0
  284. gap/pkg/semigroups/tst/standard/congruences/congrees.tst +288 -0
  285. gap/pkg/semigroups/tst/standard/congruences/congrms.tst +701 -0
  286. gap/pkg/semigroups/tst/standard/congruences/congsemigraph.tst +422 -0
  287. gap/pkg/semigroups/tst/standard/congruences/congsimple.tst +311 -0
  288. gap/pkg/semigroups/tst/standard/congruences/conguniv.tst +259 -0
  289. gap/pkg/semigroups/tst/standard/congruences/congwordgraph.tst +330 -0
  290. gap/pkg/semigroups/tst/standard/elements/bipart.tst +783 -0
  291. gap/pkg/semigroups/tst/standard/elements/blocks.tst +166 -0
  292. gap/pkg/semigroups/tst/standard/elements/boolmat.tst +608 -0
  293. gap/pkg/semigroups/tst/standard/elements/elements.tst +117 -0
  294. gap/pkg/semigroups/tst/standard/elements/ffmat.tst +349 -0
  295. gap/pkg/semigroups/tst/standard/elements/maxplusmat.tst +613 -0
  296. gap/pkg/semigroups/tst/standard/elements/pbr.tst +506 -0
  297. gap/pkg/semigroups/tst/standard/elements/pperm.tst +32 -0
  298. gap/pkg/semigroups/tst/standard/elements/semiringmat.tst +601 -0
  299. gap/pkg/semigroups/tst/standard/elements/trans.tst +58 -0
  300. gap/pkg/semigroups/tst/standard/fp/freeband.tst +311 -0
  301. gap/pkg/semigroups/tst/standard/fp/freeinverse.tst +147 -0
  302. gap/pkg/semigroups/tst/standard/fp/tietze.tst +780 -0
  303. gap/pkg/semigroups/tst/standard/fp/word.tst +106 -0
  304. gap/pkg/semigroups/tst/standard/greens/acting-inverse.tst +545 -0
  305. gap/pkg/semigroups/tst/standard/greens/acting-regular.tst +396 -0
  306. gap/pkg/semigroups/tst/standard/greens/acting.tst +2033 -0
  307. gap/pkg/semigroups/tst/standard/greens/froidure-pin.tst +1831 -0
  308. gap/pkg/semigroups/tst/standard/greens/generic.tst +1436 -0
  309. gap/pkg/semigroups/tst/standard/ideals/acting.tst +279 -0
  310. gap/pkg/semigroups/tst/standard/ideals/froidure-pin.tst +178 -0
  311. gap/pkg/semigroups/tst/standard/ideals/ideals.tst +380 -0
  312. gap/pkg/semigroups/tst/standard/libsemigroups/cong.tst +310 -0
  313. gap/pkg/semigroups/tst/standard/libsemigroups/froidure-pin.tst +778 -0
  314. gap/pkg/semigroups/tst/standard/libsemigroups/sims1.tst +379 -0
  315. gap/pkg/semigroups/tst/standard/main/acting.tst +411 -0
  316. gap/pkg/semigroups/tst/standard/main/froidure-pin.tst +392 -0
  317. gap/pkg/semigroups/tst/standard/main/semiact.tst +203 -0
  318. gap/pkg/semigroups/tst/standard/main/setup.tst +1144 -0
  319. gap/pkg/semigroups/tst/standard/obsolete.tst +19 -0
  320. gap/pkg/semigroups/tst/standard/options.tst +54 -0
  321. gap/pkg/semigroups/tst/standard/semigroups/grpperm.tst +581 -0
  322. gap/pkg/semigroups/tst/standard/semigroups/semibipart.tst +2635 -0
  323. gap/pkg/semigroups/tst/standard/semigroups/semiboolmat.tst +1871 -0
  324. gap/pkg/semigroups/tst/standard/semigroups/semicons.tst +1173 -0
  325. gap/pkg/semigroups/tst/standard/semigroups/semidp.tst +739 -0
  326. gap/pkg/semigroups/tst/standard/semigroups/semieunit.tst +339 -0
  327. gap/pkg/semigroups/tst/standard/semigroups/semiex.tst +2055 -0
  328. gap/pkg/semigroups/tst/standard/semigroups/semiffmat.tst +746 -0
  329. gap/pkg/semigroups/tst/standard/semigroups/semifp.tst +2702 -0
  330. gap/pkg/semigroups/tst/standard/semigroups/semigraph.tst +133 -0
  331. gap/pkg/semigroups/tst/standard/semigroups/semigrp.tst +1112 -0
  332. gap/pkg/semigroups/tst/standard/semigroups/semimaxplus.tst +654 -0
  333. gap/pkg/semigroups/tst/standard/semigroups/semipbr.tst +2142 -0
  334. gap/pkg/semigroups/tst/standard/semigroups/semipperm.tst +2169 -0
  335. gap/pkg/semigroups/tst/standard/semigroups/semiquo.tst +278 -0
  336. gap/pkg/semigroups/tst/standard/semigroups/semirms.tst +3010 -0
  337. gap/pkg/semigroups/tst/standard/semigroups/semitrans.tst +2758 -0
  338. gap/pkg/semigroups/tst/standard/tools/display.tst +1040 -0
  339. gap/pkg/semigroups/tst/standard/tools/io.tst +363 -0
  340. gap/pkg/semigroups/tst/testinstall.tst +1815 -0
  341. gap/pkg/semigroups/tst/teststandard.g +22 -0
  342. gap/pkg/semigroups/tst/workspaces/load-workspace.tst +142 -0
  343. gap/pkg/semigroups/tst/workspaces/load.g +11 -0
  344. gap/pkg/semigroups/tst/workspaces/save-workspace.tst +166 -0
  345. gap/pkg/semigroups/tst/workspaces/save.g +14 -0
  346. passagemath_gap_pkg_semigroups-10.6.29.dist-info/METADATA +93 -0
  347. passagemath_gap_pkg_semigroups-10.6.29.dist-info/METADATA.bak +94 -0
  348. passagemath_gap_pkg_semigroups-10.6.29.dist-info/RECORD +356 -0
  349. passagemath_gap_pkg_semigroups-10.6.29.dist-info/WHEEL +5 -0
  350. passagemath_gap_pkg_semigroups-10.6.29.dist-info/top_level.txt +1 -0
  351. passagemath_gap_pkg_semigroups.libs/libgcc_s-0cd532bd.so.1 +0 -0
  352. passagemath_gap_pkg_semigroups.libs/libsemigroups-f0b7066b.so.2.0.0 +0 -0
  353. passagemath_gap_pkg_semigroups.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  354. sage/all__sagemath_gap_pkg_semigroups.py +1 -0
  355. sage/libs/all__sagemath_gap_pkg_semigroups.py +1 -0
  356. sage/libs/gap_pkg_semigroups.abi3.so +0 -0
@@ -0,0 +1,1578 @@
1
+ ############################################################################
2
+ ##
3
+ ## fp/tietze.gi
4
+ ## Copyright (C) 2021-2022 Tom Conti-Leslie
5
+ ## Ben Spiers
6
+ ##
7
+ ## Licensing information can be found in the README file of this package.
8
+ ##
9
+ ############################################################################
10
+ ##
11
+
12
+ ########################################################################
13
+ # This file is organised as follows:
14
+ #
15
+ # 1. Definition of the Semigroup Tietze (IsStzPresentation) object
16
+ # 2. Viewing methods for IsStzPresentation objects
17
+ # 3. Internal Tietze transformation functions
18
+ # 4. User-accessible Tietze transformation functions (wrappers)
19
+ # 5. Internal helper functions for word/relation manipulation etc.
20
+ # 6. Internal auto-checkers and appliers for presentation simplifying
21
+ # 7. SimplifyPresentation etc.
22
+ # 8. Other
23
+ ########################################################################
24
+
25
+ ########################################################################
26
+ # 1. Definition of the Semigroup Tietze (IsStzPresentation) object
27
+ ########################################################################
28
+
29
+ InstallMethod(StzPresentation, "for a finitely presented semigroup",
30
+ [IsFpSemigroup],
31
+ function(S)
32
+ local gens, out, rels, type;
33
+
34
+ type := NewType(NewFamily("StzFamily", IsStzPresentation),
35
+ IsStzPresentation and IsComponentObjectRep);
36
+
37
+ rels := List(RelationsOfFpSemigroup(S),
38
+ x -> [LetterRepAssocWord(x[1]), LetterRepAssocWord(x[2])]);
39
+ gens := List(GeneratorsOfSemigroup(S), ViewString);
40
+
41
+ out := rec(GeneratorsOfStzPresentation := gens,
42
+ RelationsOfStzPresentation := rels,
43
+ UnreducedFpSemigroup := S,
44
+ TietzeForwardMap := List(
45
+ [1 .. Length(GeneratorsOfSemigroup(S))], x -> [x]),
46
+ TietzeBackwardMap := List(
47
+ [1 .. Length(GeneratorsOfSemigroup(S))], x -> [x]),
48
+ usedGens := Set(gens));
49
+
50
+ return Objectify(type, out);
51
+ end);
52
+
53
+ InstallMethod(SetRelationsOfStzPresentation,
54
+ [IsStzPresentation, IsList],
55
+ function(stz, arg)
56
+ if not ForAll(arg, IsList) or
57
+ not ForAll(arg, x -> Length(x) = 2 and ForAll(x, IsList)) or
58
+ not ForAll(arg, x -> ForAll(x, y -> ForAll(y, IsPosInt))) then
59
+ ErrorNoReturn("parameter <arg> must be a list of pairs of words in ",
60
+ "LetterRep format");
61
+ fi;
62
+ stz!.RelationsOfStzPresentation := arg;
63
+ end);
64
+
65
+ InstallMethod(RelationsOfStzPresentation, [IsStzPresentation],
66
+ stz -> stz!.RelationsOfStzPresentation);
67
+
68
+ InstallMethod(UnreducedFpSemigroup, [IsStzPresentation],
69
+ stz -> stz!.UnreducedFpSemigroup);
70
+
71
+ InstallMethod(TietzeForwardMap, [IsStzPresentation],
72
+ stz -> stz!.TietzeForwardMap);
73
+
74
+ InstallMethod(TietzeBackwardMap, [IsStzPresentation],
75
+ stz -> stz!.TietzeBackwardMap);
76
+
77
+ InstallMethod(GeneratorsOfStzPresentation, [IsStzPresentation],
78
+ stz -> stz!.GeneratorsOfStzPresentation);
79
+
80
+ InstallMethod(SetGeneratorsOfStzPresentation, [IsStzPresentation, IsList],
81
+ function(stz, newGens)
82
+ stz!.GeneratorsOfStzPresentation := newGens;
83
+ end);
84
+
85
+ InstallMethod(StzIsomorphism,
86
+ [IsStzPresentation],
87
+ function(stz)
88
+ local source, range, forward_dict, forward_map, backward_dict, backward_map;
89
+ source := UnreducedFpSemigroup(stz);
90
+ range := SEMIGROUPS.StzConvertObjToFpSemigroup(stz);
91
+
92
+ # build forward map
93
+ forward_dict := TietzeForwardMap(stz);
94
+ forward_map := function(word)
95
+ local new_word;
96
+ new_word := SEMIGROUPS.StzExpandWord(
97
+ LetterRepAssocWord(UnderlyingElement(word)), forward_dict);
98
+ return Product(new_word, x -> GeneratorsOfSemigroup(range)[x]);
99
+ end;
100
+
101
+ # build backward map
102
+ backward_dict := TietzeBackwardMap(stz);
103
+ backward_map := function(word)
104
+ local new_word;
105
+ new_word := SEMIGROUPS.StzExpandWord(
106
+ LetterRepAssocWord(UnderlyingElement(word)), backward_dict);
107
+ return Product(new_word, x -> GeneratorsOfSemigroup(source)[x]);
108
+ end;
109
+
110
+ # TODO(later) are we okay to assume this is necessarily an isomorphism?
111
+ return SemigroupIsomorphismByFunctionNC(source,
112
+ range,
113
+ forward_map,
114
+ backward_map);
115
+ end);
116
+
117
+ InstallMethod(SetTietzeForwardMap,
118
+ "for an stz presentation and list",
119
+ [IsStzPresentation, IsList],
120
+ function(stz, newMaps)
121
+ if not ForAll(newMaps, x -> IsList(x) and ForAll(x, IsPosInt)) then
122
+ ErrorNoReturn("the 2nd argument <newMaps> must ",
123
+ "be a list of lists of positive integers");
124
+ fi;
125
+ stz!.TietzeForwardMap := newMaps;
126
+ end);
127
+
128
+ InstallMethod(SetTietzeBackwardMap,
129
+ "for an stz presentation and list",
130
+ [IsStzPresentation, IsList],
131
+ function(stz, newMaps)
132
+ if not ForAll(newMaps, x -> IsList(x) and ForAll(x, IsPosInt)) then
133
+ ErrorNoReturn("the 2nd argument <newMaps> must ",
134
+ "be a list of lists of positive integers");
135
+ fi;
136
+ stz!.TietzeBackwardMap := newMaps;
137
+ end);
138
+
139
+ InstallMethod(TietzeForwardMapReplaceSubword,
140
+ "for an stz presentation, list, and list",
141
+ [IsStzPresentation, IsList, IsList],
142
+ function(stz, subWord, newSubWord)
143
+ local newMaps;
144
+ newMaps := List(stz!.TietzeForwardMap,
145
+ x -> SEMIGROUPS.StzReplaceSubwordRel(x,
146
+ subWord,
147
+ newSubWord));
148
+ stz!.TietzeForwardMap := newMaps;
149
+ end);
150
+
151
+ # Length of an StzPresentation is defined as the number of generators plus the
152
+ # length of every word in the defining relations
153
+ InstallMethod(Length, "for an stz presentation", [IsStzPresentation],
154
+ function(stz)
155
+ local out, rel;
156
+ out := Length(stz!.GeneratorsOfStzPresentation);
157
+ for rel in RelationsOfStzPresentation(stz) do
158
+ out := out + Length(rel[1]) + Length(rel[2]);
159
+ od;
160
+ return out;
161
+ end);
162
+
163
+ InstallMethod(\<, "for stz presentations",
164
+ [IsStzPresentation, IsStzPresentation],
165
+ {stz1, stz2} -> Length(stz1) < Length(stz2));
166
+
167
+ ########################################################################
168
+ # 2. Viewing methods for IsStzPresentation objects
169
+ ########################################################################
170
+
171
+ InstallMethod(ViewString,
172
+ [IsStzPresentation],
173
+ function(stz)
174
+ local num_gens, num_rels;
175
+ num_gens := Length(stz!.GeneratorsOfStzPresentation);
176
+ num_rels := Length(stz!.RelationsOfStzPresentation);
177
+ return Concatenation(
178
+ StringFormatted("<fp semigroup presentation with {} and {}",
179
+ Pluralize(num_gens, "generator"),
180
+ Pluralize(num_rels, "relation")),
181
+ StringFormatted("\< with length {}>", Length(stz)));
182
+ end);
183
+
184
+ SEMIGROUPS.StzRelationDisplayString := function(stz, i)
185
+ local rels, f, gens, w1, w2;
186
+ rels := RelationsOfStzPresentation(stz);
187
+ if i > Length(rels) then
188
+ return fail;
189
+ else
190
+ # We'd like patterns to be grouped, i.e. abab=(ab)^2 when displayed. To
191
+ # do this we sneakily piggyback off display methods for the free semigroup.
192
+ f := FreeSemigroup(GeneratorsOfStzPresentation(stz));
193
+ gens := GeneratorsOfSemigroup(f);
194
+ w1 := Product(rels[i][1], x -> gens[x]);
195
+ w2 := Product(rels[i][2], x -> gens[x]);
196
+ return Concatenation(PrintString(i),
197
+ ". ",
198
+ PrintString(w1),
199
+ " = ",
200
+ PrintString(w2));
201
+ fi;
202
+ end;
203
+
204
+ InstallMethod(StzPrintRelations,
205
+ "for an stz presentation and a list of pos ints",
206
+ [IsStzPresentation, IsList],
207
+ function(stz, list)
208
+ local i;
209
+ # This function displays the current relations in terms of the current
210
+ # generators for a semigroup Tietze presentation.
211
+ if IsEmpty(RelationsOfStzPresentation(stz)) then
212
+ Info(InfoFpSemigroup,
213
+ 1,
214
+ "There are no relations in the presentation <stz>");
215
+ fi;
216
+
217
+ # Print relations at each index of the list, unless incorrect index,
218
+ # in which case skip.
219
+ for i in list do
220
+ if IsPosInt(i) and i <= Length(RelationsOfStzPresentation(stz)) then
221
+ Info(InfoFpSemigroup, 1, SEMIGROUPS.StzRelationDisplayString(stz, i));
222
+ fi;
223
+ od;
224
+ end);
225
+
226
+ InstallMethod(StzPrintRelations, "for an stz presentation",
227
+ [IsStzPresentation],
228
+ function(stz)
229
+ StzPrintRelations(stz, [1 .. Length(RelationsOfStzPresentation(stz))]);
230
+ end);
231
+
232
+ InstallMethod(StzPrintRelation, "for an stz presentation and a pos int",
233
+ [IsStzPresentation, IsPosInt],
234
+ function(stz, int)
235
+ StzPrintRelations(stz, [int]);
236
+ end);
237
+
238
+ InstallMethod(StzPrintGenerators,
239
+ "for an stz presentation and a list of pos ints",
240
+ [IsStzPresentation, IsList],
241
+ function(stz, list)
242
+ local flat, gens, out, rel, i;
243
+ # This function displays a list of generators and number of occurrences
244
+ # of each
245
+
246
+ # warn if there are no generators in the list (not sure this could happen)
247
+ if IsEmpty(GeneratorsOfStzPresentation(stz)) then
248
+ Info(InfoFpSemigroup, 1,
249
+ "There are no generators in the presentation <stz>");
250
+ fi;
251
+
252
+ # create flat flat list of relations to count occurrences
253
+ flat := [];
254
+ for rel in RelationsOfStzPresentation(stz) do
255
+ Append(flat, rel[1]);
256
+ Append(flat, rel[2]);
257
+ od;
258
+
259
+ # enumerate and count generators
260
+ gens := GeneratorsOfStzPresentation(stz);
261
+ for i in list do
262
+ # only print if requested index is valid
263
+ if IsPosInt(i) and i <= Length(gens) then
264
+ out := Concatenation(PrintString(i),
265
+ ". ",
266
+ gens[i],
267
+ " ",
268
+ PrintString(Number(flat, x -> x = i)),
269
+ " occurrences");
270
+ Info(InfoFpSemigroup, 1, out);
271
+ fi;
272
+ od;
273
+ end);
274
+
275
+ InstallMethod(StzPrintGenerators, "for an stz presentation",
276
+ [IsStzPresentation],
277
+ function(stz)
278
+ StzPrintGenerators(stz, [1 .. Length(GeneratorsOfStzPresentation(stz))]);
279
+ end);
280
+
281
+ InstallMethod(StzPrintPresentation, "for an stz presentation",
282
+ [IsStzPresentation],
283
+ function(stz)
284
+ local status, oldgens, oldfree, oldelms, newgens, newfree, newelms, w, i;
285
+ # prints everything that is known about the presentation.
286
+
287
+ # current generators
288
+ Info(InfoFpSemigroup, 1, "Current generators:");
289
+ StzPrintGenerators(stz);
290
+
291
+ # current relations
292
+ Info(InfoFpSemigroup, 1, "");
293
+ Info(InfoFpSemigroup, 1, "Current relations:");
294
+ StzPrintRelations(stz);
295
+
296
+ # total number and total length
297
+ Info(InfoFpSemigroup, 1, "");
298
+ status := "There ";
299
+ if Length(stz!.GeneratorsOfStzPresentation) = 1 then
300
+ status := Concatenation(status, "is 1 generator");
301
+ else
302
+ status := Concatenation(status,
303
+ "are ",
304
+ PrintString(
305
+ Length(GeneratorsOfStzPresentation(stz))),
306
+ " generators");
307
+ fi;
308
+ status := Concatenation(status, " and ");
309
+ if Length(stz!.RelationsOfStzPresentation) = 1 then
310
+ status := Concatenation(status, "1 relation");
311
+ else
312
+ status := Concatenation(status,
313
+ PrintString(Length(stz!.RelationsOfStzPresentation)),
314
+ " relations");
315
+ fi;
316
+ status := Concatenation(status,
317
+ " of total length ",
318
+ PrintString(Length(stz)),
319
+ ".");
320
+ Info(InfoFpSemigroup, 1, status);
321
+
322
+ # build free semigroup of old gens for display
323
+ oldgens := GeneratorsOfSemigroup(UnreducedFpSemigroup(stz));
324
+ oldgens := List(oldgens, ViewString);
325
+ oldfree := FreeSemigroup(oldgens);
326
+ oldelms := GeneratorsOfSemigroup(oldfree);
327
+
328
+ # build free semigroup of new gens for display
329
+ newgens := GeneratorsOfStzPresentation(stz);
330
+ newfree := FreeSemigroup(newgens);
331
+ newelms := GeneratorsOfSemigroup(newfree);
332
+
333
+ # old generators expressed using current ones
334
+ Info(InfoFpSemigroup, 1, "");
335
+ Info(InfoFpSemigroup, 1, "Generators of original fp semigroup expressed as");
336
+ Info(InfoFpSemigroup, 1,
337
+ "combinations of generators in current presentation:");
338
+ for i in [1 .. Length(oldgens)] do
339
+ w := Product(TietzeForwardMap(stz)[i], x -> newelms[x]);
340
+ Info(InfoFpSemigroup, 1, Concatenation(PrintString(i),
341
+ ". ",
342
+ oldgens[i],
343
+ " = ",
344
+ PrintString(w)));
345
+ od;
346
+
347
+ # new generators expressed using old ones
348
+ Info(InfoFpSemigroup, 1, "");
349
+ Info(InfoFpSemigroup, 1, "Generators of current presentation expressed as");
350
+ Info(InfoFpSemigroup, 1,
351
+ "combinations of generators of original fp semigroup:");
352
+ for i in [1 .. Length(newgens)] do
353
+ w := Product(TietzeBackwardMap(stz)[i], x -> oldelms[x]);
354
+ Info(InfoFpSemigroup, 1, Concatenation(PrintString(i),
355
+ ". ",
356
+ newgens[i],
357
+ " = ",
358
+ PrintString(w)));
359
+ od;
360
+ end);
361
+
362
+ ########################################################################
363
+ # 3. Internal Tietze transformation functions
364
+ ########################################################################
365
+
366
+ # TIETZE TRANSFORMATION 1: INTERNAL: ADD REDUNDANT RELATION - NO CHECK
367
+ SEMIGROUPS.TietzeTransformation1 := function(stz, pair)
368
+ local rels_copy;
369
+ # Arguments:
370
+ # - <stz> should be a Semigroup Tietze (IsStzPresentation) object.
371
+ # - <pair> should be a list containing two LetterRep words.
372
+ #
373
+ # This function returns nothing, and modifies <stz> in place by adding a new
374
+ # relation given by <pair>. This relation is assumed to be redundant based
375
+ # on the relations already present in RelationsOfStzPresentation(<stz>)
376
+ # (although this is not checked).
377
+ #
378
+ # WARNING: this is an internal function and performs only minimal argument
379
+ # checks. Entering arguments in the wrong format may result in errors that
380
+ # are difficult to interpret. Argument checks are carried out in the
381
+ # analogous, documented function: StzAddRelation. However, these checks
382
+ # may not terminate in some cases.
383
+
384
+ # Add relation
385
+ rels_copy := ShallowCopy(RelationsOfStzPresentation(stz));
386
+ Add(rels_copy, pair);
387
+ stz!.RelationsOfStzPresentation := rels_copy;
388
+ return;
389
+ end;
390
+
391
+ # TIETZE TRANSFORMATION 2: INTERNAL: REMOVE REDUNDANT RELATION - NO CHECK
392
+ SEMIGROUPS.TietzeTransformation2 := function(stz, index)
393
+ local rels_copy;
394
+ # Arguments:
395
+ # - <stz> should be a Semigroup Tietze (IsStzPresentation) object.
396
+ # - <index> should be the index of the relation in
397
+ # RelationsOfStzPresentation(<stz>) that needs to be removed.
398
+ #
399
+ # This function returns nothing, and modifies <stz> in place by removing
400
+ # relation number <index>, assumed to be redundant (though redundancy of
401
+ # that relation is not checked).
402
+ #
403
+ # WARNING: this is an internal function and performs only minimal argument
404
+ # checks. Entering arguments in the wrong format may result in errors that
405
+ # are difficult to interpret. Argument checks are carried out in the
406
+ # analogous, documented function: StzRemoveRelation. However, these checks
407
+ # may not terminate in some cases.
408
+
409
+ # Remove relation
410
+ rels_copy := ShallowCopy(RelationsOfStzPresentation(stz));
411
+ Remove(rels_copy, index);
412
+ stz!.RelationsOfStzPresentation := rels_copy;
413
+ end;
414
+
415
+ # TIETZE TRANSFORMATION 3: INTERNAL: ADD NEW GENERATOR - NO CHECK
416
+ SEMIGROUPS.TietzeTransformation3 := function(stz, word, name)
417
+ local new_gens, new_rels, back_word, new_maps, letter;
418
+ # Arguments:
419
+ # - <stz> should be a Semigroup Tietze (IsStzPresentation) object.
420
+ # - <word> should be a LetterRep word.
421
+ # - <name> should be a string, or fail.
422
+ #
423
+ # This function returns nothing, and modifies <stz> in place by adding a new
424
+ # generator and the relation gen = <word>.
425
+ # The name for the new generator is <name>, unless this argument is fail,
426
+ # in which case the name is automatically generated using
427
+ # SEMIGROUPS.NewGeneratorName.
428
+ # This function also updates the Tietze backwards map so that the new
429
+ # generator can be expressed as a word on the generators of the original
430
+ # semigroup.
431
+ #
432
+ # WARNING: this is an internal function and performs only minimal argument
433
+ # checks. Entering arguments in the wrong format may result in errors that
434
+ # are difficult to interpret. Argument checks are carried out in the
435
+ # analogous, documented function: StzAddGenerator.
436
+
437
+ # Add new generator string to the list of gens in similar format
438
+ new_gens := ShallowCopy(stz!.GeneratorsOfStzPresentation);
439
+ new_rels := ShallowCopy(stz!.RelationsOfStzPresentation);
440
+ if name = fail or name in stz!.GeneratorsOfStzPresentation then
441
+ # either name was not specified, or it was but is already a generator.
442
+ # generate a new generator name, as of yet unused.
443
+ Add(new_gens, SEMIGROUPS.NewGeneratorName(List(stz!.usedGens)));
444
+ else
445
+ # this must mean the argument is a string as of yet unused, so add that
446
+ Add(new_gens, ShallowCopy(name));
447
+ fi;
448
+
449
+ # in either case we have added a new generator: for cosmetic reasons,
450
+ # prohibit that generator name from being auto-used again (in case we delete
451
+ # it)
452
+ UniteSet(stz!.usedGens, new_gens);
453
+
454
+ # Add relation setting new gen equal to <word>
455
+ Add(new_rels, [word, [Length(stz!.GeneratorsOfStzPresentation) + 1]]);
456
+
457
+ # Update internal representation of the stz object
458
+ SetGeneratorsOfStzPresentation(stz, new_gens);
459
+ SetRelationsOfStzPresentation(stz, new_rels);
460
+
461
+ # Now we need to update the backwards map to express the new generator in
462
+ # terms of the original generators.
463
+ back_word := [];
464
+ new_maps := ShallowCopy(TietzeBackwardMap(stz));
465
+ for letter in word do
466
+ Append(back_word, new_maps[letter]);
467
+ od;
468
+ Add(new_maps, back_word);
469
+ SetTietzeBackwardMap(stz, new_maps);
470
+ end;
471
+
472
+ # TIETZE TRANSFORMATION 4: INTERNAL: REMOVE GENERATOR - MINIMAL CHECKS
473
+ SEMIGROUPS.TietzeTransformation4 := function(stz, gen, index)
474
+ local found_expr, expr, decrement, tempMaps, tempRels, tempGens;
475
+ # Arguments:
476
+ # - <stz> should be a Semigroup Tietze (IsStzPresentation) object.
477
+ # - <gen> should be a pos int.
478
+ # - <index> should be a pos int.
479
+ #
480
+ # This function returns nothing, and modifies <stz> in place by removing
481
+ # generator number <gen> using relation number <index>.
482
+ # If relation number <index> of <stz> is not of the form
483
+ # [<gen>] = *some word not including <gen>* (or that relation flipped),
484
+ # then this function throws ErrorNoReturn.
485
+ # This function also updates the Tietze forward map, so that any generator
486
+ # in the original semigroup expressed as a combination of generators
487
+ # including <gen> is now represented without using <gen> (since <gen>
488
+ # has been removed).
489
+ #
490
+ # WARNING: this is an internal function and performs only minimal argument
491
+ # checks. Entering arguments in the wrong format may result in errors that
492
+ # are difficult to interpret. Argument checks are carried out in the
493
+ # analogous, documented function: StzRemoveGenerator.
494
+
495
+ # check we can express <gen> using only other generators with relation
496
+ # number <index>
497
+ found_expr := false;
498
+ if RelationsOfStzPresentation(stz)[index][1] = [gen] and
499
+ not gen in RelationsOfStzPresentation(stz)[index][2] then
500
+ expr := RelationsOfStzPresentation(stz)[index][2];
501
+ found_expr := true;
502
+ elif RelationsOfStzPresentation(stz)[index][2] = [gen] and
503
+ not gen in RelationsOfStzPresentation(stz)[index][1] then
504
+ expr := RelationsOfStzPresentation(stz)[index][1];
505
+ found_expr := true;
506
+ fi;
507
+
508
+ # check we found an expression for <gen>. If not, nothing can be done.
509
+ if not found_expr then
510
+ ErrorNoReturn("TietzeTransformation4, internal function: third argument\n",
511
+ "<index> does not point to a relation expressing second\n",
512
+ "argument <gen> as a combination of other generators");
513
+ fi;
514
+
515
+ # Define decrement function to bump down generator numbers past the one
516
+ # we're going to remove
517
+ decrement := function(z)
518
+ if z <= gen then # shouldn't be equal but just in case
519
+ return z;
520
+ else
521
+ return z - 1;
522
+ fi;
523
+ end;
524
+
525
+ # update forward mapping component
526
+ # TODO(later) do we really need TietzeForwardMapReplaceSubword?
527
+ TietzeForwardMapReplaceSubword(stz, [gen], expr);
528
+ tempMaps := ShallowCopy(TietzeForwardMap(stz));
529
+ Apply(tempMaps, x -> List(x, decrement));
530
+ SetTietzeForwardMap(stz, tempMaps);
531
+
532
+ # remove generator from backward mapping component
533
+ tempMaps := ShallowCopy(TietzeBackwardMap(stz));
534
+ Remove(tempMaps, gen);
535
+ SetTietzeBackwardMap(stz, tempMaps);
536
+
537
+ # sub in expression we found and remove relation we used for gen
538
+ tempRels := ShallowCopy(RelationsOfStzPresentation(stz));
539
+ Remove(tempRels, index);
540
+ tempRels := SEMIGROUPS.StzReplaceSubword(tempRels, [gen], expr);
541
+ SetRelationsOfStzPresentation(stz, tempRels);
542
+ Apply(stz!.RelationsOfStzPresentation, x -> List(x, y -> List(y, decrement)));
543
+
544
+ # remove generator.
545
+ tempGens := ShallowCopy(GeneratorsOfStzPresentation(stz));
546
+ Remove(tempGens, gen);
547
+ SetGeneratorsOfStzPresentation(stz, tempGens);
548
+ end;
549
+
550
+ ########################################################################
551
+ # 4. User-accessible Tietze transformation functions (wrappers)
552
+ ########################################################################
553
+
554
+ # Tietze Transformation 1: Add relation
555
+ InstallMethod(StzAddRelation, "for an stz presentation and a pair of words",
556
+ [IsStzPresentation, IsList],
557
+ 1, # bump ahead of next implementation and do the list size arg check here
558
+ function(stz, pair)
559
+ local n, f, free_fam, r, s, fp_fam, w1, w2, p1, p2, word, letter;
560
+ # <pair> should be a pair of LetterRep words.
561
+
562
+ # argument checks:
563
+ if Length(pair) <> 2 then
564
+ ErrorNoReturn("StzAddRelation: second argument <pair> should be a list\n",
565
+ "of length 2");
566
+ fi;
567
+ n := Length(stz!.GeneratorsOfStzPresentation);
568
+ for word in pair do
569
+ if not IsList(word) then
570
+ TryNextMethod(); # pass this on to the case where the list may be a pair
571
+ # of words in OG semigroup
572
+ elif IsEmpty(word) then
573
+ ErrorNoReturn("StzAddRelation: words in second argument <pair> should\n",
574
+ "be non-empty");
575
+ else
576
+ for letter in word do
577
+ if not (IsPosInt(letter) and letter <= n) then
578
+ ErrorNoReturn("StzAddRelation: words in second argument <pair>\n",
579
+ "should be lists of pos ints no greater than the\n",
580
+ "number of generators of first argument <stz>");
581
+ fi;
582
+ od;
583
+ fi;
584
+ od;
585
+
586
+ # check that the pair can be deduced from the other relations, by
587
+ # creating fp semigroup with current relations.
588
+
589
+ # base free semigroup
590
+ f := FreeSemigroup(stz!.GeneratorsOfStzPresentation);
591
+ free_fam := FamilyObj(f.1); # marrow for creating free semigp words
592
+ r := List(stz!.RelationsOfStzPresentation,
593
+ x -> List(x, y -> AssocWordByLetterRep(free_fam, y)));
594
+ s := f / r; # fp semigroup
595
+ fp_fam := FamilyObj(s.1); # marrow for creating fp words
596
+ # words first in free semigroup, then map to fp semigroup:
597
+ w1 := AssocWordByLetterRep(free_fam, pair[1]);
598
+ w2 := AssocWordByLetterRep(free_fam, pair[2]);
599
+ p1 := ElementOfFpSemigroup(fp_fam, w1);
600
+ p2 := ElementOfFpSemigroup(fp_fam, w2);
601
+ # check if words are equal in the fp semigroup
602
+ # WARNING: may run forever if undecidable
603
+ if p1 = p2 then
604
+ SEMIGROUPS.TietzeTransformation1(stz, pair);
605
+ return;
606
+ else
607
+ ErrorNoReturn("StzAddRelation: second argument <pair> must list two\n",
608
+ "words that are equal in the presentation <stz>");
609
+ fi;
610
+ end);
611
+
612
+ InstallMethod(StzAddRelation,
613
+ "for an stz presentation and a pair of semigroup elements",
614
+ [IsStzPresentation, IsList],
615
+ function(stz, pair)
616
+ local s, pairwords, word;
617
+ # retrieve original semigroup
618
+ s := UnreducedFpSemigroup(stz);
619
+ for word in pair do
620
+ if not word in s then
621
+ TryNextMethod();
622
+ fi;
623
+ od;
624
+
625
+ # convert into words in original semigroup
626
+ pairwords := List(pair, UnderlyingElement);
627
+ Apply(pairwords, LetterRepAssocWord);
628
+ # map to words in new semigroup
629
+ Apply(pairwords, x -> SEMIGROUPS.StzExpandWord(x, TietzeForwardMap(stz)));
630
+
631
+ # apply tietze1, with argument checks
632
+ StzAddRelation(stz, pairwords);
633
+ return;
634
+ end);
635
+
636
+ # Tietze Transformation 1: Add relation (NO REDUNDANCY CHECK)
637
+ InstallMethod(StzAddRelationNC, "for an stz presentation and a pair of words",
638
+ [IsStzPresentation, IsList],
639
+ 1, # bump priority, do list size check here
640
+ function(stz, pair)
641
+ local n, word, letter;
642
+ # <pair> should be a pair of LetterRep words.
643
+
644
+ # argument checks:
645
+ if Length(pair) <> 2 then
646
+ ErrorNoReturn("StzAddRelationNC: second argument <pair> should be a list\n",
647
+ "of length 2");
648
+ fi;
649
+ n := Length(stz!.GeneratorsOfStzPresentation);
650
+ for word in pair do
651
+ if not IsList(word) then
652
+ TryNextMethod(); # pass this on to the case where the list may be a pair
653
+ # of words in OG semigroup
654
+ elif IsEmpty(word) then
655
+ ErrorNoReturn("StzAddRelationNC: words in second argument <pair>\n",
656
+ "should be non-empty");
657
+ else
658
+ for letter in word do
659
+ if not (IsPosInt(letter) and letter <= n) then
660
+ ErrorNoReturn("StzAddRelationNC: words in second argument <pair>\n",
661
+ "should be lists of pos ints no greater than the\n",
662
+ "number of generators of first argument <stz>");
663
+ fi;
664
+ od;
665
+ fi;
666
+ od;
667
+
668
+ # WARNING: no checks are run to verify that the pair is redundant. This
669
+ # may result in an output semigroup which is non-isomorphic to the
670
+ # starting semigroup.
671
+ SEMIGROUPS.TietzeTransformation1(stz, pair);
672
+ return;
673
+ end);
674
+
675
+ InstallMethod(StzAddRelationNC,
676
+ "for an stz presentation and a pair of semigroup elements",
677
+ [IsStzPresentation, IsList],
678
+ function(stz, pair)
679
+ local s, pairwords, word;
680
+ # retrieve original semigroup
681
+ s := UnreducedFpSemigroup(stz);
682
+ for word in pair do
683
+ if not word in s then
684
+ TryNextMethod();
685
+ fi;
686
+ od;
687
+
688
+ # convert into words in original semigroup
689
+ pairwords := List(pair, UnderlyingElement);
690
+ Apply(pairwords, LetterRepAssocWord);
691
+ # map to words in new semigroup
692
+ Apply(pairwords, x -> SEMIGROUPS.StzExpandWord(x, TietzeForwardMap(stz)));
693
+
694
+ # apply tietze1, without argument checks
695
+ # WARNING: no checks are run to verify that the pair is redundant. This
696
+ # may result in an output semigroup which is non-isomorphic to the
697
+ # starting semigroup.
698
+ SEMIGROUPS.TietzeTransformation1(stz, pairwords);
699
+ return;
700
+ end);
701
+
702
+ # Tietze Transformation 2: Remove relation
703
+ InstallMethod(StzRemoveRelation,
704
+ "for an stz presentation and a pos int",
705
+ [IsStzPresentation, IsPosInt],
706
+ function(stz, index)
707
+ local rels, pair, new_f, new_gens, new_s, free_fam, w1, w2, fp_fam, p1, p2;
708
+ # <index> should be the index of the relation needing removing in the
709
+ # overall list of relations.
710
+
711
+ # argument check: valid index
712
+ rels := ShallowCopy(stz!.RelationsOfStzPresentation);
713
+ if index > Length(rels) then
714
+ ErrorNoReturn("StzRemoveRelation: second argument <index> must be less\n",
715
+ "than or equal to the number of relations of the first\n",
716
+ "argument <stz>");
717
+ fi;
718
+
719
+ # create hypothetical fp semigroup that would be the result of removing
720
+ # the requested pair
721
+ pair := rels[index];
722
+ Remove(rels, index);
723
+ new_f := FreeSemigroup(stz!.GeneratorsOfStzPresentation);
724
+ new_gens := GeneratorsOfSemigroup(new_f);
725
+ new_s := new_f / List(rels,
726
+ x -> List(x,
727
+ y -> Product(List(y,
728
+ z -> new_gens[z]))));
729
+
730
+ # create two associative words
731
+ free_fam := FamilyObj(new_f.1);
732
+ w1 := AssocWordByLetterRep(free_fam, pair[1]);
733
+ w2 := AssocWordByLetterRep(free_fam, pair[2]);
734
+
735
+ # map these words to hypothetical fp semigroup words and check equality
736
+ fp_fam := FamilyObj(new_s.1);
737
+ p1 := ElementOfFpSemigroup(fp_fam, w1);
738
+ p2 := ElementOfFpSemigroup(fp_fam, w2);
739
+
740
+ # WARNING: may run forever if undecidable
741
+ if p1 = p2 then
742
+ SEMIGROUPS.TietzeTransformation2(stz, index);
743
+ return;
744
+ else
745
+ ErrorNoReturn("StzRemoveRelation: second argument <index> must point to\n",
746
+ "a relation that is redundant in the presentation <stz>");
747
+ fi;
748
+ end);
749
+
750
+ # Tietze Transformation 2: Remove relation (NO REDUNDANCY CHECK)
751
+ InstallMethod(StzRemoveRelationNC,
752
+ "for an stz presentation and a pos int",
753
+ [IsStzPresentation, IsPosInt],
754
+ function(stz, index)
755
+ if index > Length(RelationsOfStzPresentation(stz)) then
756
+ ErrorNoReturn("StzRemoveRelationNC: second argument <index> must be less\n",
757
+ "than or equal to the number of relations of the first\n",
758
+ "argument <stz>");
759
+ fi;
760
+
761
+ # WARNING: no checks are run to verify that the pair is redundant. This
762
+ # may result in an output semigroup which is non-isomorphic to the
763
+ # starting semigroup.
764
+ SEMIGROUPS.TietzeTransformation2(stz, index);
765
+ return;
766
+ end);
767
+
768
+ # Tietze Transformation 3: Add generator
769
+ InstallMethod(StzAddGenerator,
770
+ "for an stz presentation and a LetterRep word",
771
+ [IsStzPresentation, IsList],
772
+ function(stz, word)
773
+ local n, letter;
774
+ # argument checks
775
+ if IsEmpty(word) then
776
+ ErrorNoReturn("StzAddGenerator: cannot add generator equal to the empty\n",
777
+ "word");
778
+ fi;
779
+ n := Length(GeneratorsOfStzPresentation(stz));
780
+ for letter in word do
781
+ if not (IsPosInt(letter) and letter <= n) then
782
+ # the argument has not been entered as a list of pos ints. Pass off to
783
+ # potential future methods for Tietze3, but this is likely to be a
784
+ # mistake.
785
+ ErrorNoReturn("StzAddGenerator: second argument <word> is not a\n",
786
+ "list of pos ints at most equal to the number of\n",
787
+ "generators of the first argument <stz>");
788
+ fi;
789
+ od;
790
+
791
+ # at this point all is good, so request new generator to be added with
792
+ # a new generator name auto-created.
793
+ SEMIGROUPS.TietzeTransformation3(stz, word, fail);
794
+ end);
795
+
796
+ InstallMethod(StzAddGenerator,
797
+ "for an stz presentation and a fp semigroup element",
798
+ [IsStzPresentation, IsElementOfFpSemigroup],
799
+ function(stz, word)
800
+ local letterrepword;
801
+ # argument check: word should be an element of the unreduced semigroup
802
+ # (that way we can express it as a word on the current tietze generators)
803
+ if not word in UnreducedFpSemigroup(stz) then
804
+ TryNextMethod();
805
+ fi;
806
+
807
+ # if we do have an element of s, use the forward map to express it as a word
808
+ # on the current generators, then run the original implementation of Tietze 3.
809
+ letterrepword := SEMIGROUPS.StzExpandWord(
810
+ LetterRepAssocWord(UnderlyingElement(word)),
811
+ TietzeForwardMap(stz));
812
+ StzAddGenerator(stz, letterrepword);
813
+ end);
814
+
815
+ # Tietze Transformation 3: Add generator (with specified new generator name)
816
+ InstallMethod(StzAddGenerator,
817
+ "for an stz presentation, a LetterRep word and a string",
818
+ [IsStzPresentation, IsList, IsString],
819
+ function(stz, word, name)
820
+ local n, letter;
821
+ # argument check 0: new word is non-empty
822
+ if IsEmpty(word) then
823
+ ErrorNoReturn("StzAddGenerator: cannot add generator equal to the empty\n",
824
+ "word");
825
+ fi;
826
+ # argument check 1: word is a valid word
827
+ n := Length(GeneratorsOfStzPresentation(stz));
828
+ for letter in word do
829
+ if not (IsPosInt(letter) and letter <= n) then
830
+ # the argument has not been entered as a list of pos ints. Pass off to
831
+ # potential future methods for Tietze3, but this is likely to be a
832
+ # mistake.
833
+ ErrorNoReturn("StzAddGenerator: second argument <word> is not a\n",
834
+ "list of pos ints at most equal to the number of\n",
835
+ "generators of the first argument <stz>");
836
+ fi;
837
+ od;
838
+
839
+ # argument check 2: requested generator name not yet used
840
+ if name in GeneratorsOfStzPresentation(stz) then
841
+ ErrorNoReturn("StzAddGenerator: third argument <name> should not be the\n",
842
+ "name of a pre-existing generator");
843
+ fi;
844
+
845
+ # otherwise we are all good
846
+ SEMIGROUPS.TietzeTransformation3(stz, word, name);
847
+ end);
848
+
849
+ InstallMethod(StzAddGenerator,
850
+ "for an stz presentation, a fp semigroup element and a string",
851
+ [IsStzPresentation, IsElementOfFpSemigroup, IsString],
852
+ function(stz, word, name)
853
+ local letterrepword;
854
+ # argument check: word should be an element of the unreduced semigroup
855
+ # (that way we can express it as a word on the current tietze generators)
856
+ if not word in UnreducedFpSemigroup(stz) then
857
+ TryNextMethod();
858
+ fi;
859
+
860
+ # if we do have an element of s, use the forward map to express it as a word
861
+ # on the current generators, then run the original implementation of Tietze 3.
862
+ letterrepword := SEMIGROUPS.StzExpandWord(
863
+ LetterRepAssocWord(UnderlyingElement(word)),
864
+ TietzeForwardMap(stz));
865
+ StzAddGenerator(stz, letterrepword, name);
866
+ end);
867
+
868
+ # Tietze Transformation 4: Remove generator
869
+ InstallMethod(StzRemoveGenerator,
870
+ "for an stz presentation and a positive integer",
871
+ [IsStzPresentation, IsPosInt],
872
+ function(stz, gen)
873
+ local found, index, i, rels;
874
+ # argument check 1: requested removal is potentially possible
875
+ if Length(GeneratorsOfStzPresentation(stz)) = 1 then
876
+ ErrorNoReturn("StzRemoveGenerator: cannot remove only remaining\n",
877
+ "generator \"",
878
+ GeneratorsOfStzPresentation(stz)[1],
879
+ "\"");
880
+ elif gen > Length(GeneratorsOfStzPresentation(stz)) then
881
+ ErrorNoReturn("StzRemoveGenerator: second argument <gen> must be no\n",
882
+ "greater than the total number of generators");
883
+ fi;
884
+
885
+ # argument check 2: generator can be expressed as a product of others.
886
+ # this check has to be repeated inside Tietze4, but we include it here to
887
+ # ensure that an incorrect input is clearly reported to the user.
888
+ found := false;
889
+ rels := RelationsOfStzPresentation(stz);
890
+ for i in [1 .. Length(rels)] do
891
+ if (rels[i][1] = [gen] and not gen in rels[i][2]) or
892
+ (rels[i][2] = [gen] and not gen in rels[i][1]) then
893
+ found := true;
894
+ index := i;
895
+ continue;
896
+ fi;
897
+ od;
898
+ if not found then
899
+ ErrorNoReturn("StzRemoveGenerator: there is no relation in first\n",
900
+ "argument <stz> expressing second argument <gen> as a\n",
901
+ "product of other generators");
902
+ fi;
903
+
904
+ # otherwise all good; apply internal Tietze 4 function (it will check
905
+ # whether any relation can actually express that generator as a combination
906
+ # of others)
907
+ SEMIGROUPS.TietzeTransformation4(stz, gen, index);
908
+ end);
909
+
910
+ InstallMethod(StzRemoveGenerator,
911
+ "for an stz presentation and a generator name",
912
+ [IsStzPresentation, IsString],
913
+ function(stz, genname)
914
+ local gen;
915
+ # find index of genname in stz gens
916
+ gen := Position(GeneratorsOfStzPresentation(stz), genname);
917
+ if gen = fail then
918
+ ErrorNoReturn("StzRemoveGenerator: second argument <gen> does not\n",
919
+ "correspond to a generator name in first argument <stz>");
920
+ else
921
+ StzRemoveGenerator(stz, gen);
922
+ fi;
923
+ end);
924
+
925
+ # Tietze transformation 4 with specified index (e.g. if there are several
926
+ # relations allowing the generator to be removed and the user wants a specific
927
+ # one)
928
+ InstallMethod(StzRemoveGenerator,
929
+ "for an stz presentation and two pos ints",
930
+ [IsStzPresentation, IsPosInt, IsPosInt],
931
+ function(stz, gen, index)
932
+ # first argument check: requested generator exists
933
+ if Length(GeneratorsOfStzPresentation(stz)) = 1 then
934
+ ErrorNoReturn("StzRemoveGenerator: cannot remove only remaining\n",
935
+ "generator \"",
936
+ GeneratorsOfStzPresentation(stz)[1],
937
+ "\"");
938
+ elif gen > Length(GeneratorsOfStzPresentation(stz)) then
939
+ ErrorNoReturn("StzRemoveGenerator: second argument <gen> must be no\n",
940
+ "greater than the total number of generators");
941
+ fi;
942
+
943
+ # second argument check: index exists
944
+ if index > Length(RelationsOfStzPresentation(stz)) then
945
+ ErrorNoReturn("StzRemoveGenerator: third argument <index> must be no\n",
946
+ "greater than the total number of relations in first\n",
947
+ "argument <stz>");
948
+ fi;
949
+
950
+ # third argument check: a reasonable relation number has been supplied
951
+ if (RelationsOfStzPresentation(stz)[index][1] <> [gen]
952
+ or gen in RelationsOfStzPresentation(stz)[index][2])
953
+ and (RelationsOfStzPresentation(stz)[index][2] <> [gen]
954
+ or gen in RelationsOfStzPresentation(stz)[index][1]) then
955
+ ErrorNoReturn("StzRemoveGenerator: third argument <index> does not point\n",
956
+ "to a relation expressing second argument <gen> as a\n",
957
+ "combination of other generators in first argument <stz>");
958
+ fi;
959
+
960
+ # if we made it this far then the substitution can be made
961
+ SEMIGROUPS.TietzeTransformation4(stz, gen, index);
962
+ end);
963
+
964
+ InstallMethod(StzRemoveGenerator,
965
+ "for an stz presentation, a generator name and a pos int",
966
+ [IsStzPresentation, IsString, IsPosInt],
967
+ function(stz, genname, index)
968
+ local gen;
969
+ # find index of genname in stz gens
970
+ gen := Position(GeneratorsOfStzPresentation(stz), genname);
971
+ if gen = fail then
972
+ ErrorNoReturn("StzRemoveGenerator: second argument <gen> does not\n",
973
+ "correspond to a generator name in first argument <stz>");
974
+ else
975
+ StzRemoveGenerator(stz, gen, index);
976
+ fi;
977
+ end);
978
+
979
+ # Tietze Transformation 1/2: substitute relation
980
+ InstallMethod(StzSubstituteRelation,
981
+ "for an stz presentation and two positive integers",
982
+ [IsStzPresentation, IsPosInt, IsPosInt],
983
+ function(stz, index, side)
984
+ local oldword, newword, new_rel, i;
985
+ # argument check
986
+ if index > Length(RelationsOfStzPresentation(stz)) then
987
+ ErrorNoReturn("StzSubstituteRelation: second argument <index> must be no\n",
988
+ "greater than the number of relations in first argument\n",
989
+ "<stz>");
990
+ fi;
991
+ if not side in [1, 2] then
992
+ ErrorNoReturn("StzSubstituteRelation: third argument <side> must be\n",
993
+ "either 1 or 2");
994
+ fi;
995
+
996
+ oldword := ShallowCopy(RelationsOfStzPresentation(stz)[index][side]);
997
+ newword := ShallowCopy(RelationsOfStzPresentation(stz)[index][[2, 1][side]]);
998
+
999
+ # Push relations onto the end of the stack of relations, each time replacing
1000
+ # the relation at the front by that relation, with oldword -> newword.
1001
+ # Each time, immediately delete the replaced relation at the front of the
1002
+ # stack, and do this as many times as there are relations, so that order
1003
+ # is preserved.
1004
+ # Special case for relation number <index> itself: it should not be changed.
1005
+ for i in [1 .. Length(RelationsOfStzPresentation(stz))] do
1006
+ if i = index then
1007
+ new_rel := [oldword, newword];
1008
+ else
1009
+ new_rel := List(stz!.RelationsOfStzPresentation[1],
1010
+ x -> SEMIGROUPS.StzReplaceSubwordRel(x,
1011
+ oldword,
1012
+ newword));
1013
+ fi;
1014
+ SEMIGROUPS.TietzeTransformation1(stz, new_rel);
1015
+ SEMIGROUPS.TietzeTransformation2(stz, 1);
1016
+ od;
1017
+ end);
1018
+
1019
+ ########################################################################
1020
+ # 5. Internal helper functions for word/relation manipulation etc.
1021
+ ########################################################################
1022
+
1023
+ SEMIGROUPS.StzReplaceSubword := function(rels, subword, newWord)
1024
+ local newRels, rel1, rel2, i;
1025
+
1026
+ newRels := List([1 .. Length(rels)], x -> []);
1027
+ for i in [1 .. Length(rels)] do
1028
+ rel1 := SEMIGROUPS.StzReplaceSubwordRel(rels[i][1], subword, newWord);
1029
+ rel2 := SEMIGROUPS.StzReplaceSubwordRel(rels[i][2], subword, newWord);
1030
+ newRels[i] := [rel1, rel2];
1031
+ od;
1032
+ return newRels;
1033
+ end;
1034
+
1035
+ SEMIGROUPS.StzReplaceSubwordRel := function(word, subword, newWord)
1036
+ local out, k, l, i;
1037
+ # Searches a single LetterRepAssocWord list and replaces instances of
1038
+ # subword with newWord.
1039
+
1040
+ # build word up as we read through the old word.
1041
+ out := [];
1042
+ k := Length(subword);
1043
+ l := Length(word);
1044
+ i := 1; # current index that we are looking at when trying to see subword
1045
+ while i <= l do
1046
+ if word{[i .. Minimum(i + k - 1, l)]} = subword then
1047
+ # in this, case the word starting at i needs to be substituted out.
1048
+ # (the minimum is there to make sure we don't fall off the end of word)
1049
+ Append(out, newWord);
1050
+ # jump to end of occurrence
1051
+ i := i + k;
1052
+ else
1053
+ # move over by one and append the original letter, since the word is not
1054
+ # seen here.
1055
+ Add(out, word[i]);
1056
+ i := i + 1;
1057
+ fi;
1058
+ od;
1059
+ return out;
1060
+ end;
1061
+
1062
+ # takes in a letterrep word and replaces every letter with its expression in
1063
+ # dict.
1064
+ # NOTE: does not check arguments. Assumes in good faith that every integer
1065
+ # in word has an entry in the list <dict>.
1066
+ SEMIGROUPS.StzExpandWord := function(word, dict)
1067
+ local out, letter;
1068
+ out := [];
1069
+ for letter in word do
1070
+ Append(out, dict[letter]);
1071
+ od;
1072
+ return out;
1073
+ end;
1074
+
1075
+ SEMIGROUPS.NewGeneratorName := function(names_immut)
1076
+ local alph, Alph, na, nA, names_prefx, names_suffx, int_positions, prefixes,
1077
+ prefixes_collected, p, ints, i, name, names;
1078
+ names := [];
1079
+ for name in names_immut do
1080
+ Add(names, ShallowCopy(name));
1081
+ od;
1082
+
1083
+ # useful helper variables
1084
+ alph := "abcdefghijklmnopqrstuvwxyz";
1085
+ Alph := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1086
+
1087
+ # SPECIAL CASE 0: empty list
1088
+ if IsEmpty(names) then
1089
+ return "a";
1090
+ fi;
1091
+
1092
+ # SPECIAL CASE 1: only one generator
1093
+ if Length(names) = 1 then
1094
+ if Length(names[1]) = 1 then
1095
+ if names[1][1] in Alph then
1096
+ return [First(Alph, x -> not [x] in names)];
1097
+ elif names[1][1] in alph then
1098
+ return [First(alph, x -> not [x] in names)];
1099
+ else
1100
+ return "a";
1101
+ fi;
1102
+ else
1103
+ return "a";
1104
+ fi;
1105
+ fi;
1106
+
1107
+ # SPECIAL CASE 2: single letter names are present. Add an unused letter
1108
+ # with the most common capitalisation
1109
+ na := Length(Filtered(names, x -> Length(x) = 1 and x[1] in alph));
1110
+ nA := Length(Filtered(names, x -> Length(x) = 1 and x[1] in Alph));
1111
+ if 2 <= na and na < 26 then
1112
+ if na <= nA and nA < 26 then
1113
+ return [First(Alph, x -> not [x] in names)];
1114
+ else
1115
+ return [First(alph, x -> not [x] in names)];
1116
+ fi;
1117
+ elif 2 <= nA and nA < 26 then
1118
+ return [First(Alph, x -> not [x] in names)];
1119
+ fi;
1120
+
1121
+ # SPECIAL CASE 3: there are names like s1, s3, s23, etc or x12, etc
1122
+ names_prefx := [];
1123
+ names_suffx := [];
1124
+ for name in names do
1125
+ Add(names_prefx, [name[1]]);
1126
+ Add(names_suffx, name{[2 .. Length(name)]});
1127
+ od;
1128
+ int_positions := PositionsProperty(names_suffx, x -> Int(x) <> fail
1129
+ and x <> ""
1130
+ and x[1] <> '-');
1131
+ if Length(int_positions) >= 2 then
1132
+ prefixes := names_prefx{int_positions};
1133
+ prefixes_collected := Collected(prefixes);
1134
+ # look for highest frequency in collected list
1135
+ p := prefixes_collected[PositionMaximum(prefixes_collected, x -> x[2])][1];
1136
+ # find maximum suffix int, even amongst those with prefix not p
1137
+ ints := List(names_suffx{int_positions}, Int);
1138
+ i := Maximum(ints) + 1;
1139
+ return Concatenation(p, String(i));
1140
+ fi;
1141
+
1142
+ # if none of the special cases are covered, just try s1, s2,... until good
1143
+ for i in [1 .. Length(names) + 1] do
1144
+ if not Concatenation("s", String(i)) in names then
1145
+ return Concatenation("s", String(i));
1146
+ fi;
1147
+ od;
1148
+ end;
1149
+
1150
+ # Counts the number of times a subword appears in the relations of an stz
1151
+ # presentation, ensuring that the subwords do not overlap
1152
+ # (Eg, for relations [[1,1,1,1],[1,1]], the subword [1,1] would return 3 and not
1153
+ # 4)
1154
+ SEMIGROUPS.StzCountRelationSubwords := function(stz, subWord)
1155
+ local count, relSide, rel, rels, pos, len, relSideCopy;
1156
+ rels := RelationsOfStzPresentation(stz);
1157
+ len := Length(subWord);
1158
+ count := 0;
1159
+ for rel in rels do
1160
+ for relSide in rel do
1161
+ pos := PositionSublist(relSide, subWord);
1162
+ relSideCopy := ShallowCopy(relSide);
1163
+ while pos <> fail do
1164
+ count := count + 1;
1165
+ relSideCopy := List([(pos + len) .. Length(relSideCopy)],
1166
+ x -> relSideCopy[x]);
1167
+ pos := PositionSublist(relSideCopy, subWord);
1168
+ od;
1169
+ od;
1170
+ od;
1171
+ return count;
1172
+ end;
1173
+
1174
+ # Converts an Stz presentation into an fp semigroup.
1175
+ SEMIGROUPS.StzConvertObjToFpSemigroup := function(stz)
1176
+ local F, rels, gens;
1177
+ F := FreeSemigroup(stz!.GeneratorsOfStzPresentation);
1178
+ rels := RelationsOfStzPresentation(stz);
1179
+ gens := GeneratorsOfSemigroup(F);
1180
+ return F / List(rels, x -> List(x, y -> Product(List(y, z -> gens[z]))));
1181
+ end;
1182
+
1183
+ ########################################################################
1184
+ # 6. Internal auto-checkers and appliers for presentation simplifying
1185
+ ########################################################################
1186
+
1187
+ ## Format to add a new reduction check:
1188
+ ## StzCheck: function that takes an stz presentation as input and checks all
1189
+ ## possible instances of the desired reduction, and outputs as a
1190
+ ## record the least length of the possible reductions together with
1191
+ ## the arguments required to achieve that length
1192
+ ## StzApply: function that takes an stz presentation and the above record as
1193
+ ## input and applies the arguments from the record to achieve the
1194
+ ## desired reduction
1195
+ ## Add the above two functions to the list results in StzSimplifyOnce as the
1196
+ ## pair [StzApply, StzCheck(stz)]
1197
+
1198
+ SEMIGROUPS.StzFrequentSubwordCheck := function(stz)
1199
+ local best_gain, best_word, flat, count_occurrences, n, c, gain, word,
1200
+ pair, i, j;
1201
+ # SUPER INEFFICIENT (~n^3), do something about this eventually (@Reinis?)
1202
+ # Look at every subword, count how many times it appears, and see whether
1203
+ # introducing a new generator equal to a given subword would make the
1204
+ # whole presentation shorter
1205
+ best_gain := 0; # best reduction seen so far
1206
+ best_word := []; # word currently holding record
1207
+
1208
+ # flat list of words (don't care about which one is related to which)
1209
+ flat := [];
1210
+ for pair in stz!.RelationsOfStzPresentation do
1211
+ Append(flat, ShallowCopy(pair)); # TODO(later) might not need shallow copy
1212
+ od;
1213
+
1214
+ # function to count occurrences of subword in list of lists
1215
+ count_occurrences := function(list, subword)
1216
+ local count, k, l, i, word;
1217
+ count := 0;
1218
+ k := Length(subword);
1219
+ for word in list do
1220
+ l := Length(word);
1221
+ i := 1; # index at which to start counting
1222
+ while i <= l - k + 1 do
1223
+ if word{[i .. i + k - 1]} = subword then
1224
+ count := count + 1;
1225
+ # jump to end of occurrence
1226
+ i := i + k;
1227
+ else
1228
+ # move over by one
1229
+ i := i + 1;
1230
+ fi;
1231
+ od;
1232
+ od;
1233
+ return count;
1234
+ end;
1235
+
1236
+ # now check for every subword, how many times it appears
1237
+ for word in flat do
1238
+ # N.B. ASSUMES WORDS NON-EMPTY
1239
+ n := Length(word);
1240
+ for i in [1 .. n - 1] do
1241
+ for j in [i + 1 .. n] do
1242
+ c := count_occurrences(flat, word{[i .. j]});
1243
+ # now calculate what a gain that would be:
1244
+ # subbing out every instance of word{[i .. j]} for a word of length 1
1245
+ # makes us gain j - i characters per substitution
1246
+ # BUT, we also have a new generator cost of 1
1247
+ # AND a new relation cost of 3 + j - i
1248
+ gain := (c - 1) * (j - i) - 3;
1249
+ if gain > best_gain then
1250
+ best_gain := gain;
1251
+ best_word := word{[i .. j]};
1252
+ fi;
1253
+ od;
1254
+ od;
1255
+ od;
1256
+ return rec(reduction := Length(stz) - best_gain,
1257
+ word := best_word);
1258
+ end;
1259
+
1260
+ SEMIGROUPS.StzFrequentSubwordApply := function(stz, metadata)
1261
+ local word, rels, n, gens, k, shortened_rels, new_rel, i, str, f, aWord;
1262
+
1263
+ # have received instruction to sub out metadata.word for something shorter.
1264
+ word := metadata.word;
1265
+ rels := ShallowCopy(RelationsOfStzPresentation(stz));
1266
+ n := Length(rels);
1267
+ gens := ShallowCopy(GeneratorsOfStzPresentation(stz));
1268
+ k := Length(gens);
1269
+
1270
+ # Build message
1271
+ str := "<Creating new generator to replace instances of word: ";
1272
+ f := FreeSemigroup(gens);
1273
+ aWord := AssocWordByLetterRep(FamilyObj(f.1), metadata.word);
1274
+ Append(str, PrintString(aWord));
1275
+ Append(str, ">");
1276
+ Info(InfoFpSemigroup, 2, PRINT_STRINGIFY(str));
1277
+
1278
+ # first, add new generator.
1279
+ SEMIGROUPS.TietzeTransformation3(stz, word, fail);
1280
+
1281
+ # then, go through and add loads of relations which are the old ones but
1282
+ # with the old word subbed out.
1283
+ shortened_rels := SEMIGROUPS.StzReplaceSubword(rels, word, [k + 1]);
1284
+ for new_rel in shortened_rels do
1285
+ SEMIGROUPS.TietzeTransformation1(stz, new_rel);
1286
+ od;
1287
+
1288
+ # finally, remove the original relations.
1289
+ for i in [1 .. n] do
1290
+ SEMIGROUPS.TietzeTransformation2(stz, 1);
1291
+ od;
1292
+ return;
1293
+ end;
1294
+
1295
+ # Checks each relation in the stz presentation in turn and determines if
1296
+ # replacing the longer side by the shorter side reduces the length of the
1297
+ # presentation
1298
+ SEMIGROUPS.StzRelsSubCheck := function(stz)
1299
+ local rels, currentMin, currentRel, tempRel, len, relLenDiff, numInstances,
1300
+ newLen, i;
1301
+ rels := RelationsOfStzPresentation(stz);
1302
+ currentMin := Length(stz);
1303
+ currentRel := 0;
1304
+ for i in [1 .. Length(rels)] do
1305
+ tempRel := ShallowCopy(rels[i]);
1306
+ SortBy(tempRel, Length);
1307
+ len := Length(stz);
1308
+ relLenDiff := Length(tempRel[2]) - Length(tempRel[1]);
1309
+ numInstances := SEMIGROUPS.StzCountRelationSubwords(stz, tempRel[2]) - 1;
1310
+ newLen := len - numInstances * relLenDiff;
1311
+ if newLen < currentMin then
1312
+ currentMin := newLen;
1313
+ currentRel := i;
1314
+ fi;
1315
+ od;
1316
+ return rec(reduction := currentMin,
1317
+ argument := currentRel);
1318
+ end;
1319
+
1320
+ # Checks each relation of the stz presentation to see if any are of the form
1321
+ # a = w, where a is a generator and w is a word not containing a, then
1322
+ # determines the length if the generator and relation were removed
1323
+ SEMIGROUPS.StzRedundantGeneratorCheck := function(stz)
1324
+ local rel, rels, numInstances, relPos, tempPositions, r, out, redLen,
1325
+ genToRemove, wordToReplace, foundRedundant, currentMin, currentGen,
1326
+ currentRel;
1327
+ rels := RelationsOfStzPresentation(stz);
1328
+ out := [];
1329
+ currentMin := Length(stz);
1330
+ currentGen := 0;
1331
+ currentRel := 0;
1332
+ for rel in rels do
1333
+ foundRedundant := false;
1334
+ if Length(rel[1]) = 1 and Length(rel[2]) = 1 and rel[1] <> rel[2] then
1335
+ genToRemove := rel[1][1];
1336
+ wordToReplace := rel[2];
1337
+ Append(out, [Length(stz) - 3]);
1338
+ if Length(stz) - 3 < currentMin then
1339
+ currentMin := Length(stz) - 3;
1340
+ currentGen := genToRemove;
1341
+ currentRel := Position(rels, rel);
1342
+ fi;
1343
+ continue;
1344
+ elif Length(rel[1]) = 1 and Length(rel[2]) > 1 and
1345
+ (not (rel[1][1] in rel[2])) then
1346
+ genToRemove := rel[1][1];
1347
+ wordToReplace := rel[2];
1348
+ foundRedundant := true;
1349
+ elif Length(rel[2]) = 1 and Length(rel[1]) > 1 and
1350
+ (not (rel[2][1] in rel[1])) then
1351
+ genToRemove := rel[2][1];
1352
+ wordToReplace := rel[1];
1353
+ foundRedundant := true;
1354
+ fi;
1355
+ if foundRedundant then
1356
+ relPos := Position(rels, rel);
1357
+ numInstances := 0;
1358
+ for r in Concatenation([1 .. relPos - 1], [relPos + 1 .. Length(rels)]) do
1359
+ tempPositions := Length(Positions(Concatenation(rels[r][1], rels[r][2]),
1360
+ genToRemove));
1361
+ numInstances := numInstances + tempPositions;
1362
+ od;
1363
+ redLen := Length(stz) + (numInstances * (Length(wordToReplace) - 1)) -
1364
+ 2 - Length(wordToReplace);
1365
+ if redLen < currentMin then
1366
+ currentMin := redLen;
1367
+ currentGen := genToRemove;
1368
+ currentRel := Position(rels, rel);
1369
+ fi;
1370
+ fi;
1371
+ od;
1372
+ return rec(reduction := currentMin,
1373
+ argument := currentGen,
1374
+ infoRel := currentRel);
1375
+ end;
1376
+
1377
+ # Checks each relation to determine if it is a direct duplicate of another
1378
+ # (ie does not check equivalence in terms of other relations, just whether they
1379
+ # are literally the same relation)
1380
+ SEMIGROUPS.StzDuplicateRelsCheck := function(stz)
1381
+ local rel, rels, i, tempRel, j, currentMin, currentRel, len;
1382
+ rels := RelationsOfStzPresentation(stz);
1383
+ currentMin := Length(stz);
1384
+ currentRel := 0;
1385
+ if Length(rels) < 2 then
1386
+ return rec(reduction := Length(stz),
1387
+ argument := 1);
1388
+ else
1389
+ for j in [1 .. Length(rels)] do
1390
+ rel := rels[j];
1391
+ for i in Concatenation([1 .. j - 1],
1392
+ [j + 1 .. Length(rels)]) do
1393
+ tempRel := rels[i];
1394
+ if (tempRel[1] = rel[1] and tempRel[2] = rel[2]) or
1395
+ (tempRel[1] = rel[2] and tempRel[2] = rel[1]) then
1396
+ len := Length(stz) - Length(rel[1]) - Length(rel[2]);
1397
+ if len < currentMin then
1398
+ currentMin := len;
1399
+ currentRel := j;
1400
+ fi;
1401
+ fi;
1402
+ od;
1403
+ od;
1404
+ return rec(reduction := currentMin,
1405
+ argument := currentRel);
1406
+ fi;
1407
+ end;
1408
+
1409
+ # Checks each relation to determine if any are of the form w = w, where w is a
1410
+ # word over the generators
1411
+ SEMIGROUPS.StzTrivialRelationCheck := function(stz)
1412
+ local rels, len, i, currentMin, currentRel, newLen;
1413
+ rels := RelationsOfStzPresentation(stz);
1414
+ len := Length(stz);
1415
+ currentMin := len;
1416
+ currentRel := 0;
1417
+ for i in [1 .. Length(rels)] do
1418
+ if rels[i][1] = rels[i][2] then
1419
+ newLen := len - Length(rels[i][1]) - Length(rels[i][2]);
1420
+ if newLen < currentMin then
1421
+ currentMin := newLen;
1422
+ currentRel := i;
1423
+ fi;
1424
+ fi;
1425
+ od;
1426
+ return rec(reduction := currentMin,
1427
+ argument := currentRel);
1428
+ end;
1429
+
1430
+ # Removes a trivial relation
1431
+ SEMIGROUPS.StzTrivialRelationApply := function(stz, args)
1432
+ local str;
1433
+ str := "<Removing trivial relation: ";
1434
+ Append(str, SEMIGROUPS.StzRelationDisplayString(stz, args.argument));
1435
+ Append(str, ">");
1436
+ Info(InfoFpSemigroup, 2, PRINT_STRINGIFY(str));
1437
+ SEMIGROUPS.TietzeTransformation2(stz, args.argument);
1438
+ end;
1439
+
1440
+ # Removes a duplicated relation
1441
+ SEMIGROUPS.StzDuplicateRelsApply := function(stz, args)
1442
+ local str;
1443
+ str := "<Removing duplicate relation: ";
1444
+ Append(str, SEMIGROUPS.StzRelationDisplayString(stz, args.argument));
1445
+ Append(str, ">");
1446
+ Info(InfoFpSemigroup, 2, PRINT_STRINGIFY(str));
1447
+ SEMIGROUPS.TietzeTransformation2(stz, args.argument);
1448
+ end;
1449
+
1450
+ # Removes a redundant generator
1451
+ SEMIGROUPS.StzGensRedundantApply := function(stz, args)
1452
+ local str;
1453
+ str := "<Removing redundant generator ";
1454
+ Append(str, GeneratorsOfStzPresentation(stz)[args.argument]);
1455
+ Append(str, " using relation : ");
1456
+ Append(str, SEMIGROUPS.StzRelationDisplayString(stz, args.infoRel));
1457
+ Append(str, ">");
1458
+ Info(InfoFpSemigroup, 2, PRINT_STRINGIFY(str));
1459
+ SEMIGROUPS.TietzeTransformation4(stz, args.argument, args.infoRel);
1460
+ end;
1461
+
1462
+ # Replaces all instances of one side of a relation with the other inside each
1463
+ # other relation
1464
+ SEMIGROUPS.StzRelsSubApply := function(stz, args)
1465
+ local str, relIndex, rels, rel, subword, replaceWord, containsRel, newRel, i,
1466
+ j;
1467
+ str := "<Replacing all instances in other relations of relation: ";
1468
+ Append(str, SEMIGROUPS.StzRelationDisplayString(stz, args.argument));
1469
+ Append(str, ">");
1470
+ Info(InfoFpSemigroup, 2, PRINT_STRINGIFY(str));
1471
+
1472
+ relIndex := args.argument;
1473
+ rels := RelationsOfStzPresentation(stz);
1474
+ rel := ShallowCopy(rels[relIndex]);
1475
+ SortBy(rel, Length);
1476
+ # TODO(later) line above: potential edge cases where we are not substituting
1477
+ # the longer for the shorter, but rather two words of equal length? I guess
1478
+ # not, since the checker function would only suggest this applier function if
1479
+ # there was an actual reduction? In that case, careful to use correctly
1480
+
1481
+ # record words to sub out (one we are searching for) and to replace with
1482
+ subword := rel[2];
1483
+ replaceWord := rel[1];
1484
+
1485
+ # keep track of relation indices where we substituted
1486
+ containsRel := [];
1487
+ for i in [1 .. Length(rels)] do
1488
+ if i <> relIndex and
1489
+ (PositionSublist(rels[i][1], subword) <> fail or
1490
+ PositionSublist(rels[i][2], subword) <> fail) then
1491
+ Add(containsRel, i);
1492
+ fi;
1493
+ od;
1494
+
1495
+ for i in containsRel do
1496
+ newRel := List([1 .. 2], x -> ShallowCopy(rels[i][x]));
1497
+ newRel := List(newRel, x -> SEMIGROUPS.StzReplaceSubwordRel(x, subword,
1498
+ replaceWord));
1499
+ SEMIGROUPS.TietzeTransformation1(stz, newRel);
1500
+ od;
1501
+ for j in [1 .. Length(containsRel)] do
1502
+ SEMIGROUPS.TietzeTransformation2(stz, containsRel[j]);
1503
+ containsRel := containsRel - 1;
1504
+ od;
1505
+ end;
1506
+
1507
+ ########################################################################
1508
+ # 7. SimplifyPresentation etc.
1509
+ ########################################################################
1510
+
1511
+ InstallMethod(StzSimplifyOnce,
1512
+ [IsStzPresentation],
1513
+ function(stz)
1514
+ local rels, results, len, mins, result, func, args;
1515
+ rels := RelationsOfStzPresentation(stz);
1516
+ if IsEmpty(rels) then
1517
+ return false;
1518
+ else
1519
+ results := [[SEMIGROUPS.StzGensRedundantApply,
1520
+ SEMIGROUPS.StzRedundantGeneratorCheck(stz)],
1521
+ [SEMIGROUPS.StzDuplicateRelsApply,
1522
+ SEMIGROUPS.StzDuplicateRelsCheck(stz)],
1523
+ [SEMIGROUPS.StzRelsSubApply,
1524
+ SEMIGROUPS.StzRelsSubCheck(stz)],
1525
+ [SEMIGROUPS.StzFrequentSubwordApply,
1526
+ SEMIGROUPS.StzFrequentSubwordCheck(stz)],
1527
+ [SEMIGROUPS.StzTrivialRelationApply,
1528
+ SEMIGROUPS.StzTrivialRelationCheck(stz)]];
1529
+ len := Length(stz);
1530
+ mins := List(results, x -> x[2].reduction);
1531
+ if Minimum(mins) < len then
1532
+ result := results[Position(mins, Minimum(mins))];
1533
+ func := result[1];
1534
+ args := result[2];
1535
+ func(stz, args);
1536
+ return true;
1537
+ fi;
1538
+ return false;
1539
+ fi;
1540
+ end);
1541
+
1542
+ InstallMethod(StzSimplifyPresentation,
1543
+ [IsStzPresentation],
1544
+ function(stz)
1545
+ local transformApplied;
1546
+ transformApplied := true;
1547
+ Info(InfoFpSemigroup, 2, "Applying StzSimplifyPresentation...");
1548
+ Info(InfoFpSemigroup, 2, "StzSimplifyPresentation is verbose by default. ",
1549
+ "Use SetInfoLevel(InfoFpSemigroup, 1) to hide");
1550
+ Info(InfoFpSemigroup, 2, "output while maintaining ability to use ",
1551
+ "StzPrintRelations, StzPrintGenerators, etc.");
1552
+ Info(InfoFpSemigroup, 2, Concatenation("Current: ", ViewString(stz)));
1553
+ while transformApplied do
1554
+ transformApplied := StzSimplifyOnce(stz);
1555
+ if transformApplied then
1556
+ Info(InfoFpSemigroup, 2, Concatenation("Current: ", ViewString(stz)));
1557
+ fi;
1558
+ od;
1559
+ end);
1560
+
1561
+ InstallMethod(SimplifiedFpSemigroup,
1562
+ [IsFpSemigroup],
1563
+ function(S)
1564
+ local T, map;
1565
+ map := SimplifyFpSemigroup(S);
1566
+ T := Range(map);
1567
+ SetUnreducedFpSemigroup(T, S);
1568
+ SetFpTietzeIsomorphism(T, map);
1569
+ return T;
1570
+ end);
1571
+
1572
+ InstallMethod(SimplifyFpSemigroup, "for an f.p. semigroup", [IsFpSemigroup],
1573
+ function(S)
1574
+ local stz;
1575
+ stz := StzPresentation(S);
1576
+ StzSimplifyPresentation(stz);
1577
+ return StzIsomorphism(stz);
1578
+ end);