Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  sims1.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

###########################################################################
##
##  libsemigroups/sims1.gi
##  Copyright (C) 2022                                   James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

DeclareOperation("LibsemigroupsSims1",
                 [IsSemigroup, IsPosInt, IsList, IsString]);

InstallMethod(LibsemigroupsSims1,
[IsSemigroup, IsPosInt, IsList, IsString],
function(S, n, extra, kind)
  local P, rules, sims1, Q, pair, r;

  Assert(1,
         CanUseFroidurePin(S)
         or IsFpSemigroup(S)
         or IsFpMonoid(S)
         or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
         or (HasIsFreeMonoid(S) and IsFreeMonoid(S)));

  Assert(1, IsEmpty(extra) or IsMultiplicativeElementCollColl(extra));

  Assert(1, kind in ["left", "right"]);

  if IsFpSemigroup(S) then
    rules := List(RelationsOfFpSemigroup(S),
                  r -> List(r,
                            x -> SEMIGROUPS.ExtRepObjToWord(ExtRepOfObj(x))));
  elif IsFpMonoid(S) then
    rules := List(RelationsOfFpMonoid(S),
                  r -> List(r,
                            x -> SEMIGROUPS.ExtRepObjToWord(ExtRepOfObj(x))));
  elif (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
      or (HasIsFreeMonoid(S) and IsFreeMonoid(S)) then
    rules := [];
  else
    Assert(1, CanUseFroidurePin(S));
    rules := RulesOfSemigroup(S);
  fi;

  P := libsemigroups.Presentation.make();
  for r in rules do
    libsemigroups.presentation_add_rule(P, r[1] - 1, r[2] - 1);
  od;

  if not IsEmpty(rules) then
    libsemigroups.Presentation.alphabet_from_rules(P);
  elif (HasIsFreeMonoid(S) and IsFreeMonoid(S)) or IsFpMonoid(S) then
    libsemigroups.Presentation.set_alphabet(
      P, [0 .. Size(GeneratorsOfMonoid(S)) - 1]);
  elif (HasIsFreeSemigroup(S) and IsFreeSemigroup(S)) or IsFpSemigroup(S) then
    libsemigroups.Presentation.set_alphabet(
      P, [0 .. Size(GeneratorsOfSemigroup(S)) - 1]);
  fi;
  libsemigroups.Presentation.validate(P);
  # RulesOfSemigroup always returns the rules of an isomorphic fp semigroup
  libsemigroups.Presentation.contains_empty_word(
    P, IsFpMonoid(S) or (HasIsFreeMonoid(S) and IsFreeMonoid(S)));

  sims1 := libsemigroups.Sims1.make(kind);
  libsemigroups.Sims1.short_rules(sims1, P);

  if not IsEmpty(extra) then
    Q := libsemigroups.Presentation.make();
    libsemigroups.Presentation.contains_empty_word(Q, IsMonoid(S));
    libsemigroups.Presentation.set_alphabet(Q,
      libsemigroups.Presentation.alphabet(P));

    for pair in extra do
      libsemigroups.presentation_add_rule(
        Q,
        MinimalFactorization(S, pair[1]) - 1,
        MinimalFactorization(S, pair[2]) - 1);
    od;
    libsemigroups.Presentation.validate(Q);
    libsemigroups.Sims1.extra(sims1, Q);
  fi;
  if n > 64 and libsemigroups.hardware_concurrency() > 2 then
    libsemigroups.Sims1.number_of_threads(
      sims1, libsemigroups.hardware_concurrency() - 2);
  fi;
  return sims1;
end);

BindGlobal("_CheckExtraPairs", function(S, extra)
  local pair;
  for pair in extra do
    if not (IsList(pair) and Length(pair) = 2) then
      ErrorNoReturn("the 3rd argument (a list) must consist of ",
                    "lists of length 2");
    elif not pair[1] in S or not pair[2] in S then
      ErrorNoReturn("the 3rd argument (a list of length 2) must consist ",
                    "of pairs of elements of the 1st argument (a semigroup)");
    fi;
  od;
end);

InstallMethod(NumberOfRightCongruences, "for a semigroup", [IsSemigroup],
S -> NumberOfRightCongruences(S, Size(S), []));

InstallMethod(NumberOfLeftCongruences, "for a semigroup", [IsSemigroup],
S -> NumberOfLeftCongruences(S, Size(S), []));

InstallMethod(NumberOfRightCongruences,
"for a semigroup and positive integer",
[IsSemigroup, IsPosInt],
{S, n} -> NumberOfRightCongruences(S, n, []));

InstallMethod(NumberOfLeftCongruences,
"for a semigroup and positive integer",
[IsSemigroup, IsPosInt],
{S, n} -> NumberOfLeftCongruences(S, n, []));

InstallMethod(NumberOfRightCongruences,
"for a semigroup, pos. int., and list ",
[IsSemigroup, IsPosInt, IsList],
function(S, n, extra)
  local sims1;
  _CheckExtraPairs(S, extra);
  if HasRightCongruencesOfSemigroup(S) then
    return Number(RightCongruencesOfSemigroup(S),
                  x -> NrEquivalenceClasses(x) <= n
                       and ForAll(extra, y -> y in x));
  elif not (CanUseFroidurePin(S) or IsFpSemigroup(S) or IsFpMonoid(S)
      or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
      or (HasIsFreeMonoid(S) and IsFreeMonoid(S))) then
    TryNextMethod();
  fi;
  sims1 := LibsemigroupsSims1(S, n, extra, "right");
  return libsemigroups.Sims1.number_of_congruences(sims1, n);
end);

InstallMethod(NumberOfLeftCongruences,
"for a semigroup, pos. int., and list",
[IsSemigroup, IsPosInt, IsList],
function(S, n, extra)
  local sims1;
  _CheckExtraPairs(S, extra);
  if HasLeftCongruencesOfSemigroup(S) then
    return Number(LeftCongruencesOfSemigroup(S),
                  x -> NrEquivalenceClasses(x) <= n
                       and ForAll(extra, y -> y in x));
  elif not (CanUseFroidurePin(S) or IsFpSemigroup(S) or IsFpMonoid(S)
      or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
      or (HasIsFreeMonoid(S) and IsFreeMonoid(S))) then
    TryNextMethod();
  fi;

  sims1 := LibsemigroupsSims1(S, n, extra, "left");
  return libsemigroups.Sims1.number_of_congruences(sims1, n);
end);

InstallMethod(SmallerDegreeTransformationRepresentation,
"for semigroup with CanUseFroidurePin",
[IsSemigroup and CanUseFroidurePin],
function(S)
  local map1, map2;
  map1 := IsomorphismFpSemigroup(S);
  map2 := SmallerDegreeTransformationRepresentation(Range(map1));
  return CompositionMapping(map2, map1);
end);

InstallMethod(SmallerDegreeTransformationRepresentation,
"for an fp semigroup", [IsFpSemigroup],
function(S)
  local P, ro, map, max, D, deg, imgs, pts, r, j, i;

  if not IsFinite(S) then
    ErrorNoReturn("the argument (an fp semigroup) must be finite");
  fi;

  P := libsemigroups.Presentation.make();
  for r in RelationsOfFpSemigroup(S) do
    r := List(r, x -> SEMIGROUPS.ExtRepObjToWord(ExtRepOfObj(x)));
    libsemigroups.presentation_add_rule(P, r[1] - 1, r[2] - 1);
  od;

  libsemigroups.Presentation.alphabet_from_rules(P);
  libsemigroups.Presentation.contains_empty_word(P, true);
  libsemigroups.Presentation.validate(P);

  ro := libsemigroups.RepOrc.make();
  libsemigroups.RepOrc.short_rules(ro, P);
  libsemigroups.RepOrc.min_nodes(ro, 1);
  if HasIsomorphismTransformationSemigroup(S)
      or IsTransformationSemigroup(S) then
    map := IsomorphismTransformationSemigroup(S);
    max := DegreeOfTransformationSemigroup(Range(map)) - 1;
  else
    max := Size(S);
  fi;

  libsemigroups.RepOrc.max_nodes(ro, max);
  libsemigroups.RepOrc.target_size(ro, Size(S));
  if Size(S) > 64 and libsemigroups.hardware_concurrency() > 2 then
    libsemigroups.RepOrc.number_of_threads(
      ro, libsemigroups.hardware_concurrency() - 2);
  fi;

  D := libsemigroups.RepOrc.digraph(ro);
  deg := Length(D);

  if deg = 0 then
    # Should only occur if HasIsomorphismTransformationSemigroup since
    # otherwise we'll always find the right regular representation eventually.
    return IsomorphismTransformationSemigroup(S);
  fi;

  imgs := [];
  for j in [1 .. Length(GeneratorsOfSemigroup(S))] do
    pts := [1 .. deg];
    for i in pts do
      pts[i] := D[i][j];
    od;
    Add(imgs, TransformationNC(pts));
  od;
  return SemigroupIsomorphismByImagesNC(S,
                                        Semigroup(imgs),
                                        GeneratorsOfSemigroup(S),
                                        imgs);
end);

BindGlobal("NextIterator_Sims1", function(iter)
  local result;
  result := libsemigroups.Sims1Iterator.deref(iter!.it);
  libsemigroups.Sims1Iterator.increment(iter!.it);
  if IsEmpty(result) then
    return fail;
  fi;
  result := Filtered(result, x -> not IsEmpty(x));
  result := DigraphNC(result);
  SetFilterObj(result, IsWordGraph);
  return iter!.construct(result);
end);

InstallMethod(IteratorOfRightCongruences,
"for a semigroup, pos. int., list or coll.",
[IsSemigroup, IsPosInt, IsListOrCollection],
function(S, n, extra)
  local sims1, iter;
  _CheckExtraPairs(S, extra);
  if HasRightCongruencesOfSemigroup(S) then
    return IteratorFiniteList(Filtered(RightCongruencesOfSemigroup(S),
                    x -> NrEquivalenceClasses(x) <= n
                    and ForAll(extra, y -> y in x)));
  elif not (CanUseFroidurePin(S) or IsFpSemigroup(S) or IsFpMonoid(S)
      or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
      or (HasIsFreeMonoid(S) and IsFreeMonoid(S))) then
    TryNextMethod();
  fi;
  sims1 := LibsemigroupsSims1(S, n, extra, "right");

  iter := rec(it := libsemigroups.Sims1.cbegin(sims1, n),
              construct := x -> RightCongruenceByWordGraphNC(S, x));

  iter.NextIterator := NextIterator_Sims1;
  iter.ShallowCopy := x -> rec(it := libsemigroups.Sims1.cbegin(sims1, n),
                               construct :=
                                 x -> RightCongruenceByWordGraphNC(S, x));
  return IteratorByNextIterator(iter);
end);

InstallMethod(IteratorOfLeftCongruences,
"for CanUseFroidurePin, pos. int., list or coll.",
[IsSemigroup and CanUseFroidurePin, IsPosInt, IsListOrCollection],
function(S, n, extra)
  local sims1, iter;
  _CheckExtraPairs(S, extra);
  if HasLeftCongruencesOfSemigroup(S) then
    return IteratorFiniteList(Filtered(LeftCongruencesOfSemigroup(S),
                    x -> NrEquivalenceClasses(x) <= n
                    and ForAll(extra, y -> y in x)));
  elif not (CanUseFroidurePin(S) or IsFpSemigroup(S) or IsFpMonoid(S)
      or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S))
      or (HasIsFreeMonoid(S) and IsFreeMonoid(S))) then
  fi;

  sims1 := LibsemigroupsSims1(S, n, extra, "left");

  iter := rec(it := libsemigroups.Sims1.cbegin(sims1, n),
              construct := x -> LeftCongruenceByWordGraphNC(S, x));
  iter.NextIterator := NextIterator_Sims1;
  iter.ShallowCopy := x -> rec(it := libsemigroups.Sims1.cbegin(sims1, n),
                               construct :=
                                 x -> LeftCongruenceByWordGraphNC(S, x));
  return IteratorByNextIterator(iter);
end);

InstallMethod(IteratorOfRightCongruences,
"for a semigroup and pos. int.",
[IsSemigroup, IsPosInt],
{S, n} -> IteratorOfRightCongruences(S, n, []));

InstallMethod(IteratorOfLeftCongruences,
"for a semigroup and pos. int.",
[IsSemigroup, IsPosInt],
{S, n} -> IteratorOfLeftCongruences(S, n, []));

InstallMethod(IteratorOfRightCongruences, "for a semigroup",
[IsSemigroup], S -> IteratorOfRightCongruences(S, Size(S), []));

InstallMethod(IteratorOfLeftCongruences, "for a semigroup",
[IsSemigroup], S -> IteratorOfLeftCongruences(S, Size(S), []));

[ Dauer der Verarbeitung: 0.44 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge