1############################################################################
2##
3#W  standard/semidp.tst
4#Y  Copyright (C) 2017                                      Wilf A. Wilson
5##
6##  Licensing information can be found in the README file of this package.
7##
8#############################################################################
9##
10gap> START_TEST("Semigroups package: standard/semidp.tst");
11gap> LoadPackage("semigroups", false);;
12
13#
14gap> SEMIGROUPS.StartTest();;
15
16################################################################################
17# Helper functions
18################################################################################
19
20#  semifp: Embedding and Projection testers
21gap> BruteForceHomomCheck := function(map)
22>   local s, t, smap, tmap, S;
23>   S := Source(map);
24>   for s in S do
25>     for t in S do
26>       smap := s ^ map;
27>       tmap := t ^ map;
28>       if smap * tmap <> (s * t) ^ map then
29>         return false;
30>       fi;
31>     od;
32>   od;
33>   return true;
34> end;;
35gap> ProductCheck := function(product, arguments, homom)
36>   local e, p, i;
37>   for i in [1 .. Length(arguments)] do
38>     e := Embedding(product, i);
39>     p := Projection(product, i);
40>     if arguments[i] <> Source(e)
41>         or arguments[i] <> Range(p)
42>         or (homom and not BruteForceHomomCheck(e))
43>         or (homom and not BruteForceHomomCheck(p))
44>         or not ForAll(arguments[i], s -> (s ^ e) ^ p = s) then
45>       return false;
46>     fi;
47>   od;
48>   return true;
49> end;;
50
51################################################################################
52# Testing errors
53################################################################################
54
55#  semidp: SEMIGROUPS.DirectProductOp, errors, 1
56gap> SEMIGROUPS.DirectProductOp(fail, fail, fail, fail, fail);
57Error, Semigroups: SEMIGROUPS.DirectProductOp: usage,
58the first argument <S> must be a non-empty list,
59gap> SEMIGROUPS.DirectProductOp([], fail, fail, fail, fail);
60Error, Semigroups: SEMIGROUPS.DirectProductOp: usage,
61the first argument <S> must be a non-empty list,
62
63#  semidp: DirectProductOp, for transformation semigroups, errors, 1
64gap> DirectProductOp([], Monoid(Transformation([1, 1])));
65Error, Semigroups: DirectProductOp: usage,
66the first argument must be a non-empty list,
67gap> DirectProductOp([], Semigroup(Transformation([1, 1])));
68Error, Semigroups: DirectProductOp: usage,
69the first argument must be a non-empty list,
70gap> DirectProductOp([Semigroup(PartialPerm([1 .. 3]))],
71> Monoid(Transformation([1, 1])));
72Error, Semigroups: DirectProductOp: usage,
73the second argument must be one of the semigroups contained in <list>,
74gap> DirectProductOp([Semigroup(PartialPerm([1 .. 3]))],
75> Semigroup(Transformation([1, 1])));
76Error, Semigroups: DirectProductOp: usage,
77the second argument must be one of the semigroups contained in <list>,
78
79#  semidp: DirectProductOp, for partial perm semigroups, errors, 1
80gap> DirectProductOp([], Semigroup(PartialPerm([1 .. 3])));
81Error, Semigroups: DirectProductOp: usage,
82the first argument must be a non-empty list,
83gap> DirectProductOp([Semigroup(IdentityTransformation)],
84> Semigroup(PartialPerm([1 .. 3])));
85Error, Semigroups: DirectProductOp: usage,
86the second argument must be one of the semigroups contained in <list>,
87
88#  semidp: DirectProductOp, for bipartition semigroups, errors, 1
89gap> DirectProductOp([], PartitionMonoid(1));
90Error, Semigroups: DirectProductOp: usage,
91the first argument must be a non-empty list,
92gap> DirectProductOp([PartitionMonoid(1)], PartitionMonoid(2));
93Error, Semigroups: DirectProductOp: usage,
94the second argument must be one of the semigroups contained in <list>,
95
96#  semidp: DirectProductOp, for PBR semigroups, errors, 1
97gap> DirectProductOp([], FullPBRMonoid(1));
98Error, Semigroups: DirectProductOp: usage,
99the first argument must be a non-empty list,
100gap> DirectProductOp([FullPBRMonoid(1)], FullPBRMonoid(2));
101Error, Semigroups: DirectProductOp: usage,
102the second argument must be one of the semigroups contained in <list>,
103
104#  semidp: DirectProductOp, for a mix of semigroups, errors, 1
105gap> S := ReesZeroMatrixSemigroup(Group([(1, 2)]), [[(), (1, 2)], [0, ()]]);
106<Rees 0-matrix semigroup 2x2 over Group([ (1,2) ])>
107gap> T := ReesMatrixSemigroup(SymmetricGroup(4), [[(1, 4, 3)], [()]]);
108<Rees matrix semigroup 1x2 over Sym( [ 1 .. 4 ] )>
109gap> DirectProductOp([], S);
110Error, Semigroups: DirectProductOp: usage,
111the first argument must be a non-empty list,
112gap> DirectProductOp([T], S);
113Error, Semigroups: DirectProductOp: usage,
114the second argument must be one of the semigroups contained in <list>,
115gap> DirectProductOp([S, T, FreeSemigroup(1)], S);
116Error, no method found! For debugging hints type ?Recovery from NoMethodFound
117Error, no 2nd choice method found for `DirectProductOp' on 2 arguments
118
119################################################################################
120# Testing transformation semigroups
121################################################################################
122
123#  semidp: DirectProduct, for transformation semigroups, 1
124gap> S := ZeroSemigroup(IsTransformationSemigroup, 2);
125<commutative non-regular transformation semigroup of size 2, degree 3 with 1
126 generator>
127gap> D := DirectProduct(S);;
128gap> ProductCheck(D, [S], true);
129true
130gap> S = D;
131true
132
133#  semidp: DirectProduct, for transformation semigroups, 2
134gap> S := ZeroSemigroup(IsTransformationSemigroup, 2);
135<commutative non-regular transformation semigroup of size 2, degree 3 with 1
136 generator>
137gap> D := DirectProduct(S, S, S);;
138gap> IsRegularSemigroup(D);
139false
140gap> D;
141<commutative non-regular transformation semigroup of size 8, degree 9 with 7
142 generators>
143gap> HasIndecomposableElements(D);
144true
145gap> IndecomposableElements(D);
146[ Transformation( [ 1, 1, 1, 4, 4, 4, 7, 7, 8 ] ),
147  Transformation( [ 1, 1, 1, 4, 4, 5, 7, 7, 7 ] ),
148  Transformation( [ 1, 1, 1, 4, 4, 5, 7, 7, 8 ] ),
149  Transformation( [ 1, 1, 2, 4, 4, 4, 7, 7, 7 ] ),
150  Transformation( [ 1, 1, 2, 4, 4, 4, 7, 7, 8 ] ),
151  Transformation( [ 1, 1, 2, 4, 4, 5, 7, 7, 7 ] ),
152  Transformation( [ 1, 1, 2, 4, 4, 5, 7, 7, 8 ] ) ]
153gap> HasMinimalSemigroupGeneratingSet(D);
154true
155gap> MinimalSemigroupGeneratingSet(D) = IndecomposableElements(D);
156true
157gap> ProductCheck(D, [S, S, S], true);
158true
159gap> D := Semigroup(D);
160<transformation semigroup of degree 9 with 7 generators>
161gap> IsZeroSemigroup(D) and Size(D) = 8;
162true
163gap> IndecomposableElements(D);
164[ Transformation( [ 1, 1, 1, 4, 4, 4, 7, 7, 8 ] ),
165  Transformation( [ 1, 1, 1, 4, 4, 5, 7, 7, 7 ] ),
166  Transformation( [ 1, 1, 1, 4, 4, 5, 7, 7, 8 ] ),
167  Transformation( [ 1, 1, 2, 4, 4, 4, 7, 7, 7 ] ),
168  Transformation( [ 1, 1, 2, 4, 4, 4, 7, 7, 8 ] ),
169  Transformation( [ 1, 1, 2, 4, 4, 5, 7, 7, 7 ] ),
170  Transformation( [ 1, 1, 2, 4, 4, 5, 7, 7, 8 ] ) ]
171
172#  semidp: DirectProduct, for transformation semigroups, 3
173gap> S := ZeroSemigroup(IsTransformationSemigroup, 3);
174<commutative non-regular transformation semigroup of size 3, degree 4 with 2
175 generators>
176gap> D := DirectProduct(S, S);;
177gap> IsRegularSemigroup(D);
178false
179gap> D;
180<commutative non-regular transformation semigroup of size 9, degree 8 with 8
181 generators>
182gap> ProductCheck(D, [S, S], true);
183true
184gap> D := Semigroup(D);
185<transformation semigroup of degree 8 with 8 generators>
186gap> IsZeroSemigroup(D) and Size(D) = 9;
187true
188
189#  semidp: DirectProduct, for transformation semigroups, 4
190gap> S := FullTransformationMonoid(3);
191<full transformation monoid of degree 3>
192gap> D := DirectProduct(S, S);;
193gap> IsRegularSemigroup(D);
194true
195gap> D;
196<regular transformation monoid of size 729, degree 6 with 6 generators>
197gap> ProductCheck(D, [S, S], false);
198true
199gap> HasIndecomposableElements(D);
200true
201gap> IndecomposableElements(D);
202[  ]
203gap> Set(GeneratorsOfMonoid(D));
204[ Transformation( [ 1, 2, 1 ] ), Transformation( [ 1, 2, 3, 4, 5, 4 ] ),
205  Transformation( [ 1, 2, 3, 5, 4 ] ), Transformation( [ 1, 2, 3, 5, 6, 4 ] ),
206  Transformation( [ 2, 1 ] ), Transformation( [ 2, 3, 1 ] ) ]
207gap> Size(D) = Size(S) ^ 2 and Size(D) = 27 ^ 2;
208true
209
210#  semidp: DirectProduct, for transformation semigroups, 5
211gap> S := Semigroup([
212> Transformation([1, 2, 3, 3, 3]),
213> Transformation([1, 1, 3, 3, 3])]);
214<transformation semigroup of degree 5 with 2 generators>
215gap> D := DirectProduct(S, S);
216<transformation semigroup of degree 10 with 3 generators>
217gap> ProductCheck(D, [S, S], true);
218true
219
220#  semidp: DirectProduct, for transformation semigroups, 6
221gap> list := [
222>  Semigroup([Transformation([1, 2, 3, 3, 3])]),
223>  Semigroup([Transformation([2, 1])])];;
224gap> D := DirectProduct(list);
225<commutative transformation semigroup of degree 7 with 2 generators>
226gap> ProductCheck(D, list, true);
227true
228gap> Elements(D);
229[ Transformation( [ 1, 2, 3, 3, 3 ] ),
230  Transformation( [ 1, 2, 3, 3, 3, 7, 6 ] ) ]
231gap> Size(D);
2322
233
234#  semidp: DirectProduct, for transformation semigroups, 7
235gap> list := [
236>  Semigroup([Transformation([2, 1])]),
237>  Semigroup([Transformation([1, 2, 3, 3, 3])])];;
238gap> D := DirectProduct(list);
239<commutative transformation semigroup of degree 7 with 2 generators>
240gap> ProductCheck(D, list, true);
241true
242gap> Elements(D);
243[ Transformation( [ 1, 2, 3, 4, 5, 5, 5 ] ),
244  Transformation( [ 2, 1, 3, 4, 5, 5, 5 ] ) ]
245gap> Size(D);
2462
247
248#  semidp: DirectProduct, for transformation semigroups, 8
249gap> list := [
250>  Semigroup([Transformation([1, 2, 3, 3, 3])]),
251>  Semigroup([Transformation([2, 1])]),
252>  Semigroup([Transformation([1, 1, 2, 3, 4])])];;
253gap> D := DirectProduct(list);
254<commutative transformation semigroup of degree 12 with 2 generators>
255gap> ProductCheck(D, list, true);
256true
257gap> Size(D);
2588
259gap> Elements(D);
260[ Transformation( [ 1, 2, 3, 3, 3, 6, 7, 8, 8, 8, 8, 8 ] ),
261  Transformation( [ 1, 2, 3, 3, 3, 6, 7, 8, 8, 8, 8, 9 ] ),
262  Transformation( [ 1, 2, 3, 3, 3, 6, 7, 8, 8, 8, 9, 10 ] ),
263  Transformation( [ 1, 2, 3, 3, 3, 6, 7, 8, 8, 9, 10, 11 ] ),
264  Transformation( [ 1, 2, 3, 3, 3, 7, 6, 8, 8, 8, 8, 8 ] ),
265  Transformation( [ 1, 2, 3, 3, 3, 7, 6, 8, 8, 8, 8, 9 ] ),
266  Transformation( [ 1, 2, 3, 3, 3, 7, 6, 8, 8, 8, 9, 10 ] ),
267  Transformation( [ 1, 2, 3, 3, 3, 7, 6, 8, 8, 9, 10, 11 ] ) ]
268
269################################################################################
270# Testing partial perm semigroups
271################################################################################
272
273#  semidp: DirectProduct, for partial perm semigroups, 1
274gap> S := Semigroup([PartialPerm([3], [3]), PartialPerm([2], [1])]);;
275gap> Size(S);
2763
277gap> D := DirectProduct(S);;
278gap> ProductCheck(D, [S], true);
279true
280gap> S = D;
281true
282
283#  semidp: DirectProduct, for partial perm semigroups, 2
284gap> S := Semigroup([PartialPerm([3], [3]), PartialPerm([2], [1])]);;
285gap> D := DirectProduct(S, S);;
286gap> ProductCheck(D, [S, S], true);
287true
288gap> Size(Semigroup(D)) = 9;
289true
290
291#  semidp: DirectProduct, for partial perm semigroups, 3
292gap> T := SymmetricInverseMonoid(3);
293<symmetric inverse monoid of degree 3>
294gap> D := DirectProduct(T, T, T);
295<inverse partial perm monoid of rank 9 with 9 generators>
296gap> ProductCheck(D, [T, T, T], false);
297true
298gap> D := InverseMonoid(D);
299<inverse partial perm monoid of rank 9 with 9 generators>
300gap> Size(D) = Size(T) ^ 3;
301true
302
303#  semidp: DirectProduct, for partial perm semigroups, 4
304gap> S := ZeroSemigroup(IsPartialPermSemigroup, 3);
305<commutative non-regular partial perm semigroup of size 3, rank 2 with 2
306 generators>
307gap> T := SymmetricInverseMonoid(3);
308<symmetric inverse monoid of degree 3>
309gap> D := DirectProduct(S, T, S);;
310gap> IsRegularSemigroup(D);
311false
312gap> D;
313<non-regular partial perm semigroup of size 306, rank 7 with 272 generators>
314gap> ProductCheck(D, [S, T, S], false);
315true
316
317#  semidp: DirectProduct, for partial perm semigroups, 5
318gap> T := SymmetricInverseMonoid(3);
319<symmetric inverse monoid of degree 3>
320gap> T := SemigroupIdeal(T, PartialPerm([1, 2]));;
321gap> T := InverseSemigroup(T);;
322gap> D := DirectProduct(T, T, T);;
323gap> ProductCheck(D, [T, T, T], false);
324true
325gap> D := Semigroup(D);;
326gap> Size(D) = Size(T) ^ 3;
327true
328
329#  semidp: DirectProduct, for partial perm semigroups, 6
330gap> S := DirectProduct(SymmetricInverseMonoid(3), SymmetricInverseMonoid(3));
331<inverse partial perm monoid of rank 6 with 6 generators>
332gap> Size(S) = 34 ^ 2;
333true
334
335#  semidp: DirectProduct, for partial perm semigroups, 7
336gap> S := Semigroup([PartialPerm([3], [3]), PartialPerm([2], [1])]);
337<partial perm semigroup of rank 2 with 2 generators>
338gap> Size(S);
3393
340gap> DirectProduct(S) = S;
341true
342
343#  semidp: DirectProduct, for partial perm semigroups, 8
344gap> S := Semigroup([PartialPerm([3], [3]), PartialPerm([2], [1])]);
345<partial perm semigroup of rank 2 with 2 generators>
346gap> T := DirectProduct(S, S);
347<partial perm semigroup of size 9, rank 4 with 6 generators>
348gap> ProductCheck(T, [S, S], true);
349true
350gap> T := Semigroup(T);
351<partial perm semigroup of rank 4 with 6 generators>
352gap> Size(T) = Size(S) ^ 2;
353true
354gap> D := DirectProduct(S, S, S);
355<partial perm semigroup of size 27, rank 6 with 20 generators>
356gap> ProductCheck(D, [S, S, S], false);
357true
358gap> D = DirectProduct(T, S);
359true
360gap> D := Semigroup(D);
361<partial perm semigroup of rank 6 with 20 generators>
362gap> Size(D) = Size(S) ^ 3;
363true
364
365#  semidp: DirectProductOp, for partial perm semigroups, 9
366gap> S := MonogenicSemigroup(IsPartialPermSemigroup, 5, 3);
367<commutative non-regular partial perm semigroup of size 7, rank 7 with 1
368 generator>
369gap> T := SymmetricInverseMonoid(3);
370<symmetric inverse monoid of degree 3>
371gap> D := DirectProduct(S, T);;
372gap> IsRegularSemigroup(D);
373false
374gap> D;
375<non-regular partial perm semigroup of size 238, rank 10 with 34 generators>
376gap> ProductCheck(D, [S, T], false);
377true
378gap> D := Semigroup(D);
379<partial perm semigroup of rank 10 with 34 generators>
380gap> Size(D);
381238
382gap> Size(D) = Size(S) * Size(T);
383true
384
385################################################################################
386# Testing bipartition semigroups
387################################################################################
388
389#  semidp: DirectProductOp, for bipartition semigroups, 1
390gap> S := Semigroup([
391>  Bipartition([[1, 3], [2, 4, -2], [5, -1, -3, -4], [-5]]),
392>  Bipartition([[1, 2, 3, 4, 5, -1, -5], [-2], [-3], [-4]]),
393>  Bipartition([[1, 2, 3, -1, -5], [4], [5, -2, -3, -4]])]);;
394gap> T := Semigroup([
395>  Bipartition([[1, 3, 4, 5, 6, -1, -4], [2, -2, -3, -5, -6]]),
396>  Bipartition([[1, 2, 3, 4, 5, -5], [6, -1, -2, -3, -4], [-6]])]);;
397gap> D := DirectProduct(S, T);
398<bipartition semigroup of size 100, degree 11 with 46 generators>
399gap> ProductCheck(D, [S, T], false);
400true
401gap> D := Semigroup(D);
402<bipartition semigroup of degree 11 with 46 generators>
403gap> Size(D);
404100
405gap> Size(S) * Size(T);
406100
407gap> D := DirectProduct(T, S);
408<bipartition semigroup of size 100, degree 11 with 46 generators>
409gap> ProductCheck(D, [T, S], false);
410true
411gap> D := Semigroup(D);
412<bipartition semigroup of degree 11 with 46 generators>
413gap> Size(D);
414100
415
416#  semidp: DirectProductOp, for bipartition semigroups, 2
417gap> S := ZeroSemigroup(IsBipartitionSemigroup, 3);
418<commutative non-regular bipartition semigroup of size 3, degree 4 with 2
419 generators>
420gap> T := ZeroSemigroup(IsBipartitionSemigroup, 5);
421<commutative non-regular bipartition semigroup of size 5, degree 5 with 4
422 generators>
423gap> D := DirectProduct(S, T);;
424gap> IsRegularSemigroup(D);
425false
426gap> D;
427<commutative non-regular bipartition semigroup of size 15, degree 9 with 14
428 generators>
429gap> ProductCheck(D, [S, T], true);
430true
431gap> D := Semigroup(D);;
432gap> IsZeroSemigroup(D) and Size(D) = Size(S) * Size(T);
433true
434gap> D := DirectProduct(T, S);;
435gap> IsRegularSemigroup(D);
436false
437gap> D;
438<commutative non-regular bipartition semigroup of size 15, degree 9 with 14
439 generators>
440gap> ProductCheck(D, [T, S], true);
441true
442gap> D := Semigroup(D);
443<bipartition semigroup of degree 9 with 14 generators>
444gap> IsZeroSemigroup(D) and Size(D) = Size(S) * Size(T);
445true
446gap> D := DirectProduct(S, PartitionMonoid(2), T);;
447gap> IsRegularSemigroup(D);
448false
449gap> D;
450<non-regular bipartition semigroup of size 225, degree 11 with 210 generators>
451gap> ProductCheck(D, [S, PartitionMonoid(2), T], false);
452true
453gap> D := Semigroup(D);
454<bipartition semigroup of degree 11 with 210 generators>
455gap> Size(D);
456225
457
458#  semidp: DirectProductOp, for bipartition semigroups, 3
459gap> S := PartitionMonoid(2);
460<regular bipartition *-monoid of size 15, degree 2 with 3 generators>
461gap> D := DirectProduct(S, S, S, S);;
462gap> IsRegularSemigroup(D);
463true
464gap> D;
465<regular bipartition monoid of size 50625, degree 8 with 12 generators>
466gap> ProductCheck(D, [S, S, S, S], false);
467true
468gap> D := Monoid(D);
469<bipartition monoid of degree 8 with 12 generators>
470gap> Size(D) = 15 ^ 4;
471true
472
473#  semidp: DirectProductOp, for bipartition semigroups, 4
474gap> list := [
475>  Semigroup([
476>    Bipartition([[1, 2, 3, -3], [-1, -2]]),
477>    Bipartition([[1, 2, 3, -1, -2], [-3]])]),
478>  Semigroup([
479>    Bipartition([[1], [2, -2], [3, -3], [-1]]),
480>    Bipartition([[1, 2, -1, -2, -3], [3]])]),
481>  Semigroup([Bipartition([[1, 3, -1, -2, -3], [2]]),
482>    Bipartition([[1, 3, -1, -2], [2, -3]])])];;
483gap> D := DirectProduct(list);;
484gap> ProductCheck(D, list, true);
485true
486
487################################################################################
488# Testing PBR semigroups
489################################################################################
490
491#  semidp: DirectProductOp, for PBR semigroups, 1
492gap> S := FullPBRMonoid(1);;
493gap> D := DirectProduct(S);;
494gap> IsRegularSemigroup(D);
495true
496gap> D;
497<regular pbr monoid of degree 1 with 4 generators>
498gap> ProductCheck(D, [S], true);
499true
500gap> D := DirectProduct(S, S);;
501gap> IsRegularSemigroup(D);
502true
503gap> D;
504<regular pbr monoid of degree 2 with 8 generators>
505gap> ProductCheck(D, [S, S], false);
506true
507gap> Size(D);
508256
509
510#  semidp: DirectProductOp, for PBR semigroups, 2
511gap> list := [
512>  Semigroup([
513>    PBR([[1, 2], [-2, 1, 2]], [[-1, 1], [-2, -1, 1]]),
514>    PBR([[2], [-2, 1, 2]], [[1, 2], [-2, 1]])]),
515>  Semigroup([
516>    PBR([[-1, 1]], [[1]])]),
517>  Semigroup([
518>    PBR([[], [-2, -1]], [[], [2]]),
519>    PBR([[-2, -1], []], [[2], []])])];;
520gap> D := DirectProduct(list);
521<pbr semigroup of size 35, degree 5 with 15 generators>
522gap> ProductCheck(D, list, true);
523true
524
525################################################################################
526# Testing mixing semigroups
527################################################################################
528
529#  semidp: DirectProductOp, for a mix of semigroups, 1
530gap> S := [
531> PartitionMonoid(1),
532> FullTransformationMonoid(1),
533> SymmetricInverseMonoid(1)];;
534gap> D := DirectProductOp(S, S[1]);
535<commutative transformation monoid of degree 4 with 2 generators>
536gap> D := DirectProductOp(S, S[2]);
537<commutative transformation monoid of degree 4 with 2 generators>
538gap> D := DirectProductOp(S, S[3]);
539<commutative transformation monoid of degree 4 with 2 generators>
540gap> last = last2 and last2 = last3;
541true
542gap> ProductCheck(D, S, true);
543true
544gap> Size(D);
5454
546
547#  semidp: DirectProductOp, for a mix of semigroups, 2
548gap> S := [
549> PartitionMonoid(1),
550> FullPBRMonoid(1),
551> FullTransformationMonoid(1),
552> SymmetricInverseMonoid(1)];;
553gap> D := DirectProductOp(S, S[2]);
554<transformation monoid of degree 20 with 6 generators>
555gap> ProductCheck(D, S, false);
556true
557
558#  semidp: DirectProductOp, for a mix of semigroups, 3
559gap> S := PartitionMonoid(1);;
560gap> T := FullTransformationMonoid(1);;
561gap> D := DirectProduct(S, T);;
562gap> IsInverseSemigroup(D);
563true
564gap> D;
565<commutative inverse transformation monoid of size 2, degree 2 with 1
566 generator>
567gap> ProductCheck(D, [S, T], true);
568true
569gap> D := DirectProduct(T, S);;
570gap> IsInverseMonoid(D);
571true
572gap> D;
573<commutative inverse transformation monoid of size 2, degree 2 with 1
574 generator>
575gap> ProductCheck(D, [T, S], true);
576true
577
578################################################################################
579# Other special direct product functions
580################################################################################
581
582# Embedding
583
584#  semidp: Embedding, for a semigroup with direct product info, 1
585gap> S := LeftZeroSemigroup(3);;
586gap> Embedding(S, 1);
587Error, no method found! For debugging hints type ?Recovery from NoMethodFound
588Error, no 1st choice method found for `Embedding' on 2 arguments
589gap> D := DirectProduct(S, S, S);;
590gap> Unbind(SemigroupDirectProductInfo(D).embeddings);
591gap> Embedding(D, 4);
592Error, Semigroups: Embedding: usage,
593the index <i> must be in the range [1 .. 3], since the direct product <D>
594consists of only 3 factors,
595gap> Embedding(D, 1);
596MappingByFunction( <transformation semigroup of degree 4 with 3 generators>,
597<transformation semigroup of degree 12 with 27 generators>
598 , function( x ) ... end )
599gap> Embedding(D, 1) = last;
600true
601gap> Unbind(SemigroupDirectProductInfo(D).embeddings[1]);
602gap> Unbind(SemigroupDirectProductInfo(D).nrfactors);
603gap> Embedding(D, 1);
604Error, Semigroups: Embedding: usage,
605the direct product information for <D> has become corrupted,
606please re-create the object,
607gap> SemigroupDirectProductInfo(D).nrfactors := 3;;
608gap> Embedding(D, 3);
609MappingByFunction( <transformation semigroup of degree 4 with 3 generators>,
610<transformation semigroup of degree 12 with 27 generators>
611 , function( x ) ... end )
612gap> Unbind(SemigroupDirectProductInfo(D).embeddings[3]);
613gap> Unbind(SemigroupDirectProductInfo(D).embedding);
614gap> Embedding(D, 3);
615Error, Semigroups: Embedding: usage,
616the direct product information for <D> has become corrupted,
617please re-create the object,
618
619#  semidp: Embedding and Projection, for a semigroup with direct product info
620gap> list := [
621>  Semigroup([
622>    Transformation([5, 1, 4, 1, 1]),
623>    Transformation([5, 3, 3, 4, 5]),
624>    Transformation([4, 1, 4, 5, 1])]),
625>  Semigroup([
626>    Transformation([6, 4, 4, 4, 6, 5, 2]),
627>    Transformation([6, 5, 1, 7, 5, 1, 7])]),
628>  Semigroup([
629>    Transformation([3, 2, 2]),
630>    Transformation([2, 1, 1]),
631>    Transformation([2, 1, 2])])];
632[ <transformation semigroup of degree 5 with 3 generators>,
633  <transformation semigroup of degree 7 with 2 generators>,
634  <transformation semigroup of degree 3 with 3 generators> ]
635gap> D := DirectProduct(list);
636<transformation semigroup of degree 15 with 625 generators>
637gap> e := [];;
638gap> e[1] := Embedding(D, 1);
639MappingByFunction( <transformation semigroup of size 55, degree 5 with 3
640 generators>, <transformation semigroup of degree 15 with 625 generators>
641 , function( x ) ... end )
642gap> e[2] := Embedding(D, 2);
643MappingByFunction( <transformation semigroup of degree 7 with 2 generators>,
644<transformation semigroup of degree 15 with 625 generators>
645 , function( x ) ... end )
646gap> e[3] := Embedding(D, 3);
647MappingByFunction( <transformation semigroup of size 11, degree 3 with 3
648 generators>, <transformation semigroup of degree 15 with 625 generators>
649 , function( x ) ... end )
650gap> p := [];;
651gap> p[1] := Projection(D, 1);
652MappingByFunction( <transformation semigroup of degree 15 with 625 generators>
653 , <transformation semigroup of size 55, degree 5 with 3 generators>
654 , function( x ) ... end )
655gap> p[2] := Projection(D, 2);
656MappingByFunction( <transformation semigroup of degree 15 with 625 generators>
657 , <transformation semigroup of degree 7 with 2 generators>
658 , function( x ) ... end )
659gap> p[3] := Projection(D, 3);
660MappingByFunction( <transformation semigroup of degree 15 with 625 generators>
661 , <transformation semigroup of size 11, degree 3 with 3 generators>
662 , function( x ) ... end )
663gap> ProductCheck(D, list, false);
664true
665gap> gens := List([1 .. 3],
666>         i -> List(GeneratorsOfSemigroup(list[i]), x -> x ^ e[i]));;
667gap> embeds := List([1 .. 3], i -> Semigroup(gens[i]));
668[ <transformation semigroup of degree 15 with 3 generators>,
669  <transformation semigroup of degree 15 with 2 generators>,
670  <transformation semigroup of degree 15 with 3 generators> ]
671gap> ForAll([1 .. 3], i -> Size(list[i]) = Size(embeds[i]));
672true
673gap> projects := List([1 .. 3], i -> ImagesSet(p[i], embeds[i]));;
674gap> ForAll([1 .. 3], i -> Size(list[i]) = Size(projects[i]));
675true
676
677# Projection
678
679#  semidp: Projection, for a semigroup with direct product info, 1
680gap> S := RightZeroSemigroup(3);;
681gap> Projection(S, 1);
682Error, no method found! For debugging hints type ?Recovery from NoMethodFound
683Error, no 1st choice method found for `Projection' on 2 arguments
684gap> D := DirectProduct(S, S, S);;
685gap> Unbind(SemigroupDirectProductInfo(D).projections);
686gap> Projection(D, 4);
687Error, Semigroups: Projection: usage,
688the index <i> must be in the range [1 .. 3], since the direct product <D>
689consists of only 3 factors,
690gap> Projection(D, 1);
691MappingByFunction( <transformation semigroup of degree 9 with 27 generators>,
692<transformation semigroup of degree 3 with 3 generators>
693 , function( x ) ... end )
694gap> Projection(D, 1) = last;
695true
696gap> Unbind(SemigroupDirectProductInfo(D).projections[1]);
697gap> Unbind(SemigroupDirectProductInfo(D).nrfactors);
698gap> Projection(D, 1);
699Error, Semigroups: Projection: usage,
700the direct product information for <D> has become corrupted,
701please re-create the object,
702gap> SemigroupDirectProductInfo(D).nrfactors := 3;;
703gap> Projection(D, 3);
704MappingByFunction( <transformation semigroup of degree 9 with 27 generators>,
705<transformation semigroup of degree 3 with 3 generators>
706 , function( x ) ... end )
707gap> Unbind(SemigroupDirectProductInfo(D).projections[3]);
708gap> Unbind(SemigroupDirectProductInfo(D).projection);
709gap> Projection(D, 3);
710Error, Semigroups: Projection: usage,
711the direct product information for <D> has become corrupted,
712please re-create the object,
713
714# Size
715
716#  semidp: Size, for a semigroup with direct product info, 1
717gap> S := Semigroup(FullTransformationMonoid(2));;
718gap> D := DirectProduct(S, S, S);;
719gap> HasSize(D);
720false
721gap> Size(D) = Size(S) ^ 3;
722true
723gap> Size(D);
72464
725
726#  semidp: Size, for a semigroup with direct product info, 2
727gap> S := Monoid([Transformation([2, 1]), Transformation([1, 1])]);;
728gap> Size(DirectProduct(S));
7294
730
731# IsCommutative
732
733#  semidp: IsCommutativeSemigroup, for a semigroup with direct product info, 1
734gap> S := IdempotentGeneratedSubsemigroup(DualSymmetricInverseMonoid(4));;
735gap> T := SymmetricInverseMonoid(1);;
736gap> D := DirectProduct(S, T);;
737gap> IsCommutativeSemigroup(D);
738true
739
740#  semidp: IsCommutativeSemigroup, for a semigroup with direct product info, 2
741gap> S := IdempotentGeneratedSubsemigroup(DualSymmetricInverseMonoid(4));;
742gap> T := FullTransformationMonoid(2);;
743gap> D := DirectProduct(S, T);;
744gap> IsCommutativeSemigroup(D);
745false
746
747#  semidp: IsCommutativeSemigroup, for a semigroup with direct product info, 3
748gap> S := Monoid([Transformation([2, 1]), Transformation([1, 1])]);;
749gap> IsCommutativeSemigroup(DirectProduct(S));
750false
751
752#  semidp: DirectProduct, for a semigroup with repeated generators
753gap> S := Semigroup([
754>  PBR([[-2, 1, 2], [-2, -1, 2]], [[-2, -1, 1, 2], [-2, -1, 1, 2]]),
755>  PBR([[-2, -1, 1, 2], [-2, -1, 1, 2]], [[-2, -1, 1, 2], [-2, -1, 1, 2]]),
756>  PBR([[-2, -1, 1, 2], [-2, -1, 1, 2]], [[-2, -1, 1, 2], [-2, -1, 1, 2]]),
757>  PBR([[-2, -1, 1, 2], [-1]], [[-2, 1], [-2, -1, 1, 2]]),
758>  PBR([[-2, 1], [-2, 2]], [[-2, -1], [-2, -1, 2]]),
759>  PBR([[-2, -1, 1, 2], [-2, -1, 2]], [[-2, -1, 1, 2], [-2, -1, 1, 2]]),
760>  PBR([[-1], [-2]], [[-2, 1], [2]])]);;
761gap> Size(S);
76215
763gap> Size(Semigroup(DirectProduct(S, S)));
764225
765
766#  semidp: DirectProduct, for very large semigroups
767gap> S := FullTransformationMonoid(50);;
768gap> S := DirectProduct(S, S, S);;
769gap> Size(S);
770700649232162408535461864791644958065640130970938257885878534141944895541342930\
771300743319094181060791015625000000000000000000000000000000000000000000000000000\
772000000000000000000000000000000000000000000000000000000000000000000000000000000\
773000000000000000000000
774
775#  SEMIGROUPS_UnbindVariables
776gap> Unbind(list);
777gap> Unbind(S);
778gap> Unbind(T);
779gap> Unbind(D);
780gap> Unbind(e);
781gap> Unbind(p);
782gap> Unbind(embeds);
783gap> Unbind(projects);
784gap> Unbind(gens);
785
786#E#
787gap> SEMIGROUPS.StopTest();
788gap> STOP_TEST("Semigroups package: standard/semidp.tst");
789