Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/smallsemi/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 25.1.2025 mit Größe 21 kB image not shown  

Quelle  greensstar.gi   Sprache: unbekannt

 
#############################################################################
##
##  greensstar.gi                  Smallsemi - a GAP library of semigroups
##  Copyright (C) 2008-2024            Andreas Distler & James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

# This file contains the implementations for starred Green's relations of
# semigroups.

# Returns the appropriate equivalence relation which is stored as an attribute.
# The relation knows nothing about itself except its source, range, and what
# type of congruence it is.
InstallMethod(RStarRelation, "for a small semigroup", [IsSmallSemigroup],
function(X)
  local fam, rel;

  fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)),
                               ElementsFamily(FamilyObj(X)));

  # Create the default type for the elements.
  rel := Objectify(NewType(fam, IsEquivalenceRelation
                                and IsEquivalenceRelationDefaultRep
                                and IsRStarRelation), rec());
  SetSource(rel, X);
  SetRange(rel, X);
  # AD The following causes weird viewing of the relation on the command line
  SetIsLeftSemigroupCongruence(rel, true);
  if HasIsFinite(X) and IsFinite(X) then
    SetIsFiniteSemigroupStarRelation(rel, true);
  fi;

  # AD rel is objectified using IsRStarRelation, so other Green's relations
  # should not be set to the same object; classes might be set at the point
  # where they are actually computed, i.e. RStarClasses

  return rel;
end);

InstallMethod(LStarRelation, "for a small semigroup", [IsSmallSemigroup],
function(X)
  local fam, rel;

  fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)),
                               ElementsFamily(FamilyObj(X)));

  # Create the default type for the elements.
  rel := Objectify(NewType(fam, IsEquivalenceRelation
                                and IsEquivalenceRelationDefaultRep
                                and IsLStarRelation), rec());

  SetSource(rel, X);
  SetRange(rel, X);
  # AD The following causes weird viewing of the relation on the command line
  SetIsRightSemigroupCongruence(rel, true);
  if HasIsFinite(X) and IsFinite(X) then
    SetIsFiniteSemigroupStarRelation(rel, true);
  fi;

  return rel;
end);

InstallMethod(JStarRelation, "for a small semigroup", [IsSmallSemigroup],
function(X)
  local fam, rel;

  fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)),
                               ElementsFamily(FamilyObj(X)));

  # Create the default type for the elements.
  rel := Objectify(NewType(fam, IsEquivalenceRelation
                                and IsEquivalenceRelationDefaultRep
                                and IsJStarRelation), rec());

  SetSource(rel, X);
  SetRange(rel, X);
  if HasIsFinite(X) and IsFinite(X) then
    SetIsFiniteSemigroupStarRelation(rel, true);
  fi;

  return rel;
end);

InstallMethod(DStarRelation, "for a small semigroup", [IsSmallSemigroup],
function(X)
    local fam, rel;

    fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)),
                                 ElementsFamily(FamilyObj(X)));

    # Create the default type for the elements.
    rel := Objectify(NewType(fam, IsEquivalenceRelation
                                  and IsEquivalenceRelationDefaultRep
                                  and IsDStarRelation), rec());

    SetSource(rel, X);
    SetRange(rel, X);

    if HasIsFinite(X) and IsFinite(X) then
      SetIsFiniteSemigroupStarRelation(rel, true);
    fi;

    return rel;
end);

InstallMethod(HStarRelation, "for a small semigroup", [IsSmallSemigroup],
function(X)
  local fam, rel;

  fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(X)),
                               ElementsFamily(FamilyObj(X)));

  # Create the default type for the elements.
  rel := Objectify(NewType(fam, IsEquivalenceRelation
                                and IsEquivalenceRelationDefaultRep
                                and IsHStarRelation), rec());

  SetSource(rel, X);
  SetRange(rel, X);

  if HasIsFinite(X) and IsFinite(X) then
    SetIsFiniteSemigroupStarRelation(rel, true);
  fi;

  return rel;
end);

### AD The following methods should probably be installed for ViewString

BindGlobal("SMALLSEMI_ViewStarRelation",
function(obj, type)
  Print("<", type, "*-relation on ");
  ViewObj(Source(obj));
  Print(">");
end);

# AD This is overwritten by the method for LeftSemigroupCongruence
InstallMethod(ViewObj, "for Green's R*-relation", [IsRStarRelation],
16,  # to beat IsLeftSemigroupCongruence
obj -> SMALLSEMI_ViewStarRelation(obj, "R"));

