passagemath-gap-pkg-semigroups 10.6.29__cp312-abi3-musllinux_1_2_aarch64.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.
- gap/pkg/semigroups/CHANGELOG.md +1699 -0
- gap/pkg/semigroups/CONTRIBUTING.md +91 -0
- gap/pkg/semigroups/GNUmakefile +110 -0
- gap/pkg/semigroups/GNUmakefile.in +110 -0
- gap/pkg/semigroups/GPL +674 -0
- gap/pkg/semigroups/LICENSE +16 -0
- gap/pkg/semigroups/Makefile +26 -0
- gap/pkg/semigroups/Makefile.gappkg +225 -0
- gap/pkg/semigroups/PackageInfo.g +529 -0
- gap/pkg/semigroups/README.md +102 -0
- gap/pkg/semigroups/VERSIONS +112 -0
- gap/pkg/semigroups/aclocal.m4 +375 -0
- gap/pkg/semigroups/autogen.sh +25 -0
- gap/pkg/semigroups/bin/aarch64-unknown-linux-musl-default64-kv10/semigroups.so +0 -0
- gap/pkg/semigroups/config.guess +1807 -0
- gap/pkg/semigroups/config.log +1021 -0
- gap/pkg/semigroups/config.status +1131 -0
- gap/pkg/semigroups/config.sub +1960 -0
- gap/pkg/semigroups/configure +9742 -0
- gap/pkg/semigroups/configure.ac +71 -0
- gap/pkg/semigroups/data/doc/greens.pickle +1 -0
- gap/pkg/semigroups/data/gens/fullbool-8.pickle.gz +0 -0
- gap/pkg/semigroups/data/gens/fullbool.pickle.gz +0 -0
- gap/pkg/semigroups/data/gens/hall.pickle.gz +0 -0
- gap/pkg/semigroups/data/gens/reflex-6.pickle.gz +0 -0
- gap/pkg/semigroups/data/gens/reflex.pickle.gz +0 -0
- gap/pkg/semigroups/data/tst/bipart4 +10 -0
- gap/pkg/semigroups/data/tst/pperm10 +1 -0
- gap/pkg/semigroups/data/tst/tables.gz +0 -0
- gap/pkg/semigroups/data/tst/testdata +1 -0
- gap/pkg/semigroups/data/tst/testinstall.pickle +1 -0
- gap/pkg/semigroups/data/tst/trans3 +7 -0
- gap/pkg/semigroups/data/tst/trans3-old +7 -0
- gap/pkg/semigroups/environment.yml +7 -0
- gap/pkg/semigroups/gap/attributes/acting.gd +15 -0
- gap/pkg/semigroups/gap/attributes/acting.gi +297 -0
- gap/pkg/semigroups/gap/attributes/attr.gd +91 -0
- gap/pkg/semigroups/gap/attributes/attr.gi +1214 -0
- gap/pkg/semigroups/gap/attributes/dual.gd +25 -0
- gap/pkg/semigroups/gap/attributes/dual.gi +209 -0
- gap/pkg/semigroups/gap/attributes/factor.gd +17 -0
- gap/pkg/semigroups/gap/attributes/factor.gi +453 -0
- gap/pkg/semigroups/gap/attributes/homomorph.gd +84 -0
- gap/pkg/semigroups/gap/attributes/homomorph.gi +591 -0
- gap/pkg/semigroups/gap/attributes/inverse.gd +38 -0
- gap/pkg/semigroups/gap/attributes/inverse.gi +708 -0
- gap/pkg/semigroups/gap/attributes/isomorph.gd +16 -0
- gap/pkg/semigroups/gap/attributes/isomorph.gi +377 -0
- gap/pkg/semigroups/gap/attributes/isorms.gd +49 -0
- gap/pkg/semigroups/gap/attributes/isorms.gi +1383 -0
- gap/pkg/semigroups/gap/attributes/maximal.gd +16 -0
- gap/pkg/semigroups/gap/attributes/maximal.gi +1876 -0
- gap/pkg/semigroups/gap/attributes/properties.gd +109 -0
- gap/pkg/semigroups/gap/attributes/properties.gi +1658 -0
- gap/pkg/semigroups/gap/attributes/rms-translat.gd +39 -0
- gap/pkg/semigroups/gap/attributes/rms-translat.gi +1078 -0
- gap/pkg/semigroups/gap/attributes/semifp.gd +12 -0
- gap/pkg/semigroups/gap/attributes/semifp.gi +84 -0
- gap/pkg/semigroups/gap/attributes/translat.gd +474 -0
- gap/pkg/semigroups/gap/attributes/translat.gi +1779 -0
- gap/pkg/semigroups/gap/congruences/cong.gd +154 -0
- gap/pkg/semigroups/gap/congruences/cong.gi +351 -0
- gap/pkg/semigroups/gap/congruences/conginv.gd +38 -0
- gap/pkg/semigroups/gap/congruences/conginv.gi +589 -0
- gap/pkg/semigroups/gap/congruences/conglatt.gd +101 -0
- gap/pkg/semigroups/gap/congruences/conglatt.gi +886 -0
- gap/pkg/semigroups/gap/congruences/congpairs.gd +21 -0
- gap/pkg/semigroups/gap/congruences/congpairs.gi +272 -0
- gap/pkg/semigroups/gap/congruences/congpart.gd +90 -0
- gap/pkg/semigroups/gap/congruences/congpart.gi +449 -0
- gap/pkg/semigroups/gap/congruences/congrees.gd +20 -0
- gap/pkg/semigroups/gap/congruences/congrees.gi +313 -0
- gap/pkg/semigroups/gap/congruences/congrms.gd +54 -0
- gap/pkg/semigroups/gap/congruences/congrms.gi +1467 -0
- gap/pkg/semigroups/gap/congruences/congsemigraph.gd +28 -0
- gap/pkg/semigroups/gap/congruences/congsemigraph.gi +289 -0
- gap/pkg/semigroups/gap/congruences/congsimple.gd +27 -0
- gap/pkg/semigroups/gap/congruences/congsimple.gi +236 -0
- gap/pkg/semigroups/gap/congruences/conguniv.gd +20 -0
- gap/pkg/semigroups/gap/congruences/conguniv.gi +271 -0
- gap/pkg/semigroups/gap/congruences/congwordgraph.gd +21 -0
- gap/pkg/semigroups/gap/congruences/congwordgraph.gi +250 -0
- gap/pkg/semigroups/gap/elements/bipart.gd +71 -0
- gap/pkg/semigroups/gap/elements/bipart.gi +995 -0
- gap/pkg/semigroups/gap/elements/blocks.gd +31 -0
- gap/pkg/semigroups/gap/elements/blocks.gi +134 -0
- gap/pkg/semigroups/gap/elements/boolmat.gd +74 -0
- gap/pkg/semigroups/gap/elements/boolmat.gi +726 -0
- gap/pkg/semigroups/gap/elements/elements.gd +11 -0
- gap/pkg/semigroups/gap/elements/elements.gi +121 -0
- gap/pkg/semigroups/gap/elements/ffmat.gd +71 -0
- gap/pkg/semigroups/gap/elements/ffmat.gi +311 -0
- gap/pkg/semigroups/gap/elements/maxplusmat.gd +131 -0
- gap/pkg/semigroups/gap/elements/maxplusmat.gi +782 -0
- gap/pkg/semigroups/gap/elements/pbr.gd +51 -0
- gap/pkg/semigroups/gap/elements/pbr.gi +740 -0
- gap/pkg/semigroups/gap/elements/pperm.gd +11 -0
- gap/pkg/semigroups/gap/elements/pperm.gi +14 -0
- gap/pkg/semigroups/gap/elements/semiringmat.gd +136 -0
- gap/pkg/semigroups/gap/elements/semiringmat.gi +717 -0
- gap/pkg/semigroups/gap/elements/star.gd +21 -0
- gap/pkg/semigroups/gap/elements/star.gi +21 -0
- gap/pkg/semigroups/gap/elements/trans.gd +13 -0
- gap/pkg/semigroups/gap/elements/trans.gi +50 -0
- gap/pkg/semigroups/gap/fp/freeband.gd +22 -0
- gap/pkg/semigroups/gap/fp/freeband.gi +502 -0
- gap/pkg/semigroups/gap/fp/freeinverse.gd +30 -0
- gap/pkg/semigroups/gap/fp/freeinverse.gi +465 -0
- gap/pkg/semigroups/gap/fp/tietze.gd +89 -0
- gap/pkg/semigroups/gap/fp/tietze.gi +1578 -0
- gap/pkg/semigroups/gap/fp/word.gd +15 -0
- gap/pkg/semigroups/gap/fp/word.gi +67 -0
- gap/pkg/semigroups/gap/greens/acting-inverse.gi +774 -0
- gap/pkg/semigroups/gap/greens/acting-regular.gi +553 -0
- gap/pkg/semigroups/gap/greens/acting.gd +81 -0
- gap/pkg/semigroups/gap/greens/acting.gi +2433 -0
- gap/pkg/semigroups/gap/greens/froidure-pin.gd +25 -0
- gap/pkg/semigroups/gap/greens/froidure-pin.gi +741 -0
- gap/pkg/semigroups/gap/greens/generic.gd +117 -0
- gap/pkg/semigroups/gap/greens/generic.gi +630 -0
- gap/pkg/semigroups/gap/ideals/acting.gd +17 -0
- gap/pkg/semigroups/gap/ideals/acting.gi +1155 -0
- gap/pkg/semigroups/gap/ideals/froidure-pin.gd +11 -0
- gap/pkg/semigroups/gap/ideals/froidure-pin.gi +105 -0
- gap/pkg/semigroups/gap/ideals/ideals.gd +45 -0
- gap/pkg/semigroups/gap/ideals/ideals.gi +442 -0
- gap/pkg/semigroups/gap/ideals/lambda-rho.gd +16 -0
- gap/pkg/semigroups/gap/ideals/lambda-rho.gi +614 -0
- gap/pkg/semigroups/gap/libsemigroups/cong.gd +24 -0
- gap/pkg/semigroups/gap/libsemigroups/cong.gi +431 -0
- gap/pkg/semigroups/gap/libsemigroups/fpsemi.gd +16 -0
- gap/pkg/semigroups/gap/libsemigroups/fpsemi.gi +53 -0
- gap/pkg/semigroups/gap/libsemigroups/froidure-pin.gd +17 -0
- gap/pkg/semigroups/gap/libsemigroups/froidure-pin.gi +945 -0
- gap/pkg/semigroups/gap/libsemigroups/sims1.gd +38 -0
- gap/pkg/semigroups/gap/libsemigroups/sims1.gi +308 -0
- gap/pkg/semigroups/gap/main/acting.gd +36 -0
- gap/pkg/semigroups/gap/main/acting.gi +779 -0
- gap/pkg/semigroups/gap/main/froidure-pin.gd +72 -0
- gap/pkg/semigroups/gap/main/froidure-pin.gi +655 -0
- gap/pkg/semigroups/gap/main/graded.gd +26 -0
- gap/pkg/semigroups/gap/main/graded.gi +355 -0
- gap/pkg/semigroups/gap/main/lambda-rho.gd +29 -0
- gap/pkg/semigroups/gap/main/lambda-rho.gi +514 -0
- gap/pkg/semigroups/gap/main/orbits.gd +24 -0
- gap/pkg/semigroups/gap/main/orbits.gi +512 -0
- gap/pkg/semigroups/gap/main/semiact.gd +20 -0
- gap/pkg/semigroups/gap/main/semiact.gi +821 -0
- gap/pkg/semigroups/gap/main/setup.gd +61 -0
- gap/pkg/semigroups/gap/main/setup.gi +1094 -0
- gap/pkg/semigroups/gap/obsolete.gd +9 -0
- gap/pkg/semigroups/gap/obsolete.gi +14 -0
- gap/pkg/semigroups/gap/options.g +55 -0
- gap/pkg/semigroups/gap/semigroups/grpperm.gd +12 -0
- gap/pkg/semigroups/gap/semigroups/grpperm.gi +177 -0
- gap/pkg/semigroups/gap/semigroups/semibipart.gd +28 -0
- gap/pkg/semigroups/gap/semigroups/semibipart.gi +570 -0
- gap/pkg/semigroups/gap/semigroups/semiboolmat.gd +20 -0
- gap/pkg/semigroups/gap/semigroups/semiboolmat.gi +104 -0
- gap/pkg/semigroups/gap/semigroups/semicons.gd +52 -0
- gap/pkg/semigroups/gap/semigroups/semicons.gi +1194 -0
- gap/pkg/semigroups/gap/semigroups/semidp.gd +13 -0
- gap/pkg/semigroups/gap/semigroups/semidp.gi +509 -0
- gap/pkg/semigroups/gap/semigroups/semieunit.gd +126 -0
- gap/pkg/semigroups/gap/semigroups/semieunit.gi +889 -0
- gap/pkg/semigroups/gap/semigroups/semiex.gd +104 -0
- gap/pkg/semigroups/gap/semigroups/semiex.gi +1590 -0
- gap/pkg/semigroups/gap/semigroups/semiffmat.gd +37 -0
- gap/pkg/semigroups/gap/semigroups/semiffmat.gi +565 -0
- gap/pkg/semigroups/gap/semigroups/semifp.gd +28 -0
- gap/pkg/semigroups/gap/semigroups/semifp.gi +1364 -0
- gap/pkg/semigroups/gap/semigroups/semigraph.gd +40 -0
- gap/pkg/semigroups/gap/semigroups/semigraph.gi +292 -0
- gap/pkg/semigroups/gap/semigroups/semigrp.gd +165 -0
- gap/pkg/semigroups/gap/semigroups/semigrp.gi +1225 -0
- gap/pkg/semigroups/gap/semigroups/semimaxplus.gd +72 -0
- gap/pkg/semigroups/gap/semigroups/semimaxplus.gi +710 -0
- gap/pkg/semigroups/gap/semigroups/semintmat.gd +13 -0
- gap/pkg/semigroups/gap/semigroups/semintmat.gi +74 -0
- gap/pkg/semigroups/gap/semigroups/semipbr.gd +19 -0
- gap/pkg/semigroups/gap/semigroups/semipbr.gi +139 -0
- gap/pkg/semigroups/gap/semigroups/semipperm.gd +27 -0
- gap/pkg/semigroups/gap/semigroups/semipperm.gi +711 -0
- gap/pkg/semigroups/gap/semigroups/semiquo.gd +14 -0
- gap/pkg/semigroups/gap/semigroups/semiquo.gi +97 -0
- gap/pkg/semigroups/gap/semigroups/semiringmat.gd +16 -0
- gap/pkg/semigroups/gap/semigroups/semiringmat.gi +21 -0
- gap/pkg/semigroups/gap/semigroups/semirms.gd +19 -0
- gap/pkg/semigroups/gap/semigroups/semirms.gi +977 -0
- gap/pkg/semigroups/gap/semigroups/semitrans.gd +49 -0
- gap/pkg/semigroups/gap/semigroups/semitrans.gi +909 -0
- gap/pkg/semigroups/gap/tools/display.gd +24 -0
- gap/pkg/semigroups/gap/tools/display.gi +749 -0
- gap/pkg/semigroups/gap/tools/io.gd +17 -0
- gap/pkg/semigroups/gap/tools/io.gi +543 -0
- gap/pkg/semigroups/gap/tools/iterators.gd +16 -0
- gap/pkg/semigroups/gap/tools/iterators.gi +253 -0
- gap/pkg/semigroups/gap/tools/utils.gd +19 -0
- gap/pkg/semigroups/gap/tools/utils.gi +756 -0
- gap/pkg/semigroups/gapbind14/.ccls +18 -0
- gap/pkg/semigroups/gapbind14/.clang-format +104 -0
- gap/pkg/semigroups/gapbind14/CPPLINT.cfg +5 -0
- gap/pkg/semigroups/gapbind14/LICENSE +674 -0
- gap/pkg/semigroups/gapbind14/README.md +76 -0
- gap/pkg/semigroups/gapbind14/demo/.gitignore +4 -0
- gap/pkg/semigroups/gapbind14/demo/LICENSE +293 -0
- gap/pkg/semigroups/gapbind14/demo/Makefile.gappkg +220 -0
- gap/pkg/semigroups/gapbind14/demo/Makefile.in +19 -0
- gap/pkg/semigroups/gapbind14/demo/PackageInfo.g +87 -0
- gap/pkg/semigroups/gapbind14/demo/README.md +17 -0
- gap/pkg/semigroups/gapbind14/demo/configure +34 -0
- gap/pkg/semigroups/gapbind14/demo/gap/gapbind_demo.gd +19 -0
- gap/pkg/semigroups/gapbind14/demo/gap/gapbind_demo.gi +10 -0
- gap/pkg/semigroups/gapbind14/demo/init.g +16 -0
- gap/pkg/semigroups/gapbind14/demo/makedoc.g +10 -0
- gap/pkg/semigroups/gapbind14/demo/read.g +6 -0
- gap/pkg/semigroups/gapbind14/demo/src/gapbind_demo.cc +142 -0
- gap/pkg/semigroups/gapbind14/demo/tst/testall.g +12 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/cpp_fn.hpp +223 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/gap_include.hpp +26 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/gapbind14.hpp +445 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/tame_free_fn.hpp +420 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/tame_mem_fn.hpp +556 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/to_cpp.hpp +162 -0
- gap/pkg/semigroups/gapbind14/include/gapbind14/to_gap.hpp +158 -0
- gap/pkg/semigroups/gapbind14/src/.clang-format +108 -0
- gap/pkg/semigroups/gapbind14/src/gapbind14.cpp +334 -0
- gap/pkg/semigroups/init.g +150 -0
- gap/pkg/semigroups/m4/ax_append_flag.m4 +50 -0
- gap/pkg/semigroups/m4/ax_check_compile_flag.m4 +53 -0
- gap/pkg/semigroups/m4/ax_check_hpcombi.m4 +121 -0
- gap/pkg/semigroups/m4/ax_check_libsemigroup.m4 +68 -0
- gap/pkg/semigroups/m4/ax_compare_version.m4 +177 -0
- gap/pkg/semigroups/m4/ax_cxx_compile_stdcxx.m4 +1009 -0
- gap/pkg/semigroups/m4/ax_cxx_compile_stdcxx_14.m4 +34 -0
- gap/pkg/semigroups/m4/ax_prefix_config_h.m4 +203 -0
- gap/pkg/semigroups/m4/ax_pthread.m4 +522 -0
- gap/pkg/semigroups/m4/find_gap.m4 +94 -0
- gap/pkg/semigroups/makedoc.g +153 -0
- gap/pkg/semigroups/prerequisites.sh +62 -0
- gap/pkg/semigroups/read.g +105 -0
- gap/pkg/semigroups/release.toml +6 -0
- gap/pkg/semigroups/tst/extreme/README +2 -0
- gap/pkg/semigroups/tst/extreme/attrinv.tst +703 -0
- gap/pkg/semigroups/tst/extreme/bipart.tst +2803 -0
- gap/pkg/semigroups/tst/extreme/closure.tst +652 -0
- gap/pkg/semigroups/tst/extreme/cong.tst +286 -0
- gap/pkg/semigroups/tst/extreme/conginv.tst +43 -0
- gap/pkg/semigroups/tst/extreme/examples.tst +2449 -0
- gap/pkg/semigroups/tst/extreme/freeband.tst +37 -0
- gap/pkg/semigroups/tst/extreme/greens-acting-regular.tst +27 -0
- gap/pkg/semigroups/tst/extreme/greens-acting.tst +1999 -0
- gap/pkg/semigroups/tst/extreme/ideals.tst +858 -0
- gap/pkg/semigroups/tst/extreme/inverse.tst +1025 -0
- gap/pkg/semigroups/tst/extreme/maximal.tst +856 -0
- gap/pkg/semigroups/tst/extreme/misc.tst +4236 -0
- gap/pkg/semigroups/tst/extreme/monoid_pkg.tst +1488 -0
- gap/pkg/semigroups/tst/extreme/properties.tst +914 -0
- gap/pkg/semigroups/tst/extreme/semibipart.tst +2837 -0
- gap/pkg/semigroups/tst/extreme/semieunit.tst +49 -0
- gap/pkg/semigroups/tst/extreme/semiffmat.tst +353 -0
- gap/pkg/semigroups/tst/extreme/semigroups.tst +245 -0
- gap/pkg/semigroups/tst/extreme/semiiter.tst +58 -0
- gap/pkg/semigroups/tst/extreme/semirms.tst +1091 -0
- gap/pkg/semigroups/tst/extreme/transform.tst +305 -0
- gap/pkg/semigroups/tst/extreme/translat.tst +44 -0
- gap/pkg/semigroups/tst/standard/README +2 -0
- gap/pkg/semigroups/tst/standard/attributes/acting.tst +388 -0
- gap/pkg/semigroups/tst/standard/attributes/attr.tst +2404 -0
- gap/pkg/semigroups/tst/standard/attributes/dual.tst +308 -0
- gap/pkg/semigroups/tst/standard/attributes/factor.tst +629 -0
- gap/pkg/semigroups/tst/standard/attributes/homomorph.tst +1134 -0
- gap/pkg/semigroups/tst/standard/attributes/inverse.tst +1521 -0
- gap/pkg/semigroups/tst/standard/attributes/isomorph.tst +435 -0
- gap/pkg/semigroups/tst/standard/attributes/isorms.tst +1147 -0
- gap/pkg/semigroups/tst/standard/attributes/maximal.tst +853 -0
- gap/pkg/semigroups/tst/standard/attributes/properties.tst +2028 -0
- gap/pkg/semigroups/tst/standard/attributes/semifp.tst +53 -0
- gap/pkg/semigroups/tst/standard/attributes/translat.tst +796 -0
- gap/pkg/semigroups/tst/standard/congruences/cong.tst +1044 -0
- gap/pkg/semigroups/tst/standard/congruences/conginv.tst +292 -0
- gap/pkg/semigroups/tst/standard/congruences/conglatt.tst +421 -0
- gap/pkg/semigroups/tst/standard/congruences/congpairs.tst +1011 -0
- gap/pkg/semigroups/tst/standard/congruences/congrees.tst +288 -0
- gap/pkg/semigroups/tst/standard/congruences/congrms.tst +701 -0
- gap/pkg/semigroups/tst/standard/congruences/congsemigraph.tst +422 -0
- gap/pkg/semigroups/tst/standard/congruences/congsimple.tst +311 -0
- gap/pkg/semigroups/tst/standard/congruences/conguniv.tst +259 -0
- gap/pkg/semigroups/tst/standard/congruences/congwordgraph.tst +330 -0
- gap/pkg/semigroups/tst/standard/elements/bipart.tst +783 -0
- gap/pkg/semigroups/tst/standard/elements/blocks.tst +166 -0
- gap/pkg/semigroups/tst/standard/elements/boolmat.tst +608 -0
- gap/pkg/semigroups/tst/standard/elements/elements.tst +117 -0
- gap/pkg/semigroups/tst/standard/elements/ffmat.tst +349 -0
- gap/pkg/semigroups/tst/standard/elements/maxplusmat.tst +613 -0
- gap/pkg/semigroups/tst/standard/elements/pbr.tst +506 -0
- gap/pkg/semigroups/tst/standard/elements/pperm.tst +32 -0
- gap/pkg/semigroups/tst/standard/elements/semiringmat.tst +601 -0
- gap/pkg/semigroups/tst/standard/elements/trans.tst +58 -0
- gap/pkg/semigroups/tst/standard/fp/freeband.tst +311 -0
- gap/pkg/semigroups/tst/standard/fp/freeinverse.tst +147 -0
- gap/pkg/semigroups/tst/standard/fp/tietze.tst +780 -0
- gap/pkg/semigroups/tst/standard/fp/word.tst +106 -0
- gap/pkg/semigroups/tst/standard/greens/acting-inverse.tst +545 -0
- gap/pkg/semigroups/tst/standard/greens/acting-regular.tst +396 -0
- gap/pkg/semigroups/tst/standard/greens/acting.tst +2033 -0
- gap/pkg/semigroups/tst/standard/greens/froidure-pin.tst +1831 -0
- gap/pkg/semigroups/tst/standard/greens/generic.tst +1436 -0
- gap/pkg/semigroups/tst/standard/ideals/acting.tst +279 -0
- gap/pkg/semigroups/tst/standard/ideals/froidure-pin.tst +178 -0
- gap/pkg/semigroups/tst/standard/ideals/ideals.tst +380 -0
- gap/pkg/semigroups/tst/standard/libsemigroups/cong.tst +310 -0
- gap/pkg/semigroups/tst/standard/libsemigroups/froidure-pin.tst +778 -0
- gap/pkg/semigroups/tst/standard/libsemigroups/sims1.tst +379 -0
- gap/pkg/semigroups/tst/standard/main/acting.tst +411 -0
- gap/pkg/semigroups/tst/standard/main/froidure-pin.tst +392 -0
- gap/pkg/semigroups/tst/standard/main/semiact.tst +203 -0
- gap/pkg/semigroups/tst/standard/main/setup.tst +1144 -0
- gap/pkg/semigroups/tst/standard/obsolete.tst +19 -0
- gap/pkg/semigroups/tst/standard/options.tst +54 -0
- gap/pkg/semigroups/tst/standard/semigroups/grpperm.tst +581 -0
- gap/pkg/semigroups/tst/standard/semigroups/semibipart.tst +2635 -0
- gap/pkg/semigroups/tst/standard/semigroups/semiboolmat.tst +1871 -0
- gap/pkg/semigroups/tst/standard/semigroups/semicons.tst +1173 -0
- gap/pkg/semigroups/tst/standard/semigroups/semidp.tst +739 -0
- gap/pkg/semigroups/tst/standard/semigroups/semieunit.tst +339 -0
- gap/pkg/semigroups/tst/standard/semigroups/semiex.tst +2055 -0
- gap/pkg/semigroups/tst/standard/semigroups/semiffmat.tst +746 -0
- gap/pkg/semigroups/tst/standard/semigroups/semifp.tst +2702 -0
- gap/pkg/semigroups/tst/standard/semigroups/semigraph.tst +133 -0
- gap/pkg/semigroups/tst/standard/semigroups/semigrp.tst +1112 -0
- gap/pkg/semigroups/tst/standard/semigroups/semimaxplus.tst +654 -0
- gap/pkg/semigroups/tst/standard/semigroups/semipbr.tst +2142 -0
- gap/pkg/semigroups/tst/standard/semigroups/semipperm.tst +2169 -0
- gap/pkg/semigroups/tst/standard/semigroups/semiquo.tst +278 -0
- gap/pkg/semigroups/tst/standard/semigroups/semirms.tst +3010 -0
- gap/pkg/semigroups/tst/standard/semigroups/semitrans.tst +2758 -0
- gap/pkg/semigroups/tst/standard/tools/display.tst +1040 -0
- gap/pkg/semigroups/tst/standard/tools/io.tst +363 -0
- gap/pkg/semigroups/tst/testinstall.tst +1815 -0
- gap/pkg/semigroups/tst/teststandard.g +22 -0
- gap/pkg/semigroups/tst/workspaces/load-workspace.tst +142 -0
- gap/pkg/semigroups/tst/workspaces/load.g +11 -0
- gap/pkg/semigroups/tst/workspaces/save-workspace.tst +166 -0
- gap/pkg/semigroups/tst/workspaces/save.g +14 -0
- passagemath_gap_pkg_semigroups-10.6.29.dist-info/METADATA +93 -0
- passagemath_gap_pkg_semigroups-10.6.29.dist-info/METADATA.bak +94 -0
- passagemath_gap_pkg_semigroups-10.6.29.dist-info/RECORD +356 -0
- passagemath_gap_pkg_semigroups-10.6.29.dist-info/WHEEL +5 -0
- passagemath_gap_pkg_semigroups-10.6.29.dist-info/top_level.txt +1 -0
- passagemath_gap_pkg_semigroups.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_gap_pkg_semigroups.libs/libsemigroups-81d76771.so.2.0.0 +0 -0
- passagemath_gap_pkg_semigroups.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_gap_pkg_semigroups.py +1 -0
- sage/libs/all__sagemath_gap_pkg_semigroups.py +1 -0
- 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);
|