passagemath-gap-pkg-semigroups 10.6.30__cp312-abi3-macosx_13_0_arm64.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 (354) 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/aarch64-apple-darwin23-default64-kv10/semigroups.so +0 -0
  15. gap/pkg/semigroups/config.guess +1807 -0
  16. gap/pkg/semigroups/config.log +1158 -0
  17. gap/pkg/semigroups/config.status +1131 -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.30.dist-info/METADATA +93 -0
  347. passagemath_gap_pkg_semigroups-10.6.30.dist-info/METADATA.bak +94 -0
  348. passagemath_gap_pkg_semigroups-10.6.30.dist-info/RECORD +354 -0
  349. passagemath_gap_pkg_semigroups-10.6.30.dist-info/WHEEL +6 -0
  350. passagemath_gap_pkg_semigroups-10.6.30.dist-info/top_level.txt +1 -0
  351. passagemath_gap_pkg_semigroups.dylibs/libsemigroups.2.dylib +0 -0
  352. sage/all__sagemath_gap_pkg_semigroups.py +1 -0
  353. sage/libs/all__sagemath_gap_pkg_semigroups.py +1 -0
  354. sage/libs/gap_pkg_semigroups.abi3.so +0 -0
@@ -0,0 +1,1876 @@
1
+ #############################################################################
2
+ ##
3
+ ## attributes/maximal.gi
4
+ ## Copyright (C) 2013-2022 James D. Mitchell
5
+ ## Wilf A. Wilson
6
+ ##
7
+ ## Licensing information can be found in the README file of this package.
8
+ ##
9
+ #############################################################################
10
+ ##
11
+
12
+ # WAW A more complicated version incorporating some maximal subsemigroup theory
13
+ # did not seem to perform significantly better, and so was removed.
14
+
15
+ InstallMethod(IsMaximalSubsemigroup, "for a semigroup and a semigroup",
16
+ [IsSemigroup, IsSemigroup],
17
+ function(S, T)
18
+ local gens;
19
+ if IsSubsemigroup(S, T) and S <> T then
20
+ if not IsFinite(S) then
21
+ TryNextMethod();
22
+ fi;
23
+ gens := GeneratorsOfSemigroup(T);
24
+ return ForAll(S, x -> x in T or Semigroup(gens, x) = S);
25
+ fi;
26
+ return false;
27
+ end);
28
+
29
+ # NrMaximalSubsemigroups:
30
+ # uses MaximalSubsemigroups algorithm without creating the semigroups themselves
31
+
32
+ InstallMethod(NrMaximalSubsemigroups,
33
+ "for a semigroup with known maximal subsemigroups",
34
+ [IsSemigroup and HasMaximalSubsemigroups],
35
+ S -> Length(MaximalSubsemigroups(S)));
36
+
37
+ InstallMethod(NrMaximalSubsemigroups, "for a semigroup", [IsSemigroup],
38
+ S -> MaximalSubsemigroupsNC(S, rec(number := true)));
39
+
40
+ InstallMethod(MaximalSubsemigroups, "for a semigroup", [IsSemigroup],
41
+ S -> MaximalSubsemigroupsNC(S, rec(number := false)));
42
+
43
+ # MaximalSubsemigroups(S, r):
44
+ #
45
+ # - <r.number>: (true) count the maximal subsemigroups;
46
+ # (false) create the maximal subsemigroups (default).
47
+ # - <r.gens>: relevant only if <r.number> is false:
48
+ # (true) return the results as generating sets;
49
+ # (false) return the results as semigroup objects (default).
50
+ # - <r.contain>: a duplicate-free subset of S:
51
+ # find only those maximal subsemigps which contain <r.contain>.
52
+ # - <r.D>: a D-class of S:
53
+ # a maximal subsemigroup of a finite semigroup lacks part of
54
+ # only one D-class. With this option, the function will find
55
+ # only maximal subsemigroups which lack part of <r.D>.
56
+ # - <r.types>: relevant only if S is a Rees (0-)matrix semigroup:
57
+ # a subset of [1 .. 6], enumerating the types to find.
58
+ # (see paper in preparation for a description of each type)
59
+ # - <r.zero>: not user-facing! relevant when S is an RZMS & <r.gens> is true:
60
+ # (true) include all generators, which may include 0 (default).
61
+ # (false) remove 0 from each generating set, if present.
62
+
63
+ InstallMethod(MaximalSubsemigroups, "for a semigroup and a record",
64
+ [IsSemigroup, IsRecord],
65
+ function(S, r)
66
+ local opts, x;
67
+
68
+ if not IsFinite(S) then
69
+ Info(InfoSemigroups, 1, "This method only works for finite semigroups");
70
+ TryNextMethod();
71
+ fi;
72
+
73
+ opts := rec();
74
+
75
+ # <rec.number> should be a boolean
76
+ if IsBound(r.number) then
77
+ if not IsBool(r.number) then
78
+ ErrorNoReturn("the record component <number> of the optional 2nd ",
79
+ "argument <r> should be true or false");
80
+ fi;
81
+ opts.number := r.number;
82
+ else
83
+ opts.number := false;
84
+ fi;
85
+
86
+ # <rec.contain> should be a duplicate-free subset of <S>
87
+ if IsBound(r.contain) then
88
+ if not IsHomogeneousList(r.contain)
89
+ or not IsDuplicateFreeList(r.contain)
90
+ or not ForAll(r.contain, x -> x in S) then
91
+ ErrorNoReturn("the record component <contain> of the optional 2nd ",
92
+ "argument <r> should be a duplicate-free list of ",
93
+ "elements of the semigroup in the 1st argument, <S>");
94
+ fi;
95
+ opts.contain := r.contain;
96
+ else
97
+ opts.contain := [];
98
+ fi;
99
+
100
+ # <rec.D> should be a D-class of <S>
101
+ if IsBound(r.D) then
102
+ if not IsGreensDClass(r.D) or not Parent(r.D) = S then
103
+ ErrorNoReturn("the record component <D> of the optional 2nd ",
104
+ "argument <r> should be a D-class of the semigroup in ",
105
+ "the 1st argument, <S>");
106
+ fi;
107
+ opts.D := r.D;
108
+ fi;
109
+
110
+ # <rec.types> should be a duplicate-free subset of [1 .. 6]
111
+ if IsBound(r.types) then
112
+ if not (IsReesMatrixSemigroup(S) or IsReesZeroMatrixSemigroup(S))
113
+ or not IsGroupAsSemigroup(UnderlyingSemigroup(S))
114
+ or not IsRegularSemigroup(S) then
115
+ Info(InfoSemigroups, 2, "the option 'types' is relevant only if <S> is ",
116
+ "a regular Rees (0-)matrix semigroup over a group");
117
+ else
118
+ if not IsHomogeneousList(r.types)
119
+ or not IsDuplicateFreeList(r.types)
120
+ or not IsSubset([1 .. 6], r.types) then
121
+ ErrorNoReturn("the record component <types> of the optional 2nd ",
122
+ "argument <r> should be a subset of [ 1 .. 6 ]");
123
+ fi;
124
+
125
+ if IsReesMatrixSemigroup(S) then
126
+ # types 1, 2, and 5 are irrelevant to a RMS
127
+ x := Intersection([1, 2, 5], r.types);
128
+ if not IsEmpty(x) then
129
+ Info(InfoSemigroups, 2, "a Rees matrix semigroup has no maximal ",
130
+ "subsemigroups of types ", x);
131
+ fi;
132
+ fi;
133
+ opts.types := r.types;
134
+ fi;
135
+ else
136
+ opts.types := [1 .. 6];
137
+ fi;
138
+
139
+ # <rec.gens> should be <true> or <false>
140
+ if IsBound(r.gens) then
141
+ if not IsBool(r.gens) then
142
+ ErrorNoReturn("the record component <gens> of the optional 2nd ",
143
+ "argument <r> should be true or false");
144
+ fi;
145
+ opts.gens := r.gens;
146
+ else
147
+ opts.gens := false;
148
+ fi;
149
+
150
+ return MaximalSubsemigroupsNC(S, opts);
151
+ end);
152
+
153
+ # MaximalSubsemigroupsNC for an RMS and a record:
154
+ # The following method comes from Remark 1 of Graham, Graham, and Rhodes '68.
155
+ # It only works for a finite Rees matrix semigroup over a group.
156
+ # The possible options record components are specified above.
157
+
158
+ InstallMethod(MaximalSubsemigroupsNC,
159
+ "for a Rees matrix subsemigroup and a record",
160
+ [IsReesMatrixSubsemigroup, IsRecord],
161
+ function(R, opts)
162
+ local type, contain, mat, rows, cols, I, L, G, out, tot, lookup_rows, remove,
163
+ i, x, n, lookup_cols, subgroups, iso, inv, R_n, G_k, iso_p, inv_p, invert, t,
164
+ trans, gens, H, l;
165
+
166
+ if not IsFinite(R)
167
+ or not IsReesMatrixSemigroup(R)
168
+ or not IsGroupAsSemigroup(UnderlyingSemigroup(R)) then
169
+ TryNextMethod();
170
+ fi;
171
+
172
+ opts := ShallowCopy(opts); # in case <opts> is immutable
173
+
174
+ # Bind default options
175
+ if not IsBound(opts.number) then
176
+ opts.number := false;
177
+ fi;
178
+ if not IsBound(opts.gens) then
179
+ opts.gens := false;
180
+ fi;
181
+ if not IsBound(opts.types) then
182
+ opts.types := [3, 4, 6];
183
+ fi;
184
+ type := BlistList([1 .. 6], opts.types);
185
+ # A RMS over a group only has one D-class, so <opts.D> is irrelevant
186
+ if not IsBound(opts.contain) then
187
+ contain := [];
188
+ else
189
+ contain := opts.contain;
190
+ fi;
191
+
192
+ mat := Matrix(R);
193
+ rows := Rows(R);
194
+ cols := Columns(R);
195
+ I := Length(rows);
196
+ L := Length(cols);
197
+ G := UnderlyingSemigroup(R);
198
+
199
+ out := [];
200
+ tot := 0;
201
+
202
+ # Maximal subsemigroups equal to I x G x L', where L' = L \ {l} for some l
203
+ # These are the maximal subsemigroups of R of type (iv)
204
+ if type[3] then
205
+ Info(InfoSemigroups, 2, "Type 3: looking for maximal subsemigroups ",
206
+ "formed by discarding a column...");
207
+ if L > 1 then
208
+ lookup_cols := EmptyPlist(Maximum(cols));
209
+ for i in [1 .. L] do
210
+ lookup_cols[cols[i]] := i;
211
+ od;
212
+ remove := BlistList(Columns(R), Columns(R));
213
+ i := 0;
214
+ while i < Length(contain) and SizeBlist(remove) > 0 do
215
+ i := i + 1;
216
+ x := contain[i];
217
+ remove[lookup_cols[x![3]]] := false;
218
+ od;
219
+ n := SizeBlist(remove);
220
+ fi;
221
+ if L > 1 and n > 0 then
222
+ Info(InfoSemigroups, 2, "...found ", n, " result(s).");
223
+ tot := tot + n;
224
+ if not opts.number then
225
+ Info(InfoSemigroups, 2, "...creating these maximal subsemigroups.");
226
+ for l in ListBlist(cols, remove) do
227
+ x := Difference(cols, [l]);
228
+ x := ReesMatrixSubsemigroupNC(R, rows, G, x);
229
+ if opts.gens then
230
+ x := GeneratorsOfSemigroup(x);
231
+ fi;
232
+ Add(out, x);
233
+ od;
234
+ fi;
235
+ else
236
+ Info(InfoSemigroups, 2, "...found none.");
237
+ fi;
238
+ fi;
239
+
240
+ # Maximal subsemigroups equal to I' x G x L, where I' = I \ {i} for some i
241
+ # These are the maximal subsemigroups of R of type (iii)
242
+ if type[4] then
243
+ Info(InfoSemigroups, 2, "Type 4: looking for maximal subsemigroups ",
244
+ "formed by discarding a row...");
245
+ if I > 1 then
246
+ # A row can be removed iff it doesn't intersect <contain>.
247
+ lookup_rows := EmptyPlist(Maximum(rows));
248
+ for i in [1 .. I] do
249
+ lookup_rows[rows[i]] := i;
250
+ od;
251
+ remove := BlistList(rows, rows);
252
+ i := 0;
253
+ while i < Length(contain) and SizeBlist(remove) > 0 do
254
+ i := i + 1;
255
+ x := contain[i];
256
+ remove[lookup_rows[x![1]]] := false;
257
+ od;
258
+ n := SizeBlist(remove);
259
+ fi;
260
+ if I > 1 and n > 0 then
261
+ Info(InfoSemigroups, 2, "...found ", n, " result(s).");
262
+ tot := tot + n;
263
+ if not opts.number then
264
+ Info(InfoSemigroups, 2, "...creating these maximal subsemigroups.");
265
+ for i in ListBlist(rows, remove) do
266
+ x := Difference(rows, [i]);
267
+ x := ReesMatrixSubsemigroupNC(R, x, G, cols);
268
+ if opts.gens then
269
+ x := GeneratorsOfSemigroup(x);
270
+ fi;
271
+ Add(out, x);
272
+ od;
273
+ fi;
274
+ else
275
+ Info(InfoSemigroups, 2, "...found none.");
276
+ fi;
277
+ fi;
278
+
279
+ # Maximal subsemigroups isomorphic to I x H x L, where H < G is maximal.
280
+ # These are the maximal subsemigroups of R of type (vi)
281
+ if type[6] then
282
+ Info(InfoSemigroups, 2, "Type 6: looking for maximal subsemigroups ",
283
+ "arising from maximal subgroups...");
284
+ subgroups := [];
285
+ if not IsTrivial(G) then
286
+ iso := RMSNormalization(R); # The normalization of R
287
+ inv := InverseGeneralMapping(iso); # The normalization inverse
288
+ R_n := Range(iso); # R (normalized)
289
+ G_k := ShallowCopy(MatrixEntries(R_n)); # Gens of the idempotent group
290
+
291
+ if IsGroup(G) then
292
+ iso_p := IdentityMapping(G);
293
+ inv_p := iso_p;
294
+ invert := InverseOp;
295
+ else # We need to use methods that apply only to IsGroup, e.g. Normalizer
296
+ iso_p := IsomorphismPermGroup(G);
297
+ inv_p := InverseGeneralMapping(iso_p);
298
+ invert := x -> ((x ^ iso_p) ^ -1) ^ inv_p;
299
+ G := Range(iso_p);
300
+ G_k := List(G_k, x -> x ^ iso_p);
301
+ fi;
302
+
303
+ i := 0;
304
+ x := Group(G_k);
305
+ while i < Length(contain) and Size(x) < Size(G) do
306
+ i := i + 1;
307
+ t := UnderlyingElementOfReesMatrixSemigroupElement(contain[i] ^ iso);
308
+ t := t ^ iso_p;
309
+ x := ClosureGroup(x, t);
310
+ AddSet(G_k, t);
311
+ od;
312
+
313
+ if Size(x) < Size(G) then # Otherwise there are no results
314
+ for H in MaximalSubgroupClassReps(G) do
315
+ trans := RightTransversal(G, Normalizer(G, H));
316
+ for t in trans do
317
+ if ForAll(G_k, x -> x ^ (t ^ -1) in H) then
318
+ # A maximal subsemigroup has been found arising from H ^ t
319
+ Add(subgroups, [H, t]);
320
+ fi;
321
+ od;
322
+ od;
323
+ fi;
324
+ fi;
325
+ if Length(subgroups) > 0 then
326
+ Info(InfoSemigroups, 2, "...found ", Length(subgroups), " result(s).");
327
+ tot := tot + Length(subgroups);
328
+ if not opts.number then
329
+ Info(InfoSemigroups, 2, "...creating these maximal subsemigroups.");
330
+ gens := [];
331
+ # These 3 loops ensure a small generating set
332
+ for i in [2 .. Minimum(I, L)] do
333
+ Add(gens, RMSElement(R, rows[i], invert(mat[i][i]), cols[i]));
334
+ od;
335
+ for i in [L + 1 .. I] do
336
+ Add(gens, RMSElement(R, rows[i], invert(mat[1][i]), cols[1]));
337
+ od;
338
+ for l in [I + 1 .. L] do
339
+ Add(gens, RMSElement(R, rows[1], invert(mat[l][1]), cols[l]));
340
+ od;
341
+ for x in subgroups do
342
+ H := x[1];
343
+ t := x[2];
344
+ x := List(GeneratorsOfSemigroup(H), x ->
345
+ RMSElement(R_n, 1, (x ^ t) ^ inv_p, 1) ^ inv);
346
+ Append(x, gens);
347
+ if not opts.gens then
348
+ x := Semigroup(x);
349
+ fi;
350
+ Add(out, x);
351
+ od;
352
+ fi;
353
+ else
354
+ Info(InfoSemigroups, 2, "...found none.");
355
+ fi;
356
+ fi;
357
+
358
+ if opts.number then
359
+ return tot;
360
+ fi;
361
+ return out;
362
+ end);
363
+
364
+ # MaximalSubsemigroupsNC for an RZMS and a record:
365
+ # The following method comes from Remark 1 in Graham, Graham, and Rhodes.
366
+ # It only works for a regular Rees 0-matrix semigroup over a group
367
+ # The required record components are given above.
368
+
369
+ InstallMethod(MaximalSubsemigroupsNC,
370
+ "for a Rees 0-matrix subsemigroup and a record",
371
+ [IsReesZeroMatrixSubsemigroup, IsRecord],
372
+ function(R, opts)
373
+ local zero, x, type, contain, mat, rows, cols, I, L, G, lookup_cols,
374
+ lookup_rows, out, tot, dig, pos, remove, i, n, nbs, deg, l, r, dig_contain,
375
+ count, rectangles, bicomp_I, bicomp_L, b, invert, gens, one, reps, i1, l1, a,
376
+ H1, l2, i2, H2, rows_in, rows_out, cols_in, cols_out, failed, iso, inv, R_n,
377
+ iso_p, inv_p, ccs, comp_row, comp_col, comp, con, sup, m, lim, P, max, q,
378
+ same_coset, results, V, normal, trans, len, T, success, visited, conjugator,
379
+ queue, u, candidate, idems, recursion, genset, k, j, t, v, choice, gen;
380
+
381
+ if not IsFinite(R)
382
+ or not IsReesZeroMatrixSemigroup(R)
383
+ or not IsGroupAsSemigroup(UnderlyingSemigroup(R))
384
+ or not IsRegularSemigroup(R) then
385
+ TryNextMethod();
386
+ fi;
387
+
388
+ zero := MultiplicativeZero(R);
389
+
390
+ opts := ShallowCopy(opts); # in case <opts> is immutable
391
+
392
+ # Bind default options
393
+ if not IsBound(opts.number) then
394
+ opts.number := false;
395
+ fi;
396
+ if not IsBound(opts.gens) then
397
+ opts.gens := false;
398
+ fi;
399
+ if not IsBound(opts.types) then
400
+ opts.types := [1 .. 6];
401
+ fi;
402
+ if not IsBound(opts.zero) then
403
+ opts.zero := true;
404
+ fi;
405
+ if IsBound(opts.D) then
406
+ # A regular RZMS over a group has two D-classes: {0} and R\{0}.
407
+ x := Representative(opts.D);
408
+ if x = zero then
409
+ opts.types := Intersection(opts.types, [2]);
410
+ else
411
+ opts.types := Intersection(opts.types, [1, 3, 4, 5, 6]);
412
+ fi;
413
+ fi;
414
+ type := BlistList([1 .. 6], opts.types);
415
+ if not IsBound(opts.contain) then
416
+ contain := [];
417
+ else
418
+ contain := opts.contain;
419
+ fi;
420
+
421
+ mat := Matrix(R);
422
+ rows := Rows(R);
423
+ cols := Columns(R);
424
+ I := Length(rows);
425
+ L := Length(cols);
426
+ G := UnderlyingSemigroup(R);
427
+
428
+ lookup_cols := EmptyPlist(Maximum(cols));
429
+ for i in [1 .. L] do
430
+ lookup_cols[cols[i]] := i;
431
+ od;
432
+ lookup_rows := EmptyPlist(Maximum(rows));
433
+ for i in [1 .. I] do
434
+ lookup_rows[rows[i]] := i;
435
+ od;
436
+
437
+ out := [];
438
+ tot := 0;
439
+
440
+ # Type 1: The maximal subsemigroup {0}.
441
+
442
+ # {0} is a maximal subsemigroup if and only if R is the 2-element semilattice
443
+ if type[1] then
444
+ Info(InfoSemigroups, 2, "Type 1: looking for a maximal subsemigroup {0}",
445
+ "...");
446
+ if I = 1 and L = 1 and IsTrivial(G) and IsSubset([zero], contain) then
447
+ tot := tot + 1;
448
+ if not opts.number then
449
+ if opts.gens then
450
+ if opts.zero then
451
+ Add(out, [zero]);
452
+ else
453
+ Add(out, []);
454
+ fi;
455
+ else
456
+ Add(out, Semigroup(zero));
457
+ fi;
458
+ fi;
459
+ Info(InfoSemigroups, 2, "...found one result.");
460
+ else
461
+ Info(InfoSemigroups, 2, "...found none.");
462
+ fi;
463
+ fi;
464
+
465
+ # Type 2: The maximal subsemigroup R \ {0}.
466
+
467
+ # R \ {0} is a maximal subsemigroup...
468
+ # if and only if <mat> contains no 0 entry
469
+ # if and only if the Graham-Houghton bipartite graph is complete
470
+ if type[2] then
471
+ Info(InfoSemigroups, 2, "Type 2: looking for a maximal subsemigroup ",
472
+ "formed by discarding 0...");
473
+ dig := RZMSDigraph(R);
474
+ if IsCompleteBipartiteDigraph(dig) and not zero in contain then
475
+ tot := tot + 1;
476
+ if not opts.number then
477
+ if opts.gens then
478
+ x := ShallowCopy(GeneratorsOfSemigroup(R));
479
+ # The 0 of <R> is necessarily contained in x
480
+ pos := Position(x, zero);
481
+ Remove(x, pos);
482
+ else
483
+ x := ReesZeroMatrixSubsemigroupNC(R, rows, G, cols);
484
+ fi;
485
+ Add(out, x);
486
+ fi;
487
+ Info(InfoSemigroups, 2, "...found one result.");
488
+ else
489
+ Info(InfoSemigroups, 2, "...found none.");
490
+ fi;
491
+ fi;
492
+
493
+ # All other maximal subsemigroups contain 0, so remove it from <contain>.
494
+ pos := Position(contain, zero);
495
+ if pos <> fail then
496
+ Remove(contain, pos);
497
+ fi;
498
+
499
+ # Type 3: Maximal subsemigroups I x G x L' + {0} where L' = L \ {l} for some l
500
+
501
+ # In the Graham-Houghton bipartite graph, we can remove any vertex <l> in <L>
502
+ # which is not adjacent to a vertex <i> in <I> which is only adjacent to <l>.
503
+ # So, we run through the vertices <i> of <I> and find the ones of degree 1,
504
+ # and we remember the vertices <l> adjacent to such <i>.
505
+ if type[3] then
506
+ Info(InfoSemigroups, 2, "Type 3: looking for ",
507
+ "maximal subsemigroups formed by discarding a column...");
508
+
509
+ if L > 1 then
510
+ remove := BlistList(cols, cols);
511
+ i := 0;
512
+ while i < Length(contain) and SizeBlist(remove) > 0 do
513
+ i := i + 1;
514
+ x := contain[i];
515
+ remove[lookup_cols[x![3]]] := false;
516
+ od;
517
+ n := SizeBlist(remove);
518
+ fi;
519
+
520
+ if L > 1 and SizeBlist(remove) > 0 then
521
+ dig := RZMSDigraph(R);
522
+ nbs := OutNeighbours(dig);
523
+ deg := OutDegrees(dig);
524
+ i := 0;
525
+ while i < I and SizeBlist(remove) > 0 do
526
+ i := i + 1;
527
+ if deg[i] = 1 then
528
+ remove[nbs[i][1] - I] := false;
529
+ fi;
530
+ od;
531
+ n := SizeBlist(remove);
532
+ fi;
533
+
534
+ if L > 1 and n > 0 then
535
+ Info(InfoSemigroups, 2, "...found ", n, " result(s).");
536
+ tot := tot + n;
537
+ if not opts.number then
538
+ Info(InfoSemigroups, 2, "creating these maximal subsemigroups.");
539
+ # Code to produce smaller generating set:
540
+ # Check whether removing any particular col leaves a matrix without 0.
541
+ # In the case that this happens, 0 must sometimes be included as a gen
542
+ x := 0;
543
+ l := 0;
544
+ r := 0;
545
+ while x < 2 and l < L do
546
+ l := l + 1;
547
+ if deg[l + I] < I then
548
+ x := x + 1;
549
+ r := cols[l]; # Col <l> corresponds to a row of <mat> with 0's
550
+ fi;
551
+ od;
552
+ if x >= 2 then
553
+ r := infinity; # At least 2 cols correspond to rows of <mat> with 0s
554
+ fi;
555
+
556
+ # Remove each possible col in turn...
557
+ for l in ListBlist(cols, remove) do
558
+ x := Difference(cols, [l]);
559
+ x := ReesZeroMatrixSubsemigroupNC(R, rows, G, x);
560
+ if opts.gens then
561
+ x := ShallowCopy(GeneratorsOfSemigroup(x));
562
+ if opts.zero and (r = 0 or r = l) then # 0 is necessarily a gen.
563
+ Add(x, zero);
564
+ fi;
565
+ else
566
+ if r = 0 or r = l then
567
+ x := Semigroup(x, zero);
568
+ fi;
569
+ SetIsReesZeroMatrixSemigroup(x, true);
570
+ fi;
571
+ Add(out, x);
572
+ od;
573
+ fi;
574
+ else
575
+ Info(InfoSemigroups, 2, "...found none.");
576
+ fi;
577
+ fi;
578
+
579
+ # Type 4: Maximal subsemigroups I' x G x L + {0} where I' = I \ {i} for some i
580
+
581
+ # In the Graham-Houghton bipartite graph, we can remove any vertex <i> in <I>
582
+ # which is not adjacent to a vertex <l> in <L> which is only adjacent to <i>.
583
+ # So, we run through the vertices <l> of <L> and find the ones of degree 1,
584
+ # and we remember the vertices <i> adjacent to such <l>.
585
+ if type[4] then
586
+ Info(InfoSemigroups, 2, "Type 4: looking for maximal subsemigroups ",
587
+ "formed by discarding a row...");
588
+ if I > 1 then
589
+ remove := BlistList(rows, rows);
590
+ i := 0;
591
+ while i < Length(contain) and SizeBlist(remove) > 0 do
592
+ i := i + 1;
593
+ x := contain[i];
594
+ remove[lookup_rows[x![1]]] := false;
595
+ od;
596
+ n := SizeBlist(remove);
597
+ fi;
598
+
599
+ if I > 1 and SizeBlist(remove) > 0 then
600
+ dig := RZMSDigraph(R);
601
+ nbs := OutNeighbours(dig);
602
+ deg := OutDegrees(dig);
603
+ l := I;
604
+ while l < L + I and SizeBlist(remove) > 0 do
605
+ l := l + 1;
606
+ if deg[l] = 1 then
607
+ remove[nbs[l][1]] := false;
608
+ fi;
609
+ od;
610
+ n := SizeBlist(remove);
611
+ fi;
612
+
613
+ if I > 1 and n > 0 then
614
+ Info(InfoSemigroups, 2, "...found ", n, " result(s).");
615
+ tot := tot + n;
616
+ if not opts.number then
617
+ Info(InfoSemigroups, 2, "creating these maximal subsemigroups.");
618
+ # Code to produce smaller generating set:
619
+ # Check whether removing any particular row leaves a matrix without 0.
620
+ # In the case that this happens, 0 must sometimes be included as a gen
621
+ x := 0;
622
+ i := 0;
623
+ r := 0;
624
+ while x < 2 and i < I do
625
+ i := i + 1;
626
+ if deg[i] < L then
627
+ x := x + 1;
628
+ r := rows[i]; # Row <i> corresponds to a column of <mat> with 0's
629
+ fi;
630
+ od;
631
+ if x >= 2 then # At least 2 rows correspond to cols of <mat> with 0's
632
+ r := infinity;
633
+ fi;
634
+
635
+ # Remove each possible row in turn...
636
+ for i in ListBlist(rows, remove) do
637
+ x := Difference(rows, [i]);
638
+ x := ReesZeroMatrixSubsemigroupNC(R, x, G, cols);
639
+ if opts.gens then
640
+ x := ShallowCopy(GeneratorsOfSemigroup(x));
641
+ if opts.zero and (r = 0 or r = i) then # 0 must be a gen.
642
+ Add(x, zero);
643
+ fi;
644
+ else
645
+ if r = 0 or r = i then
646
+ x := Semigroup(x, zero);
647
+ fi;
648
+ SetIsReesZeroMatrixSemigroup(x, true);
649
+ fi;
650
+ Add(out, x);
651
+ od;
652
+ fi;
653
+ else
654
+ Info(InfoSemigroups, 2, "...found none.");
655
+ fi;
656
+ fi;
657
+
658
+ # Type 5: Maximal subsemigroups arising from maximal rectangles of zeroes
659
+ if type[5] then
660
+ Info(InfoSemigroups, 2, "Type 5: looking for maximal subsemigroups ",
661
+ "arising from maximal rectangles...");
662
+ dig := RZMSDigraph(R);
663
+
664
+ # Create digraph <dig_contain> to remember which H-classes meet <contain>
665
+ # Every such H-class must be contained in maximal subsemigroup of type 5.
666
+ # Hence either the R- or L-class of every such H-class must be contained.
667
+ dig_contain := List([1 .. I + L], x -> BlistList([1 .. I + L], []));
668
+ for x in contain do
669
+ dig_contain[lookup_rows[x![1]]][lookup_cols[x![3]] + I] := true;
670
+ dig_contain[lookup_cols[x![3]] + I][lookup_rows[x![1]]] := true;
671
+ od;
672
+ dig_contain := DigraphByAdjacencyMatrix(dig_contain);
673
+ SetDigraphBicomponents(dig_contain, [[1 .. I], [I + 1 .. I + L]]);
674
+
675
+ count := 0;
676
+ if not IsCompleteBipartiteDigraph(dig)
677
+ and not IsCompleteBipartiteDigraph(dig_contain) then
678
+ Info(InfoSemigroups, 2, "...calculating maximal independent sets of the ",
679
+ "Graham-Houghton graph...");
680
+ rectangles := DigraphMaximalIndependentSets(dig);
681
+ n := Length(rectangles) - 2;
682
+ Info(InfoSemigroups, 2, "...found ", n, " maximal independent set(s).");
683
+ if n > 0 then
684
+ bicomp_I := BlistList([1 .. I + L], [1 .. I]);
685
+ bicomp_L := BlistList([1 .. I + L], [I + 1 .. I + L]);
686
+ rectangles := [];
687
+ for r in DigraphMaximalIndependentSets(dig) do
688
+ b := BlistList([1 .. I + L], r);
689
+
690
+ # Check that <r> is not one of the bicomponents of <dig>
691
+ if b = bicomp_I or b = bicomp_L then
692
+ continue;
693
+ fi;
694
+
695
+ # Check that maximal subsemigroup defined by <r> contains <contain>
696
+ if not ForAll(DigraphEdges(dig_contain), y -> b[y[1]] or b[y[2]]) then
697
+ continue;
698
+ fi;
699
+
700
+ # <r> defines a maximal subsemigroup of <R>
701
+ count := count + 1;
702
+ if not opts.number then
703
+ Add(rectangles, [r, b]);
704
+ fi;
705
+ od;
706
+ fi;
707
+ fi;
708
+
709
+ if count > 0 then
710
+ Info(InfoSemigroups, 2, "...found ", count, " result(s).");
711
+ tot := tot + count;
712
+ if not opts.number then
713
+ Info(InfoSemigroups, 2, "...creating these maximal subsemigroups.");
714
+
715
+ # We need to be able to invert elements of <G> easily
716
+ if IsGroup(G) then
717
+ invert := InverseOp;
718
+ else
719
+ invert := x -> InversesOfSemigroupElementNC(G, x)[1];
720
+ fi;
721
+
722
+ gens := GeneratorsOfSemigroup(G);
723
+ one := MultiplicativeNeutralElement(G);
724
+ nbs := BooleanAdjacencyMatrix(dig);
725
+
726
+ # Pre-process the H-class representatives of R
727
+ reps := List(rows, i -> List(cols,
728
+ l -> RMSElement(R, i, one, l)));
729
+
730
+ for x in rectangles do
731
+ r := x[1]; # the maximal independent set
732
+ b := x[2]; # a blist representing the maximal independent set
733
+
734
+ # Add generators for two group H-classes (in appropriate locations)
735
+ i1 := First(r, x -> x <= I);
736
+ l1 := First([1 .. L],
737
+ x -> not b[x + I] and not mat[cols[x]][rows[i1]] = 0);
738
+
739
+ a := invert(mat[cols[l1]][rows[i1]]);
740
+ H1 := List(gens, x -> RMSElement(R, rows[i1], x * a, cols[l1]));
741
+
742
+ l2 := First(r, x -> x > I) - I;
743
+ i2 := First([1 .. I],
744
+ x -> not b[x] and not mat[cols[l2]][rows[x]] = 0);
745
+
746
+ a := invert(mat[cols[l2]][rows[i2]]);
747
+ H2 := List(gens, x -> RMSElement(R, rows[i2], x * a, cols[l2]));
748
+
749
+ x := Concatenation(H1, H2);
750
+
751
+ # Add a generator to every row
752
+ for i in Difference([1 .. I], [i1, i2]) do
753
+ if b[i] then # <b> needs to be indexed differently
754
+ Add(x, reps[i][l1]);
755
+ else
756
+ Add(x, reps[i][l2]);
757
+ fi;
758
+ od;
759
+
760
+ # Add a generator for every column
761
+ for l in Difference([1 .. L], [l1, l2]) do
762
+ if b[l + I] then
763
+ Add(x, reps[i2][l]);
764
+ else
765
+ Add(x, reps[i1][l]);
766
+ fi;
767
+ od;
768
+
769
+ # If necessary, add generators for the maximal rectangle itself.
770
+ rows_in := [];
771
+ rows_out := [];
772
+ cols_in := [];
773
+ cols_out := [];
774
+ for i in [1 .. I] do
775
+ if b[i] then
776
+ Add(rows_in, i);
777
+ else
778
+ Add(rows_out, i);
779
+ fi;
780
+ od;
781
+ for i in [I + 1 .. I + L] do
782
+ if b[i] then
783
+ Add(cols_in, i - I);
784
+ else
785
+ Add(cols_out, i);
786
+ fi;
787
+ od;
788
+
789
+ if not ForAny(rows_out, i -> ForAny(cols_out, l -> nbs[i][l])) then
790
+ n := Minimum(Length(rows_in), Length(cols_in));
791
+ for i in [1 .. n] do
792
+ Add(x, reps[rows_in[i]][cols_in[i]]);
793
+ od;
794
+ for i in [n + 1 .. Length(rows_in)] do
795
+ Add(x, reps[rows_in[i]][cols_in[1]]);
796
+ od;
797
+ for i in [n + 1 .. Length(cols_in)] do
798
+ Add(x, reps[rows_in[1]][cols_in[i]]);
799
+ od;
800
+ fi;
801
+
802
+ if not opts.gens then
803
+ x := Semigroup(x); # <new> is guaranteed to generate the <0>.
804
+ fi;
805
+ Add(out, x);
806
+ od;
807
+ fi;
808
+ else
809
+ Info(InfoSemigroups, 2, "...found no maximal subsemigroups of type 5.");
810
+ fi;
811
+ fi;
812
+
813
+ # Type 6: Maximal subsemigps isomorphic to I x H x L + {0}, H < G maximal
814
+ if type[6] then
815
+ Info(InfoSemigroups, 2, "Type 6: looking for maximal subsemigroups ",
816
+ "arising from maximal subgroups...");
817
+ count := 0;
818
+ failed := false;
819
+ if IsTrivial(G) then
820
+ failed := true;
821
+ fi;
822
+
823
+ if not failed then
824
+ iso := RZMSNormalization(R); # The normalization of R
825
+ inv := InverseGeneralMapping(iso); # The normalization inverse
826
+ R_n := Range(iso); # R (normalized)
827
+ mat := Matrix(R_n); # Normalized matrix
828
+
829
+ if IsGroup(G) then
830
+ iso_p := IdentityMapping(G);
831
+ inv_p := iso_p;
832
+ else # We need to use methods that apply only to IsGroup, e.g. Normalizer
833
+ iso_p := IsomorphismPermGroup(G);
834
+ inv_p := InverseGeneralMapping(iso_p);
835
+ G := Range(iso_p);
836
+ fi;
837
+
838
+ one := Identity(G);
839
+
840
+ # Get the connected components of R_n
841
+ ccs := RZMSConnectedComponents(R_n);
842
+ n := Length(ccs);
843
+ Info(InfoSemigroups, 2, "...the Graham-Houghton graph has ", n, " ",
844
+ "connected component(s).");
845
+ I := EmptyPlist(n); # I[k] = list of rows in the k^th connected component
846
+ L := EmptyPlist(n); # L[k] = list of cols in the k^th connected component
847
+
848
+ # row -> connected component
849
+ comp_row := EmptyPlist(Length(Rows(R_n)));
850
+ # col -> connected component
851
+ comp_col := EmptyPlist(Length(Columns(R_n)));
852
+ for k in [1 .. n] do
853
+ comp := ccs[k][1];
854
+ I[k] := comp[1];
855
+ for j in comp do
856
+ comp_row[j] := k;
857
+ od;
858
+ comp := ccs[k][2];
859
+ L[k] := comp[1];
860
+ for j in comp do
861
+ comp_col[j] := k;
862
+ od;
863
+ od;
864
+
865
+ # Sort the elements of <contain> into their 'blocks'.
866
+ # By doing so, we find the necessary relationships between components.
867
+ # We call a class of related connected components 'super components'
868
+
869
+ # <con[k][l]> lists those group elts which must be contained in I_k x L_l
870
+ con := List([1 .. n], x -> List([1 .. n], y -> []));
871
+
872
+ # Adjacency mat for a <dig> which defines relationship between components.
873
+ # {k,l} is an edge of <dig> iff <con[k][l]> or <con[l][k]> is non-empty.
874
+ nbs := List([1 .. n], x -> BlistList([1 .. n], []));
875
+
876
+ contain := List(contain, x -> x ^ iso);
877
+ for x in contain do
878
+ a := comp_row[x![1]];
879
+ b := comp_col[x![3]];
880
+ if a <= b then
881
+ AddSet(con[a][b], x![2] ^ iso_p);
882
+ else
883
+ AddSet(con[b][a], (x![2] ^ iso_p) ^ -1);
884
+ fi;
885
+ nbs[a][b] := true;
886
+ nbs[b][a] := true;
887
+ od;
888
+ # There is roughly 1 'degree of freedom' per connected component of <dig>
889
+ dig := DigraphByAdjacencyMatrix(nbs); # <dig> is graph defined by <nbs>
890
+ sup := DigraphConnectedComponents(dig).comps;
891
+ m := Length(sup);
892
+
893
+ # <lim> = size of the largest set <con[k][l]>.
894
+ lim := Maximum(List(con, x -> Maximum(List(x, Length))));
895
+
896
+ # Prepare the gens of the idempotent generated group, P[k], for each k.
897
+ P := EmptyPlist(n);
898
+ for k in [1 .. n] do
899
+ # <P[k]> consists on non-zero matrix entries in cc <k>; and <con[k][k]>
900
+ P[k] := Concatenation(mat{ccs[k][2]}{ccs[k][1]});
901
+ P[k] := Unique(Concatenation(P[k], con[k][k]));
902
+ pos := Position(P[k], 0);
903
+ if pos <> fail then
904
+ Remove(P[k], pos);
905
+ fi;
906
+ P[k] := List(P[k], x -> x ^ iso_p);
907
+ if Size(Group(P[k])) = Size(G) then # If <P[k]> generates <G>
908
+ failed := true;
909
+ break;
910
+ fi;
911
+ pos := Position(P[k], one);
912
+ if pos <> fail then
913
+ Remove(P[k], pos); # remove the identity from the generating set
914
+ fi;
915
+ od;
916
+ fi;
917
+
918
+ if not failed then
919
+ max := MaximalSubgroupClassReps(G);
920
+ q := Length(max);
921
+ Info(InfoSemigroups, 2, "...there are ", q, " maximal subgroup(s) of ",
922
+ "the underlying group, up to conjugacy.");
923
+
924
+ # Technical function to respect the restrictions imposed by <con>:
925
+ # For each block {k,l} (with l > pos), do the elements of <con[k][l]>
926
+ # all define the same right coset of V ^ t?
927
+ same_coset := function(t, k, pos)
928
+ local block, l, x;
929
+ for l in [pos + 1 .. Length(sup[k])] do
930
+ block := con[sup[k][pos]][sup[k][l]];
931
+ for x in [1 .. Length(block) - 1] do
932
+ if not (block[x] * (block[x + 1] ^ -1)) ^ (t ^ -1) in V then
933
+ return false;
934
+ fi;
935
+ od;
936
+ od;
937
+ return true;
938
+ end;
939
+
940
+ # Max subsemigroup arising from <max[i]> <--> Transversal of <results[i]>
941
+ results := List([1 .. q], x -> List([1 .. m], x -> []));
942
+
943
+ for i in [1 .. q] do
944
+ V := max[i];
945
+
946
+ if Size(V) < lim then
947
+ continue; # <V> is not big enough to contain every set <con[k][l]>
948
+ fi;
949
+
950
+ normal := IsNormal(G, V);
951
+ trans := Elements(RightTransversal(G, V));
952
+
953
+ # Check that the 1st cc of each super-comp <j> contains group <P[j]>
954
+ for j in [1 .. m] do
955
+ comp := sup[j];
956
+ r := comp[1]; # <r> is the least cc of the super-component
957
+ len := Length(comp);
958
+
959
+ Assert(0, j <> 1 or r = 1, "1st elt of 1st super-comp must be 1");
960
+
961
+ T := [];
962
+ if normal and IsSubset(V, P[r]) then
963
+ # if <V> is normal then P[r] < V ^ g iff P[r] < V so only check once
964
+ if r = 1 then
965
+ # Special case for the 1st connected component if V is normal
966
+ # For 1st cc we take a transversal of the normalizer of <V> in <G>
967
+ # This transversal is [one] if <V> is normal, else it is <trans>
968
+ T := [one];
969
+ else
970
+ T := trans;
971
+ fi;
972
+ elif not normal then
973
+ # if <V> is not normal we must check P[r] < V ^ g separately
974
+ T := Filtered(trans, g -> ForAll(P[r], x -> g * x * g ^ -1 in V));
975
+ fi;
976
+
977
+ # Only allow V ^ g if that choice satisfies <con>.
978
+ T := Filtered(T, g -> same_coset(g, j, 1));
979
+
980
+ if IsEmpty(T) then
981
+ break;
982
+ elif len = 1 then
983
+ results[i][j] := List(T, x -> [x]);
984
+ continue;
985
+ fi;
986
+
987
+ # Given a conjugator V ^ t for one cc in the super-component,
988
+ # there is no freedom in choosing the conjugators for the other cc's
989
+ # in the super-component. Given t, determine these conjugators.
990
+ for t in T do
991
+ success := true;
992
+ visited := BlistList([1 .. n], []);
993
+ conjugator := EmptyPlist(n);
994
+ conjugator[r] := t;
995
+ queue := [r];
996
+
997
+ while success and not IsEmpty(queue) do
998
+ u := Remove(queue, 1);
999
+ visited[u] := true;
1000
+ for v in ListBlist([1 .. n], DifferenceBlist(nbs[u], visited)) do
1001
+ Add(queue, v);
1002
+ # the coset defined in block [u][v] determines what g_v must be
1003
+ if u < v then
1004
+ candidate := conjugator[u] * con[u][v][1];
1005
+ else
1006
+ candidate := conjugator[u] * con[v][u][1] ^ -1;
1007
+ fi;
1008
+
1009
+ # define the conjugator for cc <v> if it is not yet defined
1010
+ if not IsBound(conjugator[v]) then
1011
+ conjugator[v] := candidate;
1012
+
1013
+ # 1. check that g_v is such that P[v] < V ^ g_v
1014
+ # 2. check that g_v satisfies <con>
1015
+ if not ForAll(P[v], g -> g ^ (conjugator[v] ^ -1) in V)
1016
+ or not same_coset(candidate, j, Position(comp, v)) then
1017
+ success := false;
1018
+ break;
1019
+ fi;
1020
+ elif not candidate * conjugator[v] ^ -1 in V then
1021
+ success := false;
1022
+ break;
1023
+ fi;
1024
+ od;
1025
+ od;
1026
+
1027
+ if success then
1028
+ Add(results[i][j], List(comp, x -> conjugator[x]));
1029
+ fi;
1030
+ od;
1031
+
1032
+ if IsEmpty(results[i][j]) then
1033
+ break; # No results arise from <V[i]> because of super-comp <j>.
1034
+ fi;
1035
+ od;
1036
+ count := count + Product(List(results[i], Length));
1037
+ od;
1038
+ failed := count = 0;
1039
+ fi;
1040
+
1041
+ if failed then
1042
+ Info(InfoSemigroups, 2, "...found none.");
1043
+ else
1044
+ Info(InfoSemigroups, 2, "...found ", count, " result(s).");
1045
+ tot := tot + count;
1046
+ fi;
1047
+
1048
+ if not failed and not opts.number then
1049
+ Info(InfoSemigroups, 2, "...creating these maximal subsemigroups.");
1050
+
1051
+ idems := GeneratorsOfSemigroup(IdempotentGeneratedSubsemigroup(R));
1052
+ idems := ShallowCopy(idems);
1053
+ if not opts.zero or not IsCompleteBipartiteDigraph(RZMSDigraph(R_n)) then
1054
+ x := Position(idems, zero);
1055
+ if x <> fail then
1056
+ Remove(idems, x);
1057
+ fi;
1058
+ fi;
1059
+
1060
+ # Max subsemigroup arising from <max[i]> <--> Transversal of <results[i]>
1061
+
1062
+ # Recursive function to return a transversal/extend a partial transversal
1063
+ recursion := function(x, depth)
1064
+ local new, choice, j;
1065
+
1066
+ if depth = m then
1067
+ if not opts.gens then
1068
+ x := Semigroup(x);
1069
+ fi;
1070
+ Add(out, x);
1071
+ return;
1072
+ fi;
1073
+
1074
+ depth := depth + 1;
1075
+ for choice in results[i][depth] do
1076
+ new := ShallowCopy(x);
1077
+ for j in [1 .. Length(choice)] do
1078
+ Add(new, RMSElement(R_n, I[1],
1079
+ (conjugator ^ -1 * choice[j]) ^ inv_p,
1080
+ L[sup[depth][j]]) ^ inv);
1081
+ Add(new, RMSElement(R_n, I[sup[depth][j]],
1082
+ (choice[j] ^ -1 * conjugator) ^ inv_p,
1083
+ L[1]) ^ inv);
1084
+ od;
1085
+ recursion(new, depth);
1086
+ od;
1087
+ end;
1088
+
1089
+ # Function to create the initial partial transversals
1090
+ for i in [1 .. q] do
1091
+ if Product(List(results[i], Length)) = 0 then
1092
+ continue;
1093
+ fi;
1094
+ V := max[i];
1095
+ for choice in results[i][1] do
1096
+ genset := ShallowCopy(idems);
1097
+ conjugator := choice[1];
1098
+ for gen in GeneratorsOfGroup(V) do
1099
+ Add(genset,
1100
+ RMSElement(R_n, I[1], (gen ^ conjugator) ^ inv_p, L[1]) ^ inv);
1101
+ od;
1102
+ for j in [2 .. Length(choice)] do
1103
+ Add(genset, RMSElement(R_n, I[1],
1104
+ (conjugator ^ -1 * choice[j]) ^ inv_p,
1105
+ L[sup[1][j]]) ^ inv);
1106
+ Add(genset, RMSElement(R_n, I[sup[1][j]],
1107
+ (choice[j] ^ -1 * conjugator) ^ inv_p,
1108
+ L[1]) ^ inv);
1109
+ od;
1110
+ recursion(genset, 1);
1111
+ od;
1112
+ od;
1113
+ fi;
1114
+ fi;
1115
+
1116
+ if opts.number then
1117
+ return tot;
1118
+ fi;
1119
+ return out;
1120
+ end);
1121
+
1122
+ InstallMethod(MaximalSubsemigroupsNC,
1123
+ "for a semigroup and a record",
1124
+ [IsSemigroup, IsRecord],
1125
+ function(S, opts)
1126
+ local tot, out, try, gen, D, class_gen, reps, po, below, above, vertex_class,
1127
+ x, create_ideal, contain, ideal, inj, inv, R, M, num, num_start, gen_class,
1128
+ above_gen, above_semigroup, outside_gens, L, LL, RR, m, n, gamma_L,
1129
+ gamma_R, y, comp_L, comp_R, red_L, red_R, k, gamma, comp, delta,
1130
+ label, nredges, delta_prime, l, r, forbidden_L, forbidden_R, rectangles, min,
1131
+ bicomp_L, bicomp_R, b, source_L, source_R, L_in, L_out, R_in, R_out,
1132
+ L_out_source, R_out_source, L_in_source, R_in_source, found, v, u, H, remove,
1133
+ sources, must, e, z, i, j;
1134
+
1135
+ if not IsFinite(S) then
1136
+ TryNextMethod();
1137
+ fi;
1138
+
1139
+ opts := ShallowCopy(opts); # in case <opts> is immutable
1140
+
1141
+ # Bind default options
1142
+ if not IsBound(opts.number) then
1143
+ opts.number := false;
1144
+ fi;
1145
+ if not IsBound(opts.gens) then
1146
+ opts.gens := false;
1147
+ fi;
1148
+ if IsBound(opts.contain) then
1149
+ opts.contain := ShallowCopy(opts.contain); # assume duplicate-free
1150
+ else
1151
+ opts.contain := [];
1152
+ fi;
1153
+
1154
+ tot := 0;
1155
+ out := [];
1156
+ try := [];
1157
+
1158
+ if not IsTrivial(S) then
1159
+ Info(InfoSemigroups, 1, "enumerating the D-classes...");
1160
+ gen := GeneratorsOfSemigroup(S);
1161
+ D := GreensDClasses(S);
1162
+ # <gen[i]> is in the D-class index by <class_gen[i]>
1163
+ class_gen := List(gen, x -> PositionProperty(D, d -> x in d));
1164
+ try := Unique(class_gen);
1165
+ reps := DClassReps(S);
1166
+
1167
+ # Prepare the digraphs which relate D-classes, from the partial order
1168
+ # <below>: i->j is an edge if and only if <D[j]> is immediately below <D[i]>
1169
+ # This digraph captures the D-class partial order.
1170
+ # <above>: i->j is an edge if <D[label[j]]> is above <D[label[i]]> in p-o.
1171
+ # captures which generators are above which other generators
1172
+ Info(InfoSemigroups, 1, "computing the partial order of D-classes...");
1173
+ po := PartialOrderOfDClasses(S);
1174
+ Info(InfoSemigroups, 1, "processing the partial order of D-classes...");
1175
+
1176
+ po := DigraphMutableCopy(po);
1177
+ DigraphRemoveLoops(po);
1178
+ MakeImmutable(po);
1179
+ SetIsAcyclicDigraph(po, true);
1180
+
1181
+ below := DigraphReflexiveTransitiveReduction(po);
1182
+
1183
+ above := DigraphReverse(DigraphMutableCopy(below));
1184
+ DigraphRemoveLoops(DigraphTransitiveClosure(above));
1185
+ ClearDigraphVertexLabels(above);
1186
+ InducedSubdigraph(above, try);
1187
+ MakeImmutable(above);
1188
+ SetIsAcyclicDigraph(above, true);
1189
+
1190
+ # <vertex_class[i]> is the vertex number of <above> corresponding to <D[i]>
1191
+ # <DigraphVertexLabel(above, vertex_class[i])> is the list of gens in <D[i]>
1192
+ vertex_class := EmptyPlist(Maximum(try));
1193
+ for i in DigraphVertices(above) do
1194
+ vertex_class[DigraphVertexLabel(above, i)] := i;
1195
+ od;
1196
+ SetDigraphVertexLabels(above, List(DigraphVertices(above), y -> []));
1197
+ for i in [1 .. Length(gen)] do
1198
+ Add(above!.vertexlabels[vertex_class[class_gen[i]]], gen[i]);
1199
+ od;
1200
+
1201
+ if IsBound(opts.D) then
1202
+ x := try;
1203
+ try := [];
1204
+ for i in x do
1205
+ if reps[i] in opts.D then
1206
+ try := [i];
1207
+ break;
1208
+ fi;
1209
+ od;
1210
+ fi;
1211
+ fi;
1212
+
1213
+ # <create_ideal()> finds a generating set for the ideal consisting of
1214
+ # those elements which are strictly less than <D[i]> in the usual D-order.
1215
+ create_ideal := function()
1216
+ if not IsBound(ideal) then
1217
+ ideal := reps{OutNeighboursOfVertexNC(below, i)};
1218
+ if not IsEmpty(ideal) then
1219
+ Info(InfoSemigroups, 1,
1220
+ "...computing a generating set for the ideal below D[", i, "]...");
1221
+ ideal := GeneratorsOfSemigroup(SemigroupIdeal(S, ideal));
1222
+ fi;
1223
+ fi;
1224
+ end;
1225
+
1226
+ # TODO(later) sort <try> optimally such that any D-classes which have the
1227
+ # same ideal directly below occur together, so that that ideal needs to be
1228
+ # computed only once. And then check to actually see if it is necessary to
1229
+ # re-compute ideal Can possibly use <below> to help do this?
1230
+
1231
+ for i in try do # The D-classes to contain are those indexed by <try>
1232
+ Unbind(ideal);
1233
+
1234
+ ############################################################################
1235
+ ############################################################################
1236
+ # Code for maximal D-classes
1237
+ if OutDegreeOfVertex(above, vertex_class[i]) = 0 then
1238
+ Info(InfoSemigroups, 1, "## considering maximal D-class D[", i, "]...");
1239
+
1240
+ if not IsEmpty(opts.contain) then
1241
+ contain := Intersection(D[i], opts.contain);
1242
+ opts.contain := Difference(opts.contain, contain);
1243
+ if Length(contain) = Size(D[i]) then
1244
+ Info(InfoSemigroups, 1, "found no maximal subsemigroups.");
1245
+ continue;
1246
+ fi;
1247
+ else
1248
+ contain := [];
1249
+ fi;
1250
+
1251
+ if not opts.number then
1252
+ ideal := gen{Filtered([1 .. Length(gen)], x -> class_gen[x] <> i)};
1253
+ ideal := Concatenation(reps{OutNeighboursOfVertexNC(below, i)}, ideal);
1254
+ if not IsEmpty(ideal) then
1255
+ Info(InfoSemigroups, 1, "...computing the ideal below D[", i, "]...");
1256
+ ideal := SemigroupIdeal(S, ideal);
1257
+ if not IsTrivial(D[i]) or opts.gens then
1258
+ Info(InfoSemigroups, 1, "...computing a generating set...");
1259
+ ideal := GeneratorsOfSemigroup(ideal);
1260
+ fi;
1261
+ fi;
1262
+ fi;
1263
+
1264
+ if IsTrivial(D[i]) then # trivial D-classes include all non-regular ones.
1265
+ tot := tot + 1;
1266
+ if not opts.number then
1267
+ Add(out, ideal); # <ideal> is already in the correct form
1268
+ fi;
1269
+ Info(InfoSemigroups, 1, "* found 1 maximal subsemigroup arising from ",
1270
+ "D[", i, "], formed by removing it.");
1271
+ continue;
1272
+ fi;
1273
+
1274
+ inj := InjectionPrincipalFactor(D[i]);
1275
+ inv := InverseGeneralMapping(inj);
1276
+ R := Range(inj);
1277
+ Info(InfoSemigroups, 1, "...calculating maximal subsemigroups of the ",
1278
+ "principal factor...");
1279
+ M := MaximalSubsemigroupsNC(R, rec(types := [3, 4, 5, 6],
1280
+ number := opts.number,
1281
+ zero := false,
1282
+ gens := true,
1283
+ contain := List(contain,
1284
+ x -> x ^ inj)));
1285
+ if opts.number then
1286
+ num := M;
1287
+ else
1288
+ num := Length(M);
1289
+ fi;
1290
+ tot := tot + num;
1291
+
1292
+ Info(InfoSemigroups, 1, "* found ", num, " maximal subsemigroup(s) ",
1293
+ "arising from D[", i, "].");
1294
+ if not opts.number then
1295
+ Info(InfoSemigroups, 1, "...creating these maximal subsemigroups...");
1296
+ for R in M do
1297
+ x := Concatenation(ideal, OnTuples(R, inv));
1298
+ if not opts.gens then
1299
+ x := Semigroup(x);
1300
+ fi;
1301
+ Add(out, x);
1302
+ od;
1303
+ fi;
1304
+ continue;
1305
+ fi;
1306
+
1307
+ ############################################################################
1308
+ ############################################################################
1309
+ # Code for non-maximal D-classes
1310
+ Info(InfoSemigroups, 1, "## considering non-maximal D-class D[", i, "]...");
1311
+ num_start := tot;
1312
+ gen_class := DigraphVertexLabel(above, vertex_class[i]);
1313
+ above_gen := OutNeighbours(above)[vertex_class[i]];
1314
+ above_gen := List(above_gen, x -> DigraphVertexLabel(above, x));
1315
+ above_gen := Concatenation(above_gen);
1316
+ above_semigroup := Semigroup(above_gen);
1317
+
1318
+ # Work out whether <D[i]> is generated by the generators above
1319
+ # - For a reg D-class, check if every generator in <D[i]> is so generated.
1320
+ # - For a non-reg D-class, if any element is so generated, then all are.
1321
+ if (IsRegularDClass(D[i]) and ForAll(gen_class, x -> x in above_semigroup))
1322
+ or (not IsRegularDClass(D[i]) and gen_class[1] in above_semigroup) then
1323
+ Info(InfoSemigroups, 1, "found no maximal subsemigroups.");
1324
+ continue;
1325
+ fi;
1326
+
1327
+ # Work out which elements of <D[i]> are required to be in any result.
1328
+ if not IsEmpty(opts.contain) then
1329
+ contain := Intersection(D[i], opts.contain);
1330
+ opts.contain := Difference(opts.contain, contain);
1331
+ if Length(contain) = Size(D[i]) then
1332
+ Info(InfoSemigroups, 1, "found no maximal subsemigroups.");
1333
+ continue;
1334
+ fi;
1335
+ else
1336
+ contain := [];
1337
+ fi;
1338
+
1339
+ if not opts.number then
1340
+ outside_gens := gen{Filtered([1 .. Length(gen)], x -> class_gen[x] <> i)};
1341
+ fi;
1342
+
1343
+ ############################################################################
1344
+ # Non-regular (or trivial) non-maximal D-classes
1345
+ if not IsRegularDClass(D[i]) or IsTrivial(D[i]) then
1346
+ if not IsEmpty(contain) then
1347
+ Info(InfoSemigroups, 1, "found no maximal subsemigroups.");
1348
+ continue;
1349
+ fi;
1350
+ tot := tot + 1;
1351
+ Info(InfoSemigroups, 1, "* found 1 maximal subsemigroup by removing ",
1352
+ "the non-regular/trivial D[", i, "].");
1353
+ if not opts.number then
1354
+ create_ideal();
1355
+ x := Concatenation(ideal, outside_gens);
1356
+ if not opts.gens then
1357
+ x := Semigroup(x);
1358
+ fi;
1359
+ Add(out, x);
1360
+ fi;
1361
+ continue;
1362
+ fi;
1363
+
1364
+ ############################################################################
1365
+ # Regular and non-trivial non-maximal D-class
1366
+ Info(InfoSemigroups, 1, "...D[", i, "] is regular and non-trivial...");
1367
+
1368
+ x := Representative(GroupHClass(D[i]));
1369
+ # L/R-class reps
1370
+ L := HClassReps(GreensRClassOfElement(D[i], x));
1371
+ R := HClassReps(GreensLClassOfElement(D[i], x));
1372
+ # L/R-class objects
1373
+ LL := List(L, x -> GreensLClassOfElement(D[i], x));
1374
+ RR := List(R, x -> GreensRClassOfElement(D[i], x));
1375
+
1376
+ Info(InfoSemigroups, 1, "...computing digraphs of the D-class...");
1377
+
1378
+ # DIGRAPHS GAMMA_L AND GAMMA_R
1379
+ m := Length(L);
1380
+ n := Length(R);
1381
+
1382
+ gamma_L := List([1 .. m], x -> []);
1383
+ gamma_R := List([1 .. n], x -> []);
1384
+
1385
+ # Act on the L/R-classes of <D[i]> by the generators above <D[i]>.
1386
+ for x in above_gen do
1387
+ for k in [1 .. m] do
1388
+ y := L[k] * x;
1389
+ y := First([1 .. m], z -> y in LL[z]);
1390
+ if y <> fail then
1391
+ Add(gamma_L[k], y);
1392
+ fi;
1393
+ od;
1394
+ od;
1395
+ for x in above_gen do
1396
+ for k in [1 .. n] do
1397
+ y := x * R[k];
1398
+ y := First([1 .. n], z -> y in RR[z]);
1399
+ if y <> fail then
1400
+ Add(gamma_R[k], y);
1401
+ fi;
1402
+ od;
1403
+ od;
1404
+
1405
+ gamma_L := DigraphNC(gamma_L);
1406
+ gamma_R := DigraphNC(gamma_R);
1407
+ comp_L := DigraphStronglyConnectedComponents(gamma_L);
1408
+ comp_R := DigraphStronglyConnectedComponents(gamma_R);
1409
+ gamma_L := QuotientDigraph(gamma_L, comp_L.comps);
1410
+ gamma_L := DigraphRemoveLoops(DigraphRemoveAllMultipleEdges(gamma_L));
1411
+ ClearDigraphVertexLabels(gamma_L);
1412
+ gamma_R := QuotientDigraph(gamma_R, comp_R.comps);
1413
+ gamma_R := DigraphRemoveLoops(DigraphRemoveAllMultipleEdges(gamma_R));
1414
+ ClearDigraphVertexLabels(gamma_R);
1415
+
1416
+ m := DigraphNrVertices(gamma_L);
1417
+ n := DigraphNrVertices(gamma_R);
1418
+
1419
+ gamma := DigraphDisjointUnion(gamma_L, gamma_R);
1420
+ red_L := BlistList(DigraphVertices(gamma_L), []);
1421
+ red_R := BlistList(DigraphVertices(gamma_R), []);
1422
+ comp := rec(id := Concatenation(comp_L.id, comp_R.id + m),
1423
+ comps := Concatenation(comp_L.comps, comp_R.comps + m));
1424
+
1425
+ # GRAPH DELTA
1426
+ delta := List([1 .. m + n], y -> BlistList([1 .. m + n], []));
1427
+ label := List([1 .. m], x -> List([1 .. n], y -> []));
1428
+ nredges := 0;
1429
+ for k in [1 .. m] do
1430
+ for j in [1 .. n] do
1431
+ for x in IteratorOfCartesianProduct(comp_L.comps[k],
1432
+ comp_R.comps[j]) do
1433
+ if L[x[1]] * R[x[2]] in D[i] then
1434
+ nredges := nredges + 1;
1435
+ delta[k][j + m] := true;
1436
+ delta[j + m][k] := true;
1437
+ label[k][j] := [x[1], x[2]];
1438
+ break;
1439
+ fi;
1440
+ od;
1441
+ od;
1442
+ od;
1443
+ delta := DigraphByAdjacencyMatrix(delta);
1444
+ SetIsBipartiteDigraph(delta, true);
1445
+ SetIsSymmetricDigraph(delta, true);
1446
+ SetDigraphNrEdges(delta, nredges * 2);
1447
+ SetDigraphBicomponents(delta, [[1 .. m], [m + 1 .. m + n]]);
1448
+
1449
+ # GRAPH DELTA PRIME
1450
+ delta_prime := List([1 .. m + n], y -> BlistList([1 .. m + n], []));
1451
+ nredges := 0;
1452
+ k := 0;
1453
+ while nredges < m * n and k < Length(contain) do
1454
+ k := k + 1;
1455
+ # work out the vertices of gamma which contain <contain[k]>
1456
+ l := comp_L.id[First([1 .. Length(L)], y -> contain[k] in LL[y])];
1457
+ r := comp_R.id[First([1 .. Length(R)], y -> contain[k] in RR[y])] + m;
1458
+ if not delta_prime[l][r] then
1459
+ nredges := nredges + 1;
1460
+ delta_prime[l][r] := true;
1461
+ delta_prime[r][l] := true;
1462
+ red_L[l] := true;
1463
+ red_R[r] := true;
1464
+ fi;
1465
+ od;
1466
+
1467
+ # Find those elements of <D[i]> which are produced by the generators above
1468
+ # In fact, can I do better than this by only considering source comps?
1469
+ Info(InfoSemigroups, 1, "...computing which elements of D[", i, "] are ",
1470
+ "products of the generators above...");
1471
+ for l in [1 .. Length(comp_L.comps)] do
1472
+ for r in [1 .. Length(comp_R.comps)] do
1473
+ k := comp_L.comps[l][1];
1474
+ j := comp_R.comps[r][1];
1475
+ if not delta_prime[l][r + m] then
1476
+ if ForAny(HClass(S, R[j] * L[k]), h -> h in above_semigroup) then
1477
+ nredges := nredges + 1;
1478
+ delta_prime[l][r + m] := true;
1479
+ delta_prime[r + m][l] := true;
1480
+ red_L[l] := true;
1481
+ red_R[r] := true;
1482
+ fi;
1483
+ fi;
1484
+ od;
1485
+ od;
1486
+
1487
+ delta_prime := DigraphByAdjacencyMatrix(delta_prime);
1488
+ SetIsBipartiteDigraph(delta_prime, true);
1489
+ SetIsSymmetricDigraph(delta_prime, true);
1490
+ SetDigraphNrEdges(delta_prime, nredges * 2);
1491
+ SetDigraphBicomponents(delta_prime, [[1 .. m], [m + 1 .. m + n]]);
1492
+
1493
+ ############################################################################
1494
+ # Find maximal subsemigroups from maximal rectangles
1495
+ num := 0;
1496
+ forbidden_L := BlistList([1 .. m], []);
1497
+ forbidden_R := BlistList([1 .. n], []);
1498
+ if m * n > 1 and not IsCompleteBipartiteDigraph(delta) and
1499
+ not IsCompleteBipartiteDigraph(delta_prime) then
1500
+ Info(InfoSemigroups, 1, "...calculating maximal independent sets...");
1501
+ rectangles := DigraphMaximalIndependentSets(delta);
1502
+ num := Length(rectangles) - 2;
1503
+ Info(InfoSemigroups, 1, "...found ", num, " maximal independent set(s).");
1504
+ if num > 0 then
1505
+ num := 0;
1506
+ min := Minimum(m, n) - 1;
1507
+ bicomp_L := BlistList([1 .. m + n], [1 .. m]);
1508
+ bicomp_R := BlistList([1 .. m + n], [m + 1 .. m + n]);
1509
+ rectangles := [];
1510
+ for r in DigraphMaximalIndependentSets(delta) do
1511
+ # Check that <r> is not one of the bicomponents of <delta>.
1512
+ b := BlistList([1 .. m + n], r);
1513
+ if b = bicomp_L or b = bicomp_R then
1514
+ continue;
1515
+ fi;
1516
+
1517
+ # Check that the subset of <S> defined by <r> contains <contain>.
1518
+ # To do this, check that <r> is a vertex cover for <delta_prime>.
1519
+ if not ForAll(DigraphEdges(delta_prime), y -> b[y[1]] or b[y[2]]) then
1520
+ continue;
1521
+ fi;
1522
+
1523
+ # Check that the subset of <g> defined by <r> has no out-neighbours.
1524
+ if ForAny(r, y -> ForAny(OutNeighbours(gamma)[y], z -> not b[z])) then
1525
+ continue;
1526
+ fi;
1527
+
1528
+ # <r> defines a maximal subsemigroup of <S>
1529
+ num := num + 1;
1530
+
1531
+ # Check whether <r> lacks only one s.c.c. of rows/columns:
1532
+ # * if it does, then the subsemigroup formed by removing that row or
1533
+ # column is not maximal.
1534
+ if Length(r) >= min then
1535
+ if SizeBlist(IntersectionBlist(bicomp_L, b)) + 1 = m then
1536
+ forbidden_L[First([1 .. m], y -> not b[y])] := true;
1537
+ fi;
1538
+ if SizeBlist(IntersectionBlist(bicomp_R, b)) + 1 = n then
1539
+ forbidden_R[First([m + 1 .. m + n], y -> not b[y]) - m] := true;
1540
+ fi;
1541
+ fi;
1542
+ if not opts.number then
1543
+ Add(rectangles, r);
1544
+ fi;
1545
+ od;
1546
+ fi;
1547
+ fi;
1548
+ if num > 0 then
1549
+ Info(InfoSemigroups, 1, "* found ", num, " maximal subsemigroup(s) ",
1550
+ "from maximal rectangles in D[", i, "].");
1551
+ tot := tot + num;
1552
+ if not opts.number then
1553
+ create_ideal();
1554
+ Info(InfoSemigroups, 1, "...creating these maximal subsemigroups...");
1555
+ # Find a generating set for the maximal subsemigroup defined by <r>
1556
+ source_L := DigraphSources(gamma_L);
1557
+ source_R := DigraphSources(gamma_R) + m;
1558
+ for r in rectangles do
1559
+ b := BlistList([1 .. m + n], r);
1560
+
1561
+ L_in := [];
1562
+ L_out := [];
1563
+ R_in := [];
1564
+ R_out := [];
1565
+ for k in [1 .. m] do
1566
+ if b[k] then
1567
+ Add(L_in, k);
1568
+ else
1569
+ Add(L_out, k);
1570
+ fi;
1571
+ od;
1572
+ for k in [m + 1 .. m + n] do
1573
+ if b[k] then
1574
+ Add(R_in, k);
1575
+ else
1576
+ Add(R_out, k);
1577
+ fi;
1578
+ od;
1579
+
1580
+ L_out_source := Filtered(source_L, y -> not b[y]);
1581
+ R_out_source := Filtered(source_R, y -> not b[y]);
1582
+ x := InducedSubdigraph(gamma, L_in);
1583
+ L_in_source := List(DigraphSources(x), y -> x!.vertexlabels[y]);
1584
+ x := InducedSubdigraph(gamma, R_in);
1585
+ R_in_source := List(DigraphSources(x), y -> x!.vertexlabels[y]);
1586
+
1587
+ # Locate a group H-class in the L-section of the maximal subsemigroup
1588
+ found := false;
1589
+ for u in L_in_source do
1590
+ v := First(R_out_source, v -> IsDigraphEdge(delta, u, v));
1591
+ if v <> fail then
1592
+ found := true;
1593
+ break;
1594
+ fi;
1595
+ od;
1596
+ if not found then
1597
+ # choose <u> arbitrarily, and find a <v> that works
1598
+ u := L_in_source[1];
1599
+ v := OutNeighbours(delta)[u][1];
1600
+ fi;
1601
+ # s.c.c. L_u intersect s.c.c. R_v contains a group H-class
1602
+ # Get the index of an actual L/R-class pair such that H_{l,r} is group
1603
+ l := label[u][v - m][1];
1604
+ r := label[u][v - m][2];
1605
+ H := HClass(D[i], R[r] * L[l]);
1606
+ inv := InverseGeneralMapping(IsomorphismPermGroup(H));
1607
+ x := List(GeneratorsOfSemigroup(Source(inv)), x -> x ^ inv);
1608
+
1609
+ for k in R_out_source do
1610
+ if k <> v then
1611
+ # Add a rep in an R-class in s.c.c. <k>, in L-class <l>
1612
+ Add(x, R[comp.comps[k][1] - m] * L[l]);
1613
+ fi;
1614
+ od;
1615
+ for k in L_in_source do
1616
+ if k <> u then
1617
+ # Add a rep in an L-class in s.c.c. <k>, in R-class <r>
1618
+ Add(x, R[r] * L[comp.comps[k][1]]);
1619
+ fi;
1620
+ od;
1621
+
1622
+ # Locate a group H-class in the R-section of the maximal subsemigroup
1623
+ found := false;
1624
+ for v in R_in_source do
1625
+ u := First(L_out_source, u -> IsDigraphEdge(delta, u, v));
1626
+ if u <> fail then
1627
+ found := true;
1628
+ break;
1629
+ fi;
1630
+ od;
1631
+ if not found then
1632
+ # choose <v> arbitrarily, and find a <u> that works
1633
+ v := R_in_source[1];
1634
+ u := OutNeighbours(delta)[v][1];
1635
+ fi;
1636
+ # s.c.c. L_u intersect s.c.c. R_v contains a group H-class
1637
+ # Get the index of an actual L/R-class pair such that H_{l,r} is group
1638
+ l := label[u][v - m][1];
1639
+ r := label[u][v - m][2];
1640
+ H := HClass(D[i], R[r] * L[l]);
1641
+ inv := InverseGeneralMapping(IsomorphismPermGroup(H));
1642
+ Append(x, Images(inv, GeneratorsOfSemigroup(Source(inv))));
1643
+
1644
+ for k in L_out_source do
1645
+ if k <> u then
1646
+ Add(x, R[r] * L[comp.comps[k][1]]);
1647
+ fi;
1648
+ od;
1649
+ for k in R_in_source do
1650
+ if k <> v then
1651
+ Add(x, R[comp.comps[k][1] - m] * L[l]);
1652
+ fi;
1653
+ od;
1654
+
1655
+ # Add generators for the max rectangle if necessary
1656
+ if not ForAny(L_out,
1657
+ x -> ForAny(R_out, y -> IsDigraphEdge(delta, x, y)))
1658
+ then
1659
+ min := Minimum(Length(R_in), Length(L_in));
1660
+ for k in [1 .. min] do
1661
+ Add(x, R[comp.comps[R_in[k]][1] - m] * L[comp.comps[L_in[k]][1]]);
1662
+ od;
1663
+ for k in [min + 1 .. Length(L_in)] do
1664
+ Add(x, R[comp.comps[R_in[1]][1] - m] * L[comp.comps[L_in[k]][1]]);
1665
+ od;
1666
+ for k in [min + 1 .. Length(R_in)] do
1667
+ Add(x, R[comp.comps[R_in[k]][1] - m] * L[comp.comps[L_in[1]][1]]);
1668
+ od;
1669
+ fi;
1670
+ Append(x, outside_gens);
1671
+ Append(x, ideal);
1672
+ if not opts.gens then
1673
+ x := Semigroup(x);
1674
+ fi;
1675
+ Add(out, x);
1676
+ od;
1677
+ fi;
1678
+ fi;
1679
+
1680
+ ############################################################################
1681
+ # Find maximal subsemigroups by removing L-classes
1682
+ num := 0;
1683
+ if m > 1 and not IsCompleteBipartiteDigraph(delta_prime) then
1684
+ # Look for "non-red" sources of Gamma_L
1685
+ remove := Filtered(DigraphSources(gamma_L),
1686
+ x -> not red_L[x] and not forbidden_L[x]);
1687
+ num := Length(remove);
1688
+ fi;
1689
+
1690
+ # Each s.c.c. of Gamma_L in <remove> can be removed to form a max subsemigp
1691
+ if num > 0 then
1692
+ tot := tot + num;
1693
+ Info(InfoSemigroups, 1, "* found ", num, " maximal subsemigroup(s) by ",
1694
+ "removing L-classes from D[", i, "].");
1695
+ if not opts.number then
1696
+ create_ideal();
1697
+ Info(InfoSemigroups, 1, "...creating these maximal subsemigroups...");
1698
+ source_R := DigraphSources(gamma_R) + m;
1699
+ for v in remove do
1700
+ x := InducedSubdigraph(gamma_L, Difference([1 .. m], [v]));
1701
+ sources := List(DigraphSources(x), y -> DigraphVertexLabel(x, y));
1702
+ u := Remove(sources, 1);
1703
+ v := First(source_R, y -> y in OutNeighbours(delta)[u]);
1704
+ if v = fail then
1705
+ v := OutNeighbours(delta)[u][1];
1706
+ fi;
1707
+
1708
+ l := label[u][v - m][1];
1709
+ r := label[u][v - m][2];
1710
+
1711
+ # Generate a group H-class
1712
+ H := HClass(D[i], R[r] * L[l]);
1713
+ inv := InverseGeneralMapping(IsomorphismPermGroup(H));
1714
+ x := Images(inv, GeneratorsOfSemigroup(Source(inv)));
1715
+
1716
+ for k in source_R do
1717
+ if k <> v then
1718
+ # Add a rep in an R-class in s.c.c. <k>, in L-class <l>
1719
+ Add(x, R[comp.comps[k][1] - m] * L[l]);
1720
+ fi;
1721
+ od;
1722
+ for k in sources do
1723
+ # Add a rep in an L-class in s.c.c. <k>, in R-class <r>
1724
+ Add(x, R[r] * L[comp.comps[k][1]]);
1725
+ od;
1726
+
1727
+ x := Concatenation(ideal, outside_gens, x);
1728
+ if not opts.gens then
1729
+ x := Semigroup(x);
1730
+ fi;
1731
+ Add(out, x);
1732
+ od;
1733
+ fi;
1734
+ fi;
1735
+
1736
+ ############################################################################
1737
+ # Find maximal subsemigroups by removing R-classes
1738
+ num := 0;
1739
+ if n > 1 and not IsCompleteBipartiteDigraph(delta_prime) then
1740
+ # Look for "non-red" sources of Gamma_R
1741
+ remove := Filtered(DigraphSources(gamma_R),
1742
+ x -> not red_R[x] and not forbidden_R[x]);
1743
+ num := Length(remove);
1744
+ fi;
1745
+
1746
+ # Each s.c.c. of Gamma_R in <remove> can be removed to form a max subsemigp
1747
+ if num > 0 then
1748
+ tot := tot + num;
1749
+ Info(InfoSemigroups, 1, "* found ", num, " maximal subsemigroup(s) by ",
1750
+ "removing R-classes from D[", i, "].");
1751
+ if not opts.number then
1752
+ create_ideal();
1753
+ Info(InfoSemigroups, 1, "...creating these maximal subsemigroups...");
1754
+ source_L := DigraphSources(gamma_L);
1755
+ for v in remove do
1756
+ x := InducedSubdigraph(gamma_R, Difference([1 .. n], [v]));
1757
+ sources := List(DigraphSources(x), y -> DigraphVertexLabel(x, y));
1758
+ v := Remove(sources, 1) + m;
1759
+ u := First(source_L, y -> y in OutNeighbours(delta)[v]);
1760
+ if u = fail then
1761
+ u := OutNeighbours(delta)[v][1];
1762
+ fi;
1763
+
1764
+ l := label[u][v - m][1];
1765
+ r := label[u][v - m][2];
1766
+
1767
+ # Generate a group H-class
1768
+ H := HClass(D[i], R[r] * L[l]);
1769
+ inv := InverseGeneralMapping(IsomorphismPermGroup(H));
1770
+ x := Images(inv, GeneratorsOfSemigroup(Source(inv)));
1771
+
1772
+ for k in source_L do
1773
+ if k <> u then
1774
+ Add(x, R[r] * L[comp_L.comps[k][1]]);
1775
+ fi;
1776
+ od;
1777
+ for k in sources do
1778
+ Add(x, R[comp_R.comps[k][1]] * L[l]);
1779
+ od;
1780
+ x := Concatenation(ideal, outside_gens, x);
1781
+ if not opts.gens then
1782
+ x := Semigroup(x);
1783
+ fi;
1784
+ Add(out, x);
1785
+ od;
1786
+ fi;
1787
+ fi;
1788
+
1789
+ ############################################################################
1790
+ # Find maximal subsemigroups which intersect every H-class of D[i]
1791
+ must := ShallowCopy(contain);
1792
+ if NrLClasses(D[i]) <= NrRClasses(D[i]) then
1793
+ e := List(LClasses(D[i]), x -> Idempotents(x)[1]);
1794
+ for x in e do
1795
+ for y in above_gen do
1796
+ z := y * x;
1797
+ if z in D[i] then
1798
+ AddSet(must, z);
1799
+ fi;
1800
+ od;
1801
+ od;
1802
+ else
1803
+ e := List(RClasses(D[i]), x -> Idempotents(x)[1]);
1804
+ for x in e do
1805
+ for y in above_gen do
1806
+ z := x * y;
1807
+ if z in D[i] then
1808
+ AddSet(must, z);
1809
+ fi;
1810
+ od;
1811
+ od;
1812
+ fi;
1813
+
1814
+ inj := InjectionPrincipalFactor(D[i]);
1815
+ inv := InverseGeneralMapping(inj);
1816
+ Info(InfoSemigroups, 1, "...calculating maximal subsemigroups of the ",
1817
+ "principal factor...");
1818
+ must := List(must, z -> z ^ inj);
1819
+ M := MaximalSubsemigroupsNC(Range(inj), rec(types := [6],
1820
+ number := opts.number,
1821
+ contain := must,
1822
+ gens := true,
1823
+ zero := false));
1824
+ if opts.number then
1825
+ num := M;
1826
+ else
1827
+ num := Length(M);
1828
+ fi;
1829
+
1830
+ if num = 0 then
1831
+ Info(InfoSemigroups, 1, "found no maximal subsemigroups which ",
1832
+ "intersect every H-class.");
1833
+ else
1834
+ tot := tot + num;
1835
+ Info(InfoSemigroups, 1, "* found ", num, " maximal subsemigroup(s) ",
1836
+ "which intersect(s) every H-class.");
1837
+
1838
+ if not opts.number then
1839
+ create_ideal();
1840
+ Info(InfoSemigroups, 1, "...creating these maximal subsemigroups...");
1841
+ for R in M do
1842
+ x := List(R, x -> x ^ inv);
1843
+ x := Concatenation(ideal, outside_gens, x);
1844
+ if not opts.gens then
1845
+ x := Semigroup(x);
1846
+ fi;
1847
+ Add(out, x);
1848
+ od;
1849
+ fi;
1850
+ fi;
1851
+
1852
+ # TODO(later) check for maximal subsemigroups formed by removing D[i]
1853
+ # if tot is what it started as, then if we have reached here,
1854
+ # that means there ARE maximal subsemigroups arising from D[i]
1855
+ # but none of the types so far have been found. Therefore S\D[i]
1856
+ # is a maximal subsemigroup of S
1857
+ if tot = num_start and IsEmptyDigraph(delta_prime) then
1858
+ Info(InfoSemigroups, 1, "* found a maximal subsemigroup by removing ",
1859
+ "D[", i, "].");
1860
+ tot := tot + 1;
1861
+ if not opts.number then
1862
+ create_ideal();
1863
+ x := Concatenation(ideal, outside_gens);
1864
+ if not opts.gens then
1865
+ x := Semigroup(x);
1866
+ fi;
1867
+ Add(out, x);
1868
+ fi;
1869
+ fi;
1870
+ od;
1871
+ Info(InfoSemigroups, 1, "found ", tot, " maximal subsemigroups in total.");
1872
+ if opts.number then
1873
+ return tot;
1874
+ fi;
1875
+ return out;
1876
+ end);