# AD This is overwritten by the method for RightSemigroupCongruence
InstallMethod(ViewObj, "for Green's L*-relation", [IsLStarRelation],
16,  # to beat IsRightSemigroupCongruence
obj -> SMALLSEMI_ViewStarRelation(obj, "L"));

InstallMethod(ViewObj, "for Green's J*-relation", [IsJStarRelation],
obj -> SMALLSEMI_ViewStarRelation(obj, "J"));

InstallMethod(ViewObj, "for Green's D*-relation", [IsDStarRelation],
obj -> SMALLSEMI_ViewStarRelation(obj, "D"));

InstallMethod(ViewObj, "for Green's H*-relation", [IsHStarRelation],
obj -> SMALLSEMI_ViewStarRelation(obj, "H"));

InstallMethod(\=, "for starred Green's relations", IsIdenticalObj,
[IsStarRelation and IsEquivalenceRelation,
 IsStarRelation and IsEquivalenceRelation],
function(rel1, rel2)
  if Source(rel1) <> Source(rel2) then
    return false;
  fi;
  # make sure the internal representation is known
  EquivalenceClasses(rel1);
  EquivalenceClasses(rel2);
  return InternalRepStarRelation(rel1) = InternalRepStarRelation(rel2);
end);

# The following operations are constructors for starred Green's class with
# a given element as a representative. The call is for semigroups
# and an element in the semigroup. This function doesn't check that
# the element is actually a member of the semigroup.

InstallMethod(RStarClass, "for a small semigroup ", IsCollsElms,
[IsSmallSemigroup, IsSmallSemigroupElt],
{s, e} -> EquivalenceClassOfElement(RStarRelation(s), e));

InstallMethod(LStarClass, "for a small semigroup", IsCollsElms,
[IsSmallSemigroup, IsSmallSemigroupElt],
{s, e} -> EquivalenceClassOfElement(LStarRelation(s), e));

InstallMethod(HStarClass, "for a small semigroup", IsCollsElms,
[IsSmallSemigroup, IsSmallSemigroupElt],
{s, e} -> EquivalenceClassOfElement(HStarRelation(s), e));

InstallMethod(DStarClass, "for a small semigroup", IsCollsElms,
[IsSmallSemigroup, IsSmallSemigroupElt],
{s, e} -> EquivalenceClassOfElement(DStarRelation(s), e));

InstallMethod(JStarClass, "for a small semigroup", IsCollsElms,
[IsSmallSemigroup, IsSmallSemigroupElt],
{s, e} -> EquivalenceClassOfElement(JStarRelation(s), e));

# Methods to get any starred Green's class in its canonical form

InstallMethod(CanonicalStarClass, "for a H*-class", [IsHStarClass],
cl -> First(HStarClasses(ParentAttr(cl)), y -> Representative(cl) in y));

InstallMethod(CanonicalStarClass, "for a R * - class", [IsRStarClass],
cl -> First(RStarClasses(ParentAttr(cl)), y -> Representative(cl) in y));

InstallMethod(CanonicalStarClass, "for a L*-class", [IsLStarClass],
cl -> First(LStarClasses(ParentAttr(cl)), y -> Representative(cl) in y));

InstallMethod(CanonicalStarClass, "for a D*-class", [IsDStarClass],
cl -> First(DStarClasses(ParentAttr(cl)), y -> Representative(cl) in y));

InstallMethod(CanonicalStarClass, "for a J*-class", [IsJStarClass],
cl -> First(JStarClasses(ParentAttr(cl)), y -> Representative(cl) in y));

# method to find the images under a starred Green's relation of an
# element of a semigroup.

InstallMethod(ImagesElm, "for a starred Green's relation",
[IsStarRelation, IsObject],
function(rel, elm)
  local exp, semi;

  semi := Source(rel);

  if IsRStarRelation(rel) then
    exp := RStarClass(semi, elm);
  elif IsLStarRelation(rel) then
    exp := LStarClass(semi, elm);
  elif IsHStarRelation(rel) then
    exp := HStarClass(semi, elm);
  elif IsDStarRelation(rel) then
    exp := DStarClass(semi, elm);
  elif IsJStarRelation(rel) then
    exp := JStarClass(semi, elm);
  fi;

  return AsSSortedList(exp);
end);

# Returns ImagesElm for one element in each class of <grelation>

InstallMethod(Successors, "for a starred Green's relation",
[IsStarRelation],
rel -> List(EquivalenceClasses(rel), AsSSortedList));

# Returns the elements of the *-class <gclass>

InstallMethod(AsSSortedList, "for a starred Green's class", [IsStarClass],
x -> AsSSortedList(CanonicalStarClass(x)));

