diff --git a/doc/attr.xml b/doc/attr.xml
index f576823cc..284510215 100644
--- a/doc/attr.xml
+++ b/doc/attr.xml
@@ -1317,6 +1317,41 @@ true]]>
<#/GAPDoc>
+<#GAPDoc Label="MitschOrderOfSemigroup">
+
+
+ The Mitsch partial order on a semigroup.
+
+ The Mitsch partial order \leq on a semigroup S
+ is defined by a\leqb if there exists s and
+ t in S^1 such that
+ tb=ta=a=as=bs.
+ MitschOrderOfSemigroup returns the Mitsch partial order on the
+ semigroup S as a list of sets of positive integers where
+ entry i in MitschOrderOfSemigroup(S) is the set of
+ positions in Elements(S) of elements which are less than
+ Elements(S)[i]. See also .
+ S := BrauerMonoid(3);
+
+gap> IsRegularSemigroup(S);
+true
+gap> Size(S);
+15
+gap> NambooripadPartialOrder(S);
+[ [ ], [ ], [ ], [ ], [ ], [ ], [ ], [ ], [ ],
+ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
+ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
+ [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ], [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] ]
+gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[3], Elements(S)[9]);
+false
+gap> NambooripadLeqRegularSemigroup(S)(Elements(S)[2], Elements(S)[15]);
+true]]>
+
+
+<#/GAPDoc>
+
<#GAPDoc Label="SmallerDegreeTransformationRepresentation">
diff --git a/doc/trans.xml b/doc/trans.xml
index ce0ede604..a785ef41f 100644
--- a/doc/trans.xml
+++ b/doc/trans.xml
@@ -43,3 +43,40 @@ Transformation( [ 3, 5, 2, 2, 2 ] )]]>
<#/GAPDoc>
+
+<#GAPDoc Label="IsRefinementKernelOfTransformation">
+
+
+
+ True or False.
+
+
+ If trans1 and trans2 are two transformations belonging
+ to a transformation semigroup of degree n, then
+ IsRefinementKernelOfTransformation returns True if the kernel of
+ trans1 is a refinement of the kernel of trans2 and returns
+ False otherwise.
+ An error message will be raised if trans1 or trans2 has degree
+ higher than n and hence cannot belong to a semigroup of degree
+ n.
+ s := Transformation([2,2,3,2]);
+Transformation( [ 2, 2, 3, 2 ] )
+gap> t := Transformation([2,2,3,3]);
+Transformation( [ 2, 2, 3, 3 ] )
+gap> IsRefinementKernelOfTransformation(s, t, 4);
+false
+gap> a := Transformation([2,4,3,2]);
+Transformation( [ 2, 4, 3, 2 ] )
+gap> b := Transformation([3,3,1,3]);
+Transformation( [ 3, 3, 1, 3 ] )
+gap> IsRefinementKernelOfTransformation(a, b, 4);
+false
+gap> IsRefinementKernelOfTransformation(b, a, 4);
+true
+gap> IsRefinementKernelOfTransformation(b, a, 3);
+Error, Degree of the first transformation greater than 3.
+Expecting a degree at most n, found 4 instead.]]>
+
+
+<#/GAPDoc>
diff --git a/doc/z-chap11.xml b/doc/z-chap11.xml
index 0d95c97a5..efb4ff5e3 100644
--- a/doc/z-chap11.xml
+++ b/doc/z-chap11.xml
@@ -210,6 +210,7 @@
<#Include Label = "SmallestElementSemigroup">
<#Include Label = "CanonicalTransformation">
<#Include Label = "IsConnectedTransformationSemigroup">
+ <#Include Label = "IsRefinementKernelOfTransformation">
@@ -277,6 +278,16 @@
+
+
+
+ Mitsch partial order
+
+
+ <#Include Label = "MitschOrderOfSemigroup">
+
+
+
diff --git a/gap/attributes/attr.gd b/gap/attributes/attr.gd
index bf54289b1..b80d322d9 100644
--- a/gap/attributes/attr.gd
+++ b/gap/attributes/attr.gd
@@ -72,6 +72,16 @@ DeclareAttribute("IndecomposableElements", IsSemigroup);
DeclareAttribute("NambooripadLeqRegularSemigroup", IsSemigroup);
DeclareAttribute("NambooripadPartialOrder", IsSemigroup);
+DeclareOperation("KernelContainment",
+ [IsTransformation, IsTransformation, IsPosInt]);
+DeclareAttribute("RegularLeqTransformationSemigroupNC", IsTransformationSemigroup);
+DeclareAttribute("MitschLeqSemigroupNC", IsSemigroup);
+DeclareAttribute("MitschLeqSemigroup", IsSemigroup);
+DeclareAttribute("MitschOrderOfTransformationSemigroup",
+ IsFinite and IsTransformationSemigroup);
+DeclareAttribute("MitschOrderOfSemigroup", IsFinite and IsSemigroup);
+DeclareAttribute("DumbMitschOrderOfSemigroup", IsFinite and IsSemigroup);
+
DeclareOperation("LeftIdentity", [IsSemigroup, IsMultiplicativeElement]);
DeclareOperation("RightIdentity", [IsSemigroup, IsMultiplicativeElement]);
diff --git a/gap/attributes/attr.gi b/gap/attributes/attr.gi
index f12a48f40..560c7094a 100644
--- a/gap/attributes/attr.gi
+++ b/gap/attributes/attr.gi
@@ -1045,13 +1045,173 @@ function(S)
return
function(x, y)
- local R;
- R := RClass(S, x);
- return IsGreensLessThanOrEqual(R, RClass(S, y))
- and ForAny(Idempotents(R), e -> e * y = x);
+ local E;
+ E := Idempotents(S);
+ return ForAny(E, e -> e * y = x)
+ and ForAny(E, f -> y * f = x);
end;
end);
+SEMIGROUPS.ExistsTransversal := function(a, b, n)
+ local exists, class, i;
+ if DegreeOfTransformation(a) > n or
+ DegreeOfTransformation(b) > n then
+ ErrorNoReturn("Transformation does not",
+ "belong to a transformation semigroup of degree n");
+ fi;
+ for class in KernelOfTransformation(a, n) do
+ exists := false;
+ for i in [1 .. Size(class)] do
+ if class[i] ^ a = class[i] ^ b then
+ exists := true;
+ break;
+ fi;
+ od;
+ if not exists then
+ return false;
+ fi;
+ od;
+ return true;
+end;
+
+InstallMethod(RegularLeqTransformationSemigroupNC,
+#intended for internal use; see MitschLeqSemigroup for public use
+"for a transformation semigroup",
+[IsTransformationSemigroup],
+function(S)
+ local deg;
+ deg := DegreeOfTransformationSemigroup(S);
+ return
+ function(x, y)
+ # Only returns the correct answer if y is a regular element
+ return IsRefinementKernelOfTransformation(x, y, deg)
+ and SEMIGROUPS.ExistsTransversal(x, y, deg);
+ end;
+end);
+
+InstallMethod(MitschLeqSemigroupNC,
+"for a semigroup",
+[IsSemigroup],
+function(S)
+ return
+ function(x, y)
+ if x = y then
+ return true;
+ else
+ return ForAny(Elements(S), s -> x = x * s and x = y * s) and
+ ForAny(Elements(S), t -> t * y = x and t * x = x);
+ fi;
+ end;
+end);
+
+InstallMethod(MitschLeqSemigroup,
+"for a semigroup",
+[IsSemigroup],
+function(S)
+ if IsInverseSemigroup(S) then
+ return NaturalLeqInverseSemigroup(S);
+ elif IsRegularSemigroup(S) and IsTransformationSemigroup(S) then
+ return RegularLeqTransformationSemigroupNC(S);
+ elif IsRegularSemigroup(S) then
+ return NambooripadLeqRegularSemigroup(S);
+ else
+ return MitschLeqSemigroupNC(S);
+ fi;
+end);
+
+InstallMethod(MitschOrderOfSemigroup,
+"for a finite transformation semigroup",
+[IsTransformationSemigroup],
+function(S)
+ local elts, p, func1, func2, out, i, j, regular, D, a;
+ elts := ShallowCopy(AsListCanonical(S));
+ p := Sortex(elts, {x, y} -> IsGreensDGreaterThanFunc(S)(y, x)) ^ -1;
+ func1 := RegularLeqTransformationSemigroupNC(S);
+ func2 := MitschLeqSemigroupNC(S);
+ out := List([1 .. Size(S)], x -> []);
+ regular := BlistList([1 .. Size(S)], []);
+ for D in RegularDClasses(S) do
+ for a in D do
+ i := PositionCanonical(S, a) ^ (p ^ -1);
+ regular[i] := true;
+ od;
+ od;
+ for j in [Size(S), Size(S) - 1 .. 1] do
+ if regular[j] then
+ for i in [j - 1, j - 2 .. 1] do
+ if func1(elts[i], elts[j]) then
+ AddSet(out[j ^ p], i ^ p);
+ fi;
+ od;
+ else
+ for i in [j - 1, j - 2 .. 1] do
+ if func2(elts[i], elts[j]) then
+ AddSet(out[j ^ p], i ^ p);
+ fi;
+ od;
+ fi;
+ od;
+ return out;
+end);
+
+InstallMethod(MitschOrderOfSemigroup,
+"for a finite regular transformation semigroup",
+[IsRegularSemigroup and IsTransformationSemigroup],
+function(S)
+ local elts, p, func, out, i, j;
+ elts := ShallowCopy(Elements(S));
+ p := Sortex(elts, {x, y} -> IsGreensDGreaterThanFunc(S)(y, x)) ^ -1;
+ func := RegularLeqTransformationSemigroupNC(S);
+ out := List([1 .. Size(S)], x -> []);
+ for i in [1 .. Size(S)] do
+ for j in [i + 1 .. Size(S)] do
+ if func(elts[i], elts[j]) then
+ AddSet(out[j ^ p], i ^ p);
+ fi;
+ od;
+ od;
+ return out;
+end);
+
+InstallMethod(MitschOrderOfSemigroup,
+"for a finite semigroup",
+[IsFinite and IsSemigroup],
+function(S)
+ local i, iso, T, MT, MS, eltsS, eltsT, idx_map, q;
+ iso := IsomorphismTransformationSemigroup(S);
+ T := Range(iso);
+ eltsS := Elements(S);
+ eltsT := Elements(T);
+ idx_map := List([1 .. Size(S)], i -> Position(eltsT, eltsS[i] ^ iso));
+ q := PermList(idx_map);
+ MT := MitschOrderOfSemigroup(T);
+ MS := [];
+ for i in [1 .. Size(S)] do
+ MS[i] := AsSet(OnTuples(MT[i ^ q], q ^ -1));
+ od;
+ return MS;
+end);
+
+InstallMethod(DumbMitschOrderOfSemigroup,
+"for a finite semigroup",
+[IsSemigroup and IsFinite],
+function(S)
+ local func, out, i, j, elts;
+ func := MitschLeqSemigroup(S);
+ elts := Elements(S);
+ out := List([1 .. Size(S)], x -> []);
+ for i in [1 .. Size(S)] do
+ for j in [1 .. Size(S)] do
+ if i = j then
+ continue;
+ elif func(elts[i], elts[j]) then
+ AddSet(out[j], i);
+ fi;
+ od;
+ od;
+ return out;
+end);
+
InstallMethod(LeftIdentity,
"for semigroup with CanUseFroidurePin and mult. elt.",
[IsSemigroup and CanUseFroidurePin, IsMultiplicativeElement],
diff --git a/gap/elements/trans.gd b/gap/elements/trans.gd
index 5bef30c5f..1feec1556 100644
--- a/gap/elements/trans.gd
+++ b/gap/elements/trans.gd
@@ -11,3 +11,7 @@ DeclareAttribute("CanonicalTransformation", IsTransformation);
DeclareOperation("CanonicalTransformation", [IsTransformation, IsInt]);
DeclareOperation("TransformationByImageAndKernel",
[IsHomogeneousList, IsCyclotomicCollColl]);
+DeclareOperation("IsRefinementKernelOfTransformation",
+ [IsTransformation, IsTransformation, IsInt]);
+DeclareOperation("IsRefinementKernelOfTransformation",
+ [IsTransformation, IsTransformation]);
diff --git a/gap/elements/trans.gi b/gap/elements/trans.gi
index 296fb2830..3390a43db 100644
--- a/gap/elements/trans.gi
+++ b/gap/elements/trans.gi
@@ -48,3 +48,60 @@ end);
InstallMethod(IndexPeriodOfSemigroupElement, "for a transformation",
[IsTransformation], IndexPeriodOfTransformation);
+
+InstallMethod(IsRefinementKernelOfTransformation,
+"for two transformations in a semigroup of degree n",
+[IsTransformation, IsTransformation, IsInt],
+function(a, b, n)
+ local m, i, idx, q, class;
+ if DegreeOfTransformation(a) > n then
+ ErrorNoReturn("Degree of the first transformation greater than ", n,
+ ".\nExpecting a degree at most n, found ", DegreeOfTransformation(a),
+ " instead.");
+ fi;
+ if DegreeOfTransformation(b) > n then
+ ErrorNoReturn("Degree of the second transformation greater than ", n,
+ ".\nExpecting a degree at most n, found ", DegreeOfTransformation(b),
+ " instead.");
+ fi;
+ q := [];
+ for class in KernelOfTransformation(a, n) do
+ m := Minimum(class);
+ for i in class do
+ q[i] := m;
+ od;
+ od;
+ for class in KernelOfTransformation(b, n) do
+ idx := q[class[1]];
+ for i in class do
+ if q[i] <> idx then
+ return false;
+ fi;
+ od;
+ od;
+ return true;
+end);
+
+InstallMethod(IsRefinementKernelOfTransformation,
+"for two transformations",
+[IsTransformation, IsTransformation],
+function(a, b)
+ local m, i, idx, q, class, n;
+ n := Maximum(DegreeOfTransformation(a), DegreeOfTransformation(b));
+ q := [];
+ for class in KernelOfTransformation(a, n) do
+ m := Minimum(class);
+ for i in class do
+ q[i] := m;
+ od;
+ od;
+ for class in KernelOfTransformation(b, n) do
+ idx := q[class[1]];
+ for i in class do
+ if q[i] <> idx then
+ return false;
+ fi;
+ od;
+ od;
+ return true;
+end);
\ No newline at end of file
diff --git a/tst/standard/semigroups/semitrans.tst b/tst/standard/semigroups/semitrans.tst
index 401ee3599..66984d039 100644
--- a/tst/standard/semigroups/semitrans.tst
+++ b/tst/standard/semigroups/semitrans.tst
@@ -11,6 +11,7 @@
#@local B, BruteForceInverseCheck, BruteForceIsoCheck, C, CC, D, DP, F
#@local LoopIterator, M, Noop, R, S, S1, S2, T, TC, TestIterator, W, WW, acting
#@local coll, gr, inv, iso, iter1, iter2, len, list, map, n, rels, valid, x, y
+#@local a, b
gap> START_TEST("Semigroups package: standard/semigroups/semitrans.tst");
gap> LoadPackage("semigroups", false);;
@@ -2753,6 +2754,19 @@ gap> IsomorphismTransformationSemigroup(MinimalIdeal(FreeBand(2)));
->
+# IsRefinementOfKernelTransformation
+gap> a := Transformation([2,4,3,2]);
+Transformation( [ 2, 4, 3, 2 ] )
+gap> b := Transformation([3,3,1,3]);
+Transformation( [ 3, 3, 1, 3 ] )
+gap> IsRefinementKernelOfTransformation(a, b, 4);
+false
+gap> IsRefinementKernelOfTransformation(b, a, 4);
+true
+gap> IsRefinementKernelOfTransformation(b, a, 3);
+Error, Degree of the first transformation greater than 3.
+Expecting a degree at most n, found 4 instead.
+
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/semigroups/semitrans.tst");