# Equality of *-classes
InstallMethod(\=, "for starred Green's classes",
[IsStarClass, IsStarClass],
function(class1, class2)
  if ParentAttr(class1) <> ParentAttr(class2) then
    return false;
  fi;
  return Representative(class1) in class2;
end);

# Size of a starred Green's class
InstallMethod(Size, "for a starred Green's class", [IsStarClass],
class -> Size(Elements(class)));

# Membership test for a starred Green's class
InstallMethod(\in, "membership test of starred Green's class",
[IsObject, IsStarClass],
function(elm, class)
  if elm = Representative(class) then
     return true;
  fi;
  return elm in Elements(class);
end);

InstallMethod(EquivalenceRelationPartition, "for a starred Green's equivalence",
[IsEquivalenceRelation and IsStarRelation],
rel -> Filtered(Successors(rel), x -> not Length(x) <> 1));

# New methods required so that what is returned by this function
# is the appropriate type of starred Green's class.

InstallOtherMethod(EquivalenceClassOfElementNC,
"for a starred Green's relation",
[IsEquivalenceRelation and IsStarRelation, IsObject],
function(rel, rep)
  local new;

  new := Objectify(NewType(CollectionsFamily(FamilyObj(rep)),
                   IsEquivalenceClass and IsEquivalenceClassDefaultRep),
                   rec());

  SetEquivalenceClassRelation(new, rel);
  SetRepresentative(new, rep);
  SetParent(new, UnderlyingDomainOfBinaryRelation(rel));
  SetIsStarClass(new, true);

  if IsRStarRelation(rel) then
      SetIsRStarClass(new, true);
  elif IsLStarRelation(rel) then
      SetIsLStarClass(new, true);
  elif IsHStarRelation(rel) then
      SetIsHStarClass(new, true);
  elif IsDStarRelation(rel) then
      SetIsDStarClass(new, true);
  elif IsJStarRelation(rel) then
      SetIsJStarClass(new, true);
  fi;

  return new;
end);

InstallMethod(EquivalenceClasses, "for a starred Green's R - relation",
[IsEquivalenceRelation and IsRStarRelation], x -> RStarClasses(Source(x)));

InstallMethod(EquivalenceClasses, "for a starred Green's L-relation",
[IsEquivalenceRelation and IsLStarRelation], x -> LStarClasses(Source(x)));

InstallMethod(EquivalenceClasses, "for a starred Green's H - relation",
[IsEquivalenceRelation and IsHStarRelation], x -> HStarClasses(Source(x)));

InstallMethod(EquivalenceClasses, "for a starred Green's D - relation",
[IsEquivalenceRelation and IsDStarRelation], x -> DStarClasses(Source(x)));

InstallMethod(EquivalenceClasses, "for a starred Green's J-relation",
[IsEquivalenceRelation and IsJStarRelation], x -> JStarClasses(Source(x)));

# Return the XStarClass containing the smaller class

InstallOtherMethod(RStarClass, "for a starred Green's H-class",
[IsHStarClass], cl -> RStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(LStarClass, "for a starred Green's H-class",
[IsHStarClass], cl -> LStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(DStarClass, "for a starred Green's H-class",
[IsHStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(JStarClass, "for a starred Green's H-class",
[IsHStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(DStarClass, "for a starred Green's R-class",
[IsRStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(JStarClass, "for a starred Green's R-class",
[IsRStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(DStarClass, "for a starred Green's L-class",
[IsLStarClass], cl -> DStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(JStarClass, "for a starred Green's L-class",
[IsLStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl)));

InstallOtherMethod(JStarClass, "for a starred Green's D-class",
[IsDStarClass], cl -> JStarClass(ParentAttr(cl), Representative(cl)));

# Find all the classes of a particular type

InstallGlobalFunction(LStarPartitionByMT, function(table)
  local mt,         # mutable copy of multiplication table
        n,          # size of <mt>
        profiles,   # types of rows, sorted
        partition,  # partition of indices into R*-classes
        k,          # element counter
        pro,        # profile of current elements row
        pos;        # position of current profile

  # get a mutable copy of the multiplication table
  mt := MutableCopyMat(table);
  n := Length(mt);
  mt{[1 .. n]}[n + 1] := [1 .. n];

  # initialise sorted list of profiles ...
  profiles := EmptyPlist(n);
  # ... and partition into R*-classes
  partition := EmptyPlist(n);

  # loop over elements
  for k in [1 .. n] do
    pro := KernelOfTransformation(TransformationNC(mt[k]));
    pos := PositionSorted(profiles, pro);

    # either ...
    if IsBound(profiles[pos]) and profiles[pos] = pro then
        # add element to part with same profile ...
        Add(partition[pos], k);
    else
        # ... or start a new part
        Add(profiles, pro, pos);
        Add(partition, [k], pos);
    fi;
  od;

  return AsSSortedList(partition);
end);

InstallMethod(RStarClasses, "for a small semigroup", [IsSmallSemigroup],
function(semi)
  local partition,  # partition of indices into R*-classes
        classes,    # the actual classes
        part,       # one part of <partition>, used as loop counter
        rc;         # one R*-class

  # get partition of index set into R*-classes ...
  partition := LStarPartitionByMT(TransposedMat(MultiplicationTable(semi)));

  # ... and use as internal representation
  SetInternalRepStarRelation(RStarRelation(semi), partition);

  # create actual classes as GAP objects
  classes := EmptyPlist(Length(partition));

  for part in partition do
    rc := RStarClass(semi, Elements(semi)[part[1]]);
    Add(classes, rc);
    SetAsSSortedList(rc, Elements(semi){part});
    SetSize(rc, Size(part));
    SetCanonicalStarClass(rc, rc);
  od;

  return classes;
end);

InstallOtherMethod(RStarClasses, "for a starred Green's D-class",
[IsDStarClass], cl -> Filtered(RStarClasses(ParentAttr(cl)),
                               c -> Representative(c) in cl));

InstallOtherMethod(RStarClasses, "for a starred Green's J-class",
[IsJStarClass], cl -> Filtered(RStarClasses(ParentAttr(cl)),
                               c -> Representative(c) in cl));

InstallMethod(LStarClasses, "for a small semigroup", [IsSmallSemigroup],
function(semi)
  local partition,  # partition of indices into L*-classes
        classes,    # the actual classes
        part,       # one part of <partition>, used as loop counter
        lc;         # one L*-class

  # get partition of index set into L*-classes ...
  partition := LStarPartitionByMT(MultiplicationTable(semi));

  # ... and use as internal representation
  SetInternalRepStarRelation(LStarRelation(semi), partition);

  # create actual classes as GAP objects
  classes := EmptyPlist(Length(partition));

  for part in partition do
    lc := LStarClass(semi, Elements(semi)[part[1]]);
    Add(classes, lc);
    SetAsSSortedList(lc, Elements(semi){part});
    SetSize(lc, Size(part));
    SetCanonicalStarClass(lc, lc);
  od;

  return classes;
end);

InstallOtherMethod(LStarClasses, "for a starred Green's D-class",
[IsDStarClass], cl -> Filtered(LStarClasses(ParentAttr(cl)),
                               c -> Representative(c) in cl));

InstallOtherMethod(LStarClasses, "for a starred Green's J-class",
[IsJStarClass], cl -> Filtered(LStarClasses(ParentAttr(cl)),
                               c -> Representative(c) in cl));

# AD would it be better to use JoinEquivalenceRelations?
InstallMethod(DStarClasses, "for a small semigroup", [IsSmallSemigroup],
function(semi)
  local mt,         # multiplication table of <semi>
        left,       # partition of indices into L*-classes
        right,      # partition of indices into R*-classes
        lookupL,    # positions of parts in <left> containing each index
        lookupR,    # positions of parts in <right> containing each index
        partition,  # partition of indices into D*-classes
        classes,    # the actual classes
        part,       # one part of <partition>, used as loop counter
        dc;         # one D*-class

  mt := MultiplicationTable(semi);

  # get R- and L-classes
  LStarClasses(semi);
  RStarClasses(semi);
  left := InternalRepStarRelation(LStarRelation(semi));
  right := InternalRepStarRelation(RStarRelation(semi));

  lookupL := List([1 .. Size(mt)], k -> First(left, part -> k in part));
  lookupR := List([1 .. Size(mt)], k -> First(right, part -> k in part));

  while left <> right do
    left := Unique(List(right, part -> Union(List(part, k -> lookupL[k]))));
    right := Unique(List(left, part -> Union(List(part, k -> lookupR[k]))));
  od;

  partition := AsSSortedList(left);

  SetInternalRepStarRelation(DStarRelation(semi), partition);
  classes := EmptyPlist(Length(partition));

  for part in partition do
    dc := DStarClass(semi, Elements(semi)[part[1]]);
    Add(classes, dc);
    SetAsSSortedList(dc, Elements(semi){part});
    SetSize(dc, Size(part));
    SetCanonicalStarClass(dc, dc);
  od;

  return classes;
end);

InstallOtherMethod(DStarClasses, "for a starred Green's J-class",
[IsJStarClass], cl -> Filtered(DStarClasses(ParentAttr(cl)),
                               c -> Representative(c) in cl));

InstallMethod(JStarClasses, "for a small semigroup", [IsSmallSemigroup],
function(semi)
  local mt,         # multiplication table of <semi>
        n,          # size of <mt>
        jideals,    # Green's J*-ideals of all elements
        partition,  # partition of indices into J*-classes
        set,        # a subset of the indices to become a part of <partition>
        classes,    # list of Green's J*-classes
        rest,       # elements not yet sorted into classes
        elm,        # element for building next class
        part,       # one part of <partition>, used as loop counter
        jc,         # one J*-class
        # AD the ideal computation should certainly become a user function
        # AD but the necessary technicalities are unclear to me
        greensStarJIdealRaw;

  greensStarJIdealRaw := function(elm)
    local ideal,     # the Green's J*-ideal of <elm>
          new,       # auxiliary variable for construction of <ideal>
          trans,     # transposed of <mt>
          dclasses,  # internal representation of Green's D*-classes
          greensJIdeal;

    # AD this step is rather inefficient in its current form
    # AD it should be replaced by a call to an attribute
    greensJIdeal := function(a)
      local regid;  # the regular Greens J-ideal of <a>
      # {a} \cup aS
      regid := Union(mt[a], [a]);
      # {a} \cup aS \cup aS \cup SaS
      return Union(regid, Union(List(regid, x -> trans[x])));
    end;

    trans := TransposedMat(mt);
    DStarClasses(semi);
    dclasses := InternalRepStarRelation(DStarRelation(semi));
    dclasses := List([1 .. n], x -> First(dclasses, cl -> x in cl));

    new := [elm];

    repeat
      ideal := new;
      new := Union(List(ideal, greensJIdeal));
      new := Union(List(new, x -> dclasses[x]));
    until new = ideal;

    return ideal;
  end;

  mt := MultiplicationTable(semi);
  n := Size(mt);

  jideals := List([1 .. n], greensStarJIdealRaw);

  partition := EmptyPlist(Size(mt));
  rest := [1 .. Size(mt)];

  repeat
    # take one of the remaining elements
    elm := rest[1];

    # get remaining elements in the same class
    set := Filtered(Intersection(rest, jideals[elm]),
                    x -> elm in jideals[x]);

    # remember new class and prepare for next step
    Add(partition, set);
    rest := Difference(rest, set);
  until IsEmpty(rest);

  MakeImmutable(partition);
  SetIsSSortedList(partition, true);

  SetInternalRepStarRelation(JStarRelation(semi), partition);
  classes := EmptyPlist(Length(partition));

  for part in partition do
      jc := JStarClass(semi, Elements(semi)[part[1]]);
      Add(classes, jc);
      SetAsSSortedList(jc, Elements(semi){part});
      SetSize(jc, Size(part));
      SetCanonicalStarClass(jc, jc);
  od;

  SetJStarClasses(semi, classes);

  return classes;
end);

InstallMethod(HStarClasses, "for a small semigroup", [IsSmallSemigroup],
function(semi)
    local left,       # partition of indices into L*-classes
          lpart,      # one part of <left>
          right,      # partition of indices into R*-classes
          rpart,      # one part of <right>
          partition,  # partition of indices into D*-classes
          classes,    # the actual classes
          part,       # one part of <partition>, used as loop counter
          hc;         # one H*-class

    # get R- and L-classes
    LStarClasses(semi);
    RStarClasses(semi);

    left := InternalRepStarRelation(LStarRelation(semi));
    right := InternalRepStarRelation(RStarRelation(semi));

    partition := [];

    for lpart in left do
      for rpart in right do
        Add(partition, Intersection(lpart, rpart));
      od;
    od;

    partition := AsSSortedList(Filtered(partition, p -> not IsEmpty(p)));

    SetInternalRepStarRelation(HStarRelation(semi), partition);
    classes := EmptyPlist(Length(partition));

    for part in partition do
      hc := HStarClass(semi, Elements(semi)[part[1]]);
      Add(classes, hc);
      SetAsSSortedList(hc, Elements(semi){part});
      SetSize(hc, Size(part));
      SetCanonicalStarClass(hc, hc);
    od;
    SetHStarClasses(semi, classes);
    return classes;
end);

InstallOtherMethod(HStarClasses, "for a starred Green's class",
[IsStarClass], cl -> Filtered(HStarClasses(ParentAttr(cl)),
                              c -> Representative(c) in cl));

[ Dauer der Verarbeitung: 0.31 Sekunden  (vorverarbeitet)  ]