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


Quelle  orders.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Isabel Araújo.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##


#############################################################################
##
#M  OrderingsFamily(<F>)
##
InstallMethod( OrderingsFamily,
  "for a family", true, [IsFamily], 0,
  function( fam)
    local ord_req, ord_imp;

    ord_req := IsOrdering;
    ord_imp := IsObject;
    return NewFamily( "OrderingsFamily(...)",ord_req,ord_imp);

end);


######################################################################
##
#M  ViewObj( <ord> )
##
InstallMethod( ViewObj,
  "for an ordering", true,
  [IsOrdering], 0,
  function(ord)
    Print("Ordering");
  end);


######################################################################
##
##  Creating orderings
##

######################################################################
##
#F  CreateOrderingByLtFunction( <fam>, <fun>, <list> )
##
##  creates an orderings for the elements of the family fam
##  with LessThan given by <fun>
##  and with the properties list in <list>
##
BindGlobal("CreateOrderingByLtFunction",
function( fam, fun, list)
    local ord,prop;

    if NumberArgumentsFunction(fun)<>2 then
      return Error("Function for orderings has to have two arguments");
    fi;

    ord := Objectify(
            NewType( OrderingsFamily( fam ),
            IsAttributeStoringRep),rec());

    SetFamilyForOrdering(ord, fam);
    SetLessThanFunction(ord, fun);

    # now set the properties in list to true
    for prop in list do
      Setter(prop)(ord,true);
    od;

    return ord;
end);


######################################################################
##
#F  CreateOrderingByLteqFunction( <fam>, <fun>, <list> )
##
##  creates an orderings for the elements of the family fam
##  with LessThanOrequal given by <fun>
##  and with the properties list in <list>
##
BindGlobal("CreateOrderingByLteqFunction",
function( fam, fun, list)
    local ord,prop;

    if NumberArgumentsFunction(fun)<>2 then
      return Error("Function for orderings has to have two arguments");
    fi;

    ord := Objectify(
            NewType( OrderingsFamily( fam ),
            IsAttributeStoringRep),rec());

    SetFamilyForOrdering(ord, fam);
    SetLessThanOrEqualFunction(ord, fun);

    # now set the properties in list to true
    for prop in list do
      Setter(prop)(ord,true);
    od;

    return ord;
end);


######################################################################
##
#M  OrderingByLessThanFunctionNC( <fam>, <fun> )
##
InstallMethod( OrderingByLessThanFunctionNC,
  "for a family and a function", true,
  [IsFamily, IsFunction], 0,
  function(fam, fun)
    return CreateOrderingByLtFunction(fam,fun,[]);
  end);



InstallOtherMethod( OrderingByLessThanFunctionNC,
  "for a family, a function, and a list of properties", true,
  [IsFamily,IsFunction,IsList], 0,
  function(fam,fun,list)
    return CreateOrderingByLtFunction( fam,fun,list );
  end);


######################################################################
##
#M  OrderingByLessThanOrEqualFunctionNC( <fam>, <fun> )
##
InstallMethod( OrderingByLessThanOrEqualFunctionNC,
  "for a family and a function", true,
  [IsFamily, IsFunction], 0,
  function(fam, fun)
    return CreateOrderingByLteqFunction(fam,fun,[]);
  end);


InstallOtherMethod( OrderingByLessThanOrEqualFunctionNC,
  "for a family, a function, and a list of properties", true,
  [IsFamily,IsFunction,IsList], 0,
  function(fam,fun,list)
    return CreateOrderingByLteqFunction( fam,fun,list );
  end);


#############################################################################
##
#A  LessThanOrEqualFunction( <ord> )
##
InstallMethod( LessThanOrEqualFunction,
  "for an ordering which has a LessThanFunction", true,
  [IsOrdering and HasLessThanFunction], 0,
  function( ord)
    local fun;

    fun := function(x,y)
      return x=y or LessThanFunction(ord)(x,y);
    end;

    return fun;
end);


#############################################################################
##
#A  LessThanFunction( <ord> )
##
InstallMethod( LessThanFunction,
  "for an ordering which has a LessThanOrEqualFunction", true,
  [IsOrdering and HasLessThanOrEqualFunction], 0,
  function( ord)
    local fun;

    fun := function(x,y)
      return x<>y and LessThanOrEqualFunction(ord)(x,y);
    end;

    return fun;
end);


#############################################################################
##
#A  IsLessThanUnder( <ord>, <obj1>, <obj2> )
##
InstallMethod( IsLessThanUnder,
  "for an ordering ", true,
  [IsOrdering, IsObject,IsObject], 0,
  function( ord, obj1, obj2 )
    local fun;

    if FamilyObj(obj1)<>FamilyObj(obj2) then
      Error("Can only compare objects belonging to the same family");
    fi;
    if FamilyObj(ord)<>OrderingsFamily(FamilyObj(obj1)) then
      Error(ord," and ",obj1,obj2," do not have compatible families");
    fi;
    fun := LessThanFunction(ord);
    return fun(obj1,obj2);

end);


#############################################################################
##
#A  IsLessThanOrEqualUnder( <ord>,<obj1>, <obj2> )
##
InstallMethod( IsLessThanOrEqualUnder,
  "for an ordering and two objects ", true,
  [IsOrdering,IsObject,IsObject], 0,
  function( ord, obj1, obj2 )
    local fun;

    fun := LessThanOrEqualFunction(ord);
    return fun(obj1,obj2);

  end);


#############################################################################
##
#A  IsIncomparableUnder( <ord>,<obj1>, <obj2> )
##
##  for an ordering <ord> on the elements of the family of <el1> and <el2>.
##  Returns true if $el1\neq el2$i and  `IsLessThanUnder'(<ord>,<el1>,<el2>),
##  `IsLessThanUnder'(<ord>,<el2>,<el1>) are both false.
##  Returns false otherwise.
##  Notice that if obj1=obj2 then they are comparable
##
InstallMethod( IsIncomparableUnder,
  "for an ordering", true,
  [IsOrdering,IsObject,IsObject], 0,
  function(ord,obj1,obj2)
    local lteqfun;

    if FamilyObj(obj1)<>FamilyObj(obj2) then
      Error("`obj1' and `obj2' must belong to same family");
    fi;
    if not (FamilyObj(ord)=OrderingsFamily(FamilyObj(obj1))) then
      Error("`ord' is not an ordering in `OrderingsFamily(obj1)'");
    fi;

    # if we know that the ordering is total
    # then any pair of elements is comparable
    if HasIsTotalOrdering(ord) and IsTotalOrdering(ord) then
      return false;
    fi;

    lteqfun := LessThanOrEqualFunction( ord );
    # now check that neither obj1 is less than or equal to obj2
    # nor obj2 is less than or equal to obj1
    # Note that if obj1=obj2 then they are comparable!
    if (not lteqfun(obj1,obj2)) and (not lteqfun(obj2,obj1)) then
      return true;
    fi;
    return false;

end);


######################################################################
##
##  Orderings on families of associative words
##

#############################################################################
##
#M  LexicographicOrdering( <fam> )
#M  LexicographicOrdering( <fam>, <alphabet> )
#M  LexicographicOrdering( <fam>, <gensord> )
#M  LexicographicOrdering( <f> )
#M  LexicographicOrdering( <f>, <alphabet> )
#M  LexicographicOrdering( <f>, <gensord> )
#B  LexicographicOrderingNC( <fam>, <alphabet> )
##
##  LexicographicOrderingNC is the function that actually does the work
##
BindGlobal("LexicographicOrderingNC",
function(fam,alphabet)
    local ltfun,          # the less than function
          ord;            # the ordering

    ltfun := function(w1,w2)
      local i,x,y;

      for i in [1..Minimum(Length(w1),Length(w2))] do
        x := Subword(w1,i,i);
        y := Subword(w2,i,i);
        if Position(alphabet,x)< Position(alphabet,y) then
          return true;
        elif Position(alphabet,y)<Position(alphabet,x) then
          return false;
        fi;
      od;
      # at this time the shortest one is a prefix of the other one
      # or they are equal
      return Length(w1)<Length(w2);
    end;

    ord := OrderingByLessThanFunctionNC(fam,ltfun,[IsTotalOrdering,
        IsOrderingOnFamilyOfAssocWords]);
    SetIsTranslationInvariantOrdering(ord, false);
    SetOrderingOnGenerators(ord,alphabet);

    return ord;
end);


InstallOtherMethod( LexicographicOrdering,
  "for a family of words of a free semigroup or free monoid",
  true,
  [IsFamily and IsAssocWordFamily], 0,
  function(fam)
    local gens;         # the generating set

  # first find out if fam is a family of free semigroup or monoid
  # because we need to get a list of generators (in the default order)
  if IsBound(fam!.freeSemigroup) then
    gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
  elif IsBound(fam!.freeMonoid) then
    gens := GeneratorsOfMonoid(fam!.freeMonoid);
  else
    TryNextMethod();
  fi;

  return LexicographicOrderingNC(fam,gens);

end);


InstallMethod( LexicographicOrdering,
  "for a family of words of a free semigroup or free monoid and a list of generators",
  true,
  [IsFamily and IsAssocWordFamily,IsList and IsAssocWordCollection], 0,
  function(fam,alphabet)
    local gens;

  # first find out if fam is a family of free semigroup or monoid
  # because we need to get a list of generators (in the default order)
  if IsBound(fam!.freeSemigroup) then
    gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
  elif IsBound(fam!.freeMonoid) then
    gens := GeneratorsOfMonoid(fam!.freeMonoid);
  else
    TryNextMethod();
  fi;

  # now check that the elements of alphabet lie in the right family
  if ElementsFamily(FamilyObj(alphabet))<>fam then
    Error("Elements of `alphabet' should be in family `fam'");
  fi;

  # alphabet has to be a list of size Length(gens)
  # and all gens have to appear in the alphabet
  if Length(alphabet)<>Length(gens) or Set(alphabet)<>gens then
    Error("The list `alphabet' does not contain all generators");
  fi;

  return LexicographicOrderingNC(fam,alphabet);

end);


InstallOtherMethod( LexicographicOrdering,
  "for a family of words of a free semigroup or free monoid and a list",
  true,
  [IsFamily and IsAssocWordFamily,IsList], 0,
  function(fam,orderofgens)
    local gens,           # list of generators
          alphabet,       # list of gens in the appropriate ordering
          n;              # the size of the generating set

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # orderofgens has to be a list of size Length(gens)
    # and all indexed of gens have to appear in the list
    n := Length(gens);
    if Length(orderofgens)<>n or Set(orderofgens)<>[1..n] then
      Error("`list' is not compatible with `fam'");
    fi;

    # we have to turn the list giving the order of gens
    # in a list of gens
    alphabet := List([1..Length(gens)],i->gens[orderofgens[i]]);

    return LexicographicOrderingNC(fam,alphabet);
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free semigroup",
  true,
  [IsFreeSemigroup], 0,
  function(f)
    return LexicographicOrderingNC(ElementsFamily(FamilyObj(f)),
                                   GeneratorsOfSemigroup(f));
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free monoid",
  true,
  [IsFreeMonoid], 0,
  function(f)
    return LexicographicOrderingNC(ElementsFamily(FamilyObj(f)),
                                   GeneratorsOfMonoid(f));
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free semigroup and a list of generators",
  IsElmsColls,
  [IsFreeSemigroup,IsList and IsAssocWordCollection], 0,
  function(f,alphabet)
    return LexicographicOrdering(ElementsFamily(FamilyObj(f)),alphabet);
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free monoid and a list of generators",
  IsElmsColls,
  [IsFreeMonoid,IsList and IsAssocWordCollection], 0,
  function(f,alphabet)
    return LexicographicOrdering(ElementsFamily(FamilyObj(f)),alphabet);
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free semigroup and a list",
  true,
  [IsFreeSemigroup,IsList], 0,
  function(f,gensord)
    return LexicographicOrdering(ElementsFamily(FamilyObj(f)),gensord);
end);


InstallOtherMethod( LexicographicOrdering,
  "for a free monoid and a list",
  true,
  [IsFreeMonoid,IsList], 0,
  function(f,gensord)
    return LexicographicOrdering(ElementsFamily(FamilyObj(f)),gensord);
end);


#############################################################################
##
#M  ShortLexOrdering( <fam> )
#M  ShortLexOrdering( <fam>, <alphabet> )
#M  ShortLexOrdering( <fam>, <gensorder> )
#M  ShortLexOrdering( <f> )
#M  ShortLexOrdering( <f>, <alphabet> )
#M  ShortLexOrdering( <f>, <gensorder> )
#B  ShortLexOrderingNC ( <fam>, <alphabet> )
##
##  We implement these for families of elements of free smg and monoids
##  In the first form returns the ShortLexOrdering for the elements of fam
##  with the generators of the freeSmg (or freeMonoid) in the default order.
##  In the second form returns the ShortLexOrdering for the elements of fam
##  with the generators of the freeSmg (or freeMonoid) in the following order:
##  gens[i]<gens[j] if and only if orderofgens[i]<orderofgens[j]
##
BindGlobal("ShortLexOrderingNC",
function(fam,alphabet)
local ltfun, ord;

  # the less than function
  ltfun := function(w1,w2)

    # if w1=w2 then w1 is certainly not less than w2
    if w1=w2 then
      return false;
    fi;

    if Length(w1)<Length(w2) then
      return true;
    elif Length(w1)=Length(w2) then
      return IsLessThanUnder(LexicographicOrdering(fam,alphabet),w1,w2);
    fi;
    return false;
  end;

  ord := OrderingByLessThanFunctionNC(fam,ltfun,[IsTotalOrdering,
            IsReductionOrdering, IsShortLexOrdering,
            IsOrderingOnFamilyOfAssocWords]);
  SetOrderingOnGenerators(ord,alphabet);

  alphabet:=MakeImmutable(List(alphabet,i->GeneratorSyllable(i,1)));
  ord!.alphnums:=alphabet;
  if IsSSortedList(alphabet) then
    SetLetterRepWordsLessFunc(ord,function(a,b)
      if Length(a)<Length(b) then
        return true;
      elif Length(a)>Length(b) then
        return false;
      else
        return a<b;
      fi;
    end);
  else
    ord!.alphpos:=MakeImmutable(List([1..Maximum(alphabet)],i->Position(alphabet,i)));
    SetLetterRepWordsLessFunc(ord,function(a,b)
      if Length(a)<Length(b) then
        return true;
      elif Length(a)>Length(b) then
        return false;
      else
        return List(a,i->SignInt(i)*ord!.alphpos[AbsInt(i)])<
               List(b,i->SignInt(i)*ord!.alphpos[AbsInt(i)]);
      fi;
    end);
  fi;

  return ord;

end);


InstallOtherMethod( ShortLexOrdering,
  "for a family of words of a free semigroup or free  monoid", true,
  [IsFamily and IsAssocWordFamily], 0,
  function(fam)
    local gens;

    # first find out if fam is a family of free semigroup or monoid
    # because we need to get a list of generators (in the default order)
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    return ShortLexOrderingNC(fam,gens);
end);


InstallMethod( ShortLexOrdering,
  "for a family of words of a free semigroup or free monoid and a list of generators",
  true,
  [IsFamily and IsAssocWordFamily,IsList and IsAssocWordCollection], 0,
  function(fam,alphabet)

    local x,            # loop variable
          gens,         # the generators of the semigroup or monoid
          ltfun,        # the less than function of the ordering being built,
          ord;          # the ordering

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # now check that the elements of alphabet lie in the right family
    if ElementsFamily(FamilyObj(alphabet))<>fam then
      Error("Elements of `alphabet' should be in family `fam'");
    fi;

    # alphabet has to be a list of size Length(gens)
    # and all gens have to appear in the alphabet
    if Length(alphabet)<>Length(gens) or Set(alphabet)<>gens then
      Error("`fam' and `alphabet' are not compatible");
    fi;

    # now build the ordering
    return ShortLexOrderingNC(fam,alphabet);

end);


InstallOtherMethod( ShortLexOrdering,
  "for a family of free words of a free semigroup or free  monoid and a list",
  true, [IsFamily and IsAssocWordFamily,IsList], 0,
  function(fam,orderofgens)

    local i,            # loop variable
          gens,         # the generators of the semigroup or monoid
          n,            # the length of the generators list
          alphabet;     # the gens in the desired order

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # orderofgens has to be a list of size Length(gens)
    # and all gens have to appear in the list
    n := Length(gens);
    if Length(orderofgens)<>n or Set(orderofgens)<>[1..n] then
      Error("`fam' and `orderofgens' are not compatible");
    fi;

    # we have to turn the list giving the order of gens
    # in a list of gens
    alphabet := List([1..Length(gens)],i->gens[orderofgens[i]]);

    return ShortLexOrderingNC(fam,alphabet);
end);


InstallOtherMethod( ShortLexOrdering,
  "for a free semigroup", true,
  [IsFreeSemigroup], 0,
  f -> ShortLexOrderingNC(ElementsFamily(FamilyObj(f)),
        GeneratorsOfSemigroup(f)));


InstallOtherMethod( ShortLexOrdering,
  "for a free monoid", true,
  [IsFreeMonoid], 0,
  f -> ShortLexOrderingNC(ElementsFamily(FamilyObj(f)),GeneratorsOfMonoid(f)));


InstallOtherMethod( ShortLexOrdering,
  "for a free semigroup and a list of generators in the required order",
  IsElmsColls,
  [IsFreeSemigroup, IsList and IsAssocWordCollection], 0,
  function(f,alphabet)
    return ShortLexOrdering( ElementsFamily(FamilyObj(f)),alphabet);
  end);


InstallOtherMethod( ShortLexOrdering,
  "for a free monoid and a list of generators in the required order ",
  IsElmsColls,
  [IsFreeMonoid,IsList and IsAssocWordCollection], 0,
  function(f,alphabet)
    return ShortLexOrdering( ElementsFamily(FamilyObj(f)),alphabet);
  end);


InstallOtherMethod( ShortLexOrdering,
  "for a free semigroup and a list", true,
  [IsFreeSemigroup, IsList], 0,
  function(f,gensorder)
    return ShortLexOrdering( ElementsFamily(FamilyObj(f)),gensorder);
  end);


InstallOtherMethod( ShortLexOrdering,
  "for a free monoid and a list", true,
  [IsFreeMonoid,IsList], 0,
  function(f,gensorder)
    return ShortLexOrdering( ElementsFamily(FamilyObj(f)),gensorder);
  end);


#############################################################################
##
#F  IsShortLexLessThanOrEqual( <u>, <v> )
##
##  for two associative words <u> and <v>.
##  It returns true if <u> is less than or equal to <v>, with
##  respect to the shortlex ordering.
##  (the shortlex ordering is the default one given by u<=v)
##  (we have this function here to assure compatibility with gap4.2).
##
InstallGlobalFunction( IsShortLexLessThanOrEqual,
function( u, v )
  local fam,ord;

  fam := FamilyObj(u);
  ord := ShortLexOrdering(fam);

  return IsLessThanOrEqualUnder(ord,u,v);
end);


#############################################################################
##
#M  WeightLexOrdering( <fam>,<alphabet>,<wt>)
#M  WeightLexOrdering( <fam>,<gensord>,<wt>)
#M  WeightLexOrdering( <f>,<wt>,<alphabet>)
#M  WeightLexOrdering( <f>,<wt>,<gensord>)
#B  WeightLexOrderingNC( <fam>,<alphabet>,<wt>)
##
BindGlobal("WeightLexOrderingNC",
function(fam,alphabet,wt)
  local wordwt,       # function that given a word returns its weight
        ltfun,        # the less than function
        auxalph,
        ord;          # the ordering

  #########################################################
  # this is a function that given a word returns its weight
  wordwt := function(w)
    local i, sum;
    sum := 0;
    for i in [1..Length(alphabet)] do
      sum := sum + ExponentSumWord(w,alphabet[i])*wt[i];
    od;
    return sum;
  end;

  # the less than function
  ltfun := function(w1,w2)
    local w1wt,w2wt;        # the weights of words w1 and w2, resp

    # if w1=w2 then w1 is certainly not less than w2
    if w1=w2 then
      return false;
    fi;

    # then if the sum of the weights of w1 is less than
    # the sum of the weight of w2 then returns true
    # so we calculate the weight of w1
    w1wt := wordwt(w1);
    w2wt := wordwt(w2);
    if w1wt<w2wt then
      return true;
    elif w1wt=w2wt then
      return IsLessThanUnder(LexicographicOrdering(fam,alphabet),w1,w2);
    fi;
    return false;
  end;

  ord := OrderingByLessThanFunctionNC(fam,ltfun,[IsTotalOrdering,
            IsReductionOrdering, IsWeightLexOrdering,
            IsOrderingOnFamilyOfAssocWords]);
  SetOrderingOnGenerators(ord,alphabet);
  SetWeightOfGenerators(ord,wt);

  auxalph := ShallowCopy(alphabet);
  auxalph := List(auxalph,i->GeneratorSyllable(i,1));
  ord!.alphnums:=auxalph;
  if IsSSortedList(auxalph) then
    SetLetterRepWordsLessFunc(ord,function(a,b)
      local wa,wb;
      wa:=Sum(a,i->wt[i]);
      wb:=Sum(b,i->wt[i]);
      if wa<wb then
        return true;
      elif wa>wb then
        return false;
      else
        return a<b;
      fi;
    end);
  else
    ord!.alphpos:=List([1..Maximum(auxalph)],i->Position(auxalph,i));
    SetLetterRepWordsLessFunc(ord,function(a,b)
      local wa,wb;
      wa:=Sum(a,i->wt[i]);
      wb:=Sum(b,i->wt[i]);
      if wa<wb then
        return true;
      elif wa>wb then
        return false;
      else
        return List(a,i->SignInt(i)*ord!.alphpos[AbsInt(i)])<
               List(b,i->SignInt(i)*ord!.alphpos[AbsInt(i)]);
      fi;
    end);
  fi;

  return ord;

end);


InstallMethod( WeightLexOrdering,
  "for a family of words of a free semigroup or free monoid, a list of generators and a list of weights",
  true,
  [IsFamily and IsAssocWordFamily,IsList and IsAssocWordCollection, IsList], 0,
  function(fam,alphabet,wt)

    local x,            # loop variable
          gens,         # the generators of the semigroup or monoid
          ltfun,        # the less than function of the ordering being built,
          w1wt,w2wt,    # the weights of w1 and w2, resp
          ord;          # the ordering

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # now check that the elements of alphabet lie in the right family
    if ElementsFamily(FamilyObj(alphabet))<>fam then
      Error("Elements of `alphabet' should be in family `fam'");
    fi;

    # alphabet and wt both have to be lists of size Length(gens)
    # and all gens have to appear in the alphabet
    if Length(alphabet)<>Length(gens) or Length(wt)<>Length(gens)
          or Set(alphabet)<> gens then
      Error("`alphabet' and `wt' are not compatible with `fam'");
    fi;

    return WeightLexOrderingNC(fam,alphabet,wt);
end);


InstallOtherMethod( WeightLexOrdering,
  "for a family of words of a free semigroup or free monoid, and two lists",
  true, [IsFamily and IsAssocWordFamily,IsList,IsList], 0,
  function(fam,orderofgens,wt)

  local gens,         # the generators of the semigroup or monoid
        alphabet;     # the gens in the desired order

  # first find out if fam is a family of free semigroup or monoid
  if IsBound(fam!.freeSemigroup) then
    gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
  elif IsBound(fam!.freeMonoid) then
    gens := GeneratorsOfMonoid(fam!.freeMonoid);
  else
    TryNextMethod();
  fi;

  # alphabet and wt both have to be lists of size Length(gens)
  # and all gens have to appear in the alphabet
  if Length(orderofgens)<>Length(gens) or Length(wt)<>Length(gens)
    or Set(orderofgens)<> [1..Length(gens)] then
    Error("`orderofgens' and `wt' are not compatible with `fam'");
  fi;

  # we have to turn the list giving the order of gens
  # in a list of gens
  alphabet := List([1..Length(gens)],i->gens[orderofgens[i]]);

  return WeightLexOrderingNC(fam,alphabet,wt);
end);


InstallOtherMethod( WeightLexOrdering,
  "for a free semigroup, a list of generators and a list of weights",
  true,
  [IsFreeSemigroup,IsList and IsAssocWordCollection,IsList], 0,
  function(f,alphabet,wt)
    return WeightLexOrdering( ElementsFamily(FamilyObj(f)),alphabet,wt);
  end);


InstallOtherMethod( WeightLexOrdering,
  "for a free monoid, a list of generators and a list of weights",
  true,
  [IsFreeMonoid,IsList and IsAssocWordCollection,IsList], 0,
  function(f,alphabet,wt)
    return WeightLexOrdering( ElementsFamily(FamilyObj(f)),alphabet,wt);
  end);


InstallOtherMethod( WeightLexOrdering,
  "for a free semigroup, a list giving ordering on generators and a list of weights",
  true,
  [IsFreeSemigroup,IsList,IsList], 0,
  function(f,orderofgens,wt)
    return WeightLexOrdering( ElementsFamily(FamilyObj(f)),orderofgens,wt);
  end);

InstallOtherMethod( WeightLexOrdering,
  "for a free monoid, a list giving ordering on generators and a list of weights",
  true,
  [IsFreeMonoid,IsList,IsList], 0,
  function(f,orderofgens,wt)
    return WeightLexOrdering( ElementsFamily(FamilyObj(f)),orderofgens,wt);
  end);


#############################################################################
##
#M  BasicWreathProductOrdering( <fam> )
#M  BasicWreathProductOrdering( <fam>, <alphabet>)
#M  BasicWreathProductOrdering( <fam>, <gensord>)
#M  BasicWreathProductOrdering( <f>)
#M  BasicWreathProductOrdering( <f>, <alphabet>)
#M  BasicWreathProductOrdering( <f>, <gensord>)
#B  BasicWreathProductOrderingNC( <fam>, <alphabet>)
##
##  We implement these for families of elements of free smg and monoids
##  In the first form returns the BasicWreathProductOrdering for the
##  elements of fam with the generators of the freeSmg (or freeMonoid)
##  in the default order.
##  In the second form returns the BasicWreathProductOrdering for the
##  elements of fam with the generators of the freeSmg (or freeMonoid)
##  in the following order:
##  gens[i]<gens[j] if and only if orderofgens[i]<orderofgens[j]
##
##  So with the given order on the generators
##  u<v if u'<v' where u=xu'y and v=xv'y
##  So, if u and v have no common prefix, u is less than v wrt this ordering if
##    (i) maxletter(v) > maxletter(u); or
##   (ii) maxletter(u) = maxletter(v) and
##        #maxletter(u) < #maxletter(v); or
##  (iii) maxletter(u) = maxletter(v) =b and
##        #maxletter(u) = #maxletter(v) and
##        if u = u1 * b * u2 * b ... b * uk
##           v = v1 * b * v2 * b ... b * vk
##        then u1<v1 in the basic wreath product ordering.
##
BindGlobal("BasicWreathProductOrderingNC",
function(fam,alphabet)
  local ltfun,            # the less than function
        oltfun,
        nltfun,
        alphpos,
        ord;              # the ordering

  nltfun := function(u,v)
    local l,eu,ev,mp,np,me,ne;

    eu:=ExtRepOfObj(u);
    ev:=ExtRepOfObj(v);
    if eu=ev then
      return false;
    fi;
    # find the longest common prefix
    l:=1;
    while l<=Length(eu) and l<=Length(ev) and eu[l]=ev[l] do
      l:=l+1;
    od;
    l:=l-1;

    if l<>0 or (l=0 and (IsEmpty(eu) or IsEmpty(ev))) then
      if IsEvenInt(l) then
        # disagree on generator or ran out
        # if u is a proper prefix of v (ie l=|u|) then u<v
        if Length(eu)=l then
          return true;
        # but if v is a proper prefix of u then u>v
        elif Length(ev)=l then
          return false;
        fi;
        eu:=eu{[l+1..Length(eu)]};
        ev:=ev{[l+1..Length(ev)]};
      elif SignInt(eu[l+1])=SignInt(ev[l+1]) then
        # disagree on exponent
        # if u is a proper prefix of v (ie l=|u|) then u<v
        if Length(eu)=l+1 and AbsInt(eu[l+1])<AbsInt(ev[l+1]) then
          return true;
        # but if v is a proper prefix of u then u>v
        elif Length(ev)=l+1 and AbsInt(eu[l+1])>AbsInt(ev[l+1]) then
          return false;
        fi;
        if AbsInt(eu[l+1])<AbsInt(ev[l+1]) then
          ev:=ev{[l..Length(ev)]};
          ev[2]:=ev[2]-eu[l+1];
          eu:=eu{[l+2..Length(eu)]};
        else
          eu:=eu{[l..Length(eu)]};
          eu[2]:=eu[2]-ev[l+1];
          ev:=ev{[l+2..Length(ev)]};
        fi;
      else
        eu:=eu{[l..Length(eu)]};
        ev:=ev{[l..Length(ev)]};
      fi;
    fi;
    # now eu and ev don't have a common prefix.

    #T the code now assumes that all exponents are positive. If we use free
    #T groups, this needs to be cleaned up
    mp:=Length(eu)-1;
    np:=Length(ev)-1;
    me:=eu[mp+1];
    ne:=ev[np+1];
    while mp>0 and np>0 do
      if ord!.alphpos[ev[np]]<ord!.alphpos[eu[mp]] then
        ne:=ne-1;
        if ne=0 then
          np:=np-2;
          if np>0 then
            ne:=ev[np+1];
          fi;
        fi;
      elif ord!.alphpos[eu[mp]]<ord!.alphpos[ev[np]] then
        me:=me-1;
        if me=0 then
          mp:=mp-2;
          if mp>0 then
            me:=eu[mp+1];
          fi;
        fi;
      else
        ne:=ne-1;
        if ne=0 then
          np:=np-2;
          if np>0 then
            ne:=ev[np+1];
          fi;
        fi;
        me:=me-1;
        if me=0 then
          mp:=mp-2;
          if mp>0 then
            me:=eu[mp+1];
          fi;
        fi;
      fi;
    od;

    return mp<=0 and np<>0;
  end;

  ########
  #
  # this is obsolete but for tests

  oltfun := function(u,v)
    local l,m,n,ltgens;

    # we start by building the function that gives the order on the alphabet
    ltgens := function(x,y)
      return Position(alphabet,x)< Position(alphabet,y);
    end;

    if u=v then
      return false;
    fi;

    l := LengthOfLongestCommonPrefixOfTwoAssocWords( u, v);
    if l<>0 then
      # if u is a proper prefix of v (ie l=|u|) then u<v
      # but if v is a proper prefix of u then u>v
      if l=Length(u) then
        return true;
      elif l=Length(v) then
        return false;
      fi;

      # at this stage none of the words is a proper prefix of the other one
      # so remove the common prefix from both words
      u := Subword( u, l+1, Length(u) );
      v := Subword( v, l+1, Length(v) );
    fi;

    m := Length( u );
    n := Length( v );

    # so now u and v have no common prefixes
    # (in particular they are not equal)

    while m>0 and n>0 do
      if ltgens(Subword( v, n, n),Subword( u, m, m)) then
        n := n - 1;
      elif ltgens(Subword( u, m, m),Subword( v, n, n)) then
        m := m - 1;
      else
        m := m - 1;
        n := n - 1;
      fi;
    od;

    return m =0 and n<>0;
  end;

  ltfun:=function(u,v)
  local x,y;
    x:=oltfun(u,v);
    y:=nltfun(u,v);
    if x=y then
      return x;
    else
      Error("disagree");
    fi;
  end;

  if AssertionLevel()=0 then
    ltfun:=nltfun;
  fi;


  ord := OrderingByLessThanFunctionNC(fam,ltfun,[IsTotalOrdering,
            IsBasicWreathProductOrdering,
            IsOrderingOnFamilyOfAssocWords, IsReductionOrdering]);
  SetOrderingOnGenerators(ord,alphabet);

  alphpos:=List(alphabet,i->GeneratorSyllable(i,1));
  ord!.alphpos:=List([1..Maximum(alphpos)],i->Position(alphpos,i));

  return ord;

end);


InstallOtherMethod(BasicWreathProductOrdering,
  "for a family of words of a free semigroup or free monoid and a list",
  true, [IsAssocWordFamily and IsFamily], 0,
  function(fam)
    local gens;       # the generators list

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    return BasicWreathProductOrderingNC(fam,gens);
end);


InstallMethod(BasicWreathProductOrdering,
  "for a family of words of a free semigroup or free monoid and a list of generators",
  true, [IsAssocWordFamily and IsFamily, IsList and IsAssocWordCollection], 0,
  function(fam,alphabet)
    local gens;       # the generators of the semigroup or monoid

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # alphabet has to be a list of size Length(gens)
    # all gens have to appear in the list
    if Length(alphabet)<>Length(gens) or Set(alphabet)<>gens then
      Error("`alphabet' is not compatible with `fam'");
    fi;

    return BasicWreathProductOrderingNC(fam,alphabet);

end);


InstallMethod(BasicWreathProductOrdering,
  "for a family of words of a free semigroup or free monoid and a list",
  true, [IsAssocWordFamily and IsFamily, IsList], 0,
  function(fam,orderofgens)
    local gens,       # the generators of the semigroup or monoid
          n,          # the length of the generators list
          alphabet;   # the generators in the appropriate order

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # orderofgens has to be a list of size Length(gens)
    # all gens have to appear in the list
    n := Length(gens);
    if Length(orderofgens)<>n or Set(orderofgens)<>[1..n] then
      Error("`orderofgens' is not compatible with `fam'");
    fi;

    # we have to turn the list giving the order of gens
    # in a list of gens
    alphabet := List([1..Length(gens)],i->gens[orderofgens[i]]);

    return BasicWreathProductOrderingNC(fam,alphabet);

end);


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free semigroup", true,
  [IsFreeSemigroup], 0,
  f-> BasicWreathProductOrderingNC(ElementsFamily(FamilyObj(f)),
          GeneratorsOfSemigroup(f)));


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free monoid", true,
  [IsFreeMonoid], 0,
  f-> BasicWreathProductOrderingNC(ElementsFamily(FamilyObj(f)),
          GeneratorsOfMonoid(f)));


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free semigroup and a list of generators", true,
  [IsFreeSemigroup,IsList and  IsAssocWordCollection], 0,
  function(f,alphabet)
    return BasicWreathProductOrdering(ElementsFamily(FamilyObj(f)),alphabet);
  end);


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free monoid and a list of generators", true,
  [IsFreeMonoid,IsList and IsAssocWordCollection], 0,
  function(f,alphabet)
    return BasicWreathProductOrdering(ElementsFamily(FamilyObj(f)),alphabet);
  end);


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free semigroup and a list", true,
  [IsFreeSemigroup,IsList], 0,
  function(f,gensorder)
    return BasicWreathProductOrdering(ElementsFamily(FamilyObj(f)),gensorder);
  end);


InstallOtherMethod(BasicWreathProductOrdering,
  "for a free monoid and a list", true,
  [IsFreeMonoid,IsList], 0,
  function(f,gensorder)
    return BasicWreathProductOrdering(ElementsFamily(FamilyObj(f)),gensorder);
  end);


#############################################################################
##
#F  IsBasicWreathLessThanOrEqual( <u>, <v> )
##
##  for two associative words <u> and <v>.
##  It returns true if <u> is less than or equal to <v>, with
##  respect to the basic wreath product ordering.
##  (we have this function here to assure compatibility with gap4.2).
##
InstallGlobalFunction( IsBasicWreathLessThanOrEqual,
function( u, v )
  local fam,ord;

  fam := FamilyObj(u);
  ord := BasicWreathProductOrdering(fam);

  return IsLessThanOrEqualUnder(ord,u,v);
end);


#############################################################################
##
#M  WreathProductOrdering( <fam>, <levels> )
#M  WreathProductOrdering( <fam>, <gensord>, <levels>)
#M  WreathProductOrdering( <f>, <levels>)
#M  WreathProductOrdering( <f>, <gensord>, <levels>)
##
##  We implement these for families of elements of free smg and monoids
##  In the first form returns the WreathProductOrdering for the
##  elements of fam with the generators of the freeSmg (or freeMonoid)
##  in the default order.
##  In the second form returns the WreathProductOrdering for the
##  elements of fam with the generators of the freeSmg (or freeMonoid)
##  in the following order:
##  gens[i]<gens[j] if and only if orderofgens[i]<orderofgens[j]
##
##  <levels> is a list of length equal to the number of generators,
##  specifying the levels of the generators IN THEIR NEW ORDERING,
##  That is, levels[i] is the level of the generator that comes i-th
##  in the new ordering.
##
##  So with the given order on the generators
##  u<v if u'<v' where u=xu'y and v=xv'y
##  So, if u and v have no common prefix, u is less than v wrt this ordering if
##    (i) u_max < v_max in the shortlex ordering, where u_max, v_max are
##        the words obtained from u, v by removing all letters that do not
##        the highest level, or
##   (ii) u_max = v_max and
##        if u = u1 * u_m1 * u2 * u_m2 ... b * u_mk
##           v = v1 * v_m1 * v2 * v_m2 ... b * v_mk
##           where u_mi, v_mi are the maximal subwords of u, v containing
##           only the letters of maximal weight
##           (so u_max = u_m1 * u_m2 * ... * u_mk = v_m1 * v_m2 * ... * v_mk),
##           then u1<v1 in the wreath product ordering.
##
InstallOtherMethod(WreathProductOrdering,
  "for a family of words of a free semigroup or free monoid and a list",
  true, [IsAssocWordFamily and IsFamily,IsList], 0,
  function(fam, levels)
    local gens;

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    return WreathProductOrdering(fam,[1..Length(gens)],levels);
end);

InstallMethod(WreathProductOrdering,
  "for a family of words of a free semigroup or free monoid and a list",
  true, [IsAssocWordFamily and IsFamily, IsList, IsList], 0,
  function(fam,orderofgens,levels)
    local i,  # loop variable
       gens,  # the generators of the semigroup or monoid
     ltgens,  # the function giving the order on the alphabet
      ltfun,  # the less than function
        ord;  # the ordering

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # orderofgens has to be a list of size Length(gens)
    if Length(orderofgens)<>Length(gens) then
      TryNextMethod();
    fi;
    # all gens have to appear in the list
    for i in [1..Length(orderofgens)] do
      if not i in orderofgens then
        TryNextMethod();
      fi;
    od;

  # now we build the less than function for the ordering
  ltfun := function(u,v)
    local l,  #length of common prefix of u,v
          m,  #current position in scan of u (from right)
          n,  #current position in scan of v (from right)
       ug, vg,  #Current generators of u, v
   ug_lev, vg_lev,  #levels of urrent generators of u, v
     sl_lev,  #level at which one of the words  u,v  is
        #smaller in the shortlex ordering
                     sl,  #sl=1 or 2 if u or v, resp., is
        #smaller in the shortlex ordering at level sl_lev.
        #note sl=0 <=> sl_lev=0.
          levgens;  #functions on generators

    # we start by building the function that gives the order on
    # the alphabet
    # we construct it from the list <orderofgens>
    ltgens := function(x,y)
      return Position(orderofgens,Position(gens,x))<
          Position(orderofgens,Position(gens,y));
    end;

    #and similarly for the level function on the alphabet
    levgens := function(x)
      return levels[Position(orderofgens,Position(gens,x))];
    end;

    if u=v then
      return false;
    fi;

    if Length(u)=0 then
      return true;
    fi;
    if Length(v)=0 then
      return false;
    fi;

    l := LengthOfLongestCommonPrefixOfTwoAssocWords( u, v);
    if l<>0 then
      # if u is a proper prefix of v (ie l=|u|) then u<v
      # but if v is a proper prefix of u then u>v
      if l=Length(u) then
        return true;
      elif l=Length(v) then
        return false;
      fi;

    # at this stage none of the words is a proper prefix of the
    # other one so remove the common prefix from both words
      u := Subword( u, l+1, Length(u) );
      v := Subword( v, l+1, Length(v) );
    fi;

    # so now u and v have no common prefixes
    # (in particular they are not equal)

    m := Length( u );
      n := Length( v );
    sl_lev := 0;
    sl := 0;

    #We now start scanning u,v from right to left.
    #sl_lev denotes the level of the block of generators
    #which is currently distinguishing between u,v.
    #sl = 1 or 2 if u or v is smaller, respectively, in this block.
    #Initially sl_lev=sl=0. This can also occur later if either
    # (i) we read two equal generators in u,v at a higher level
    #     than sl_lev. Then everything to the right of these
    #     equal generators becomes irrelevant.
    #(ii) we read a generator in u or v at a higher level than
    #     sl_lev that is not matched by a generator at the same
    #     level in the other word. We keep scanning backwards
    #     along the other word until we find a generator of the
    #     corresponding level or higher, but keep sl_lev=sl=0
    #     while we are doing this.
    while m>0 or n>0 do
                        #Print(m,n,sl,sl_lev,"\n");
      if m<>0 then
          ug := Subword(u,m,m);
          ug_lev := levgens(ug);
      fi;
      if n<>0 then
          vg := Subword(v,n,n);
          vg_lev := levgens(vg);
      fi;
        if m = 0 then
          #we have reached the beginning of u, but
          #u might be ahead in shortlex at sl_lev
            if  sl <> 2 or vg_lev >= sl_lev then
        #u is certainly smaller
        return true;
          fi;
          #u is ahead in shortlex at sl_lev, so keep
          #scanning v
          n := n-1;
        elif n = 0 then
          #we have reached the beginning of v, but
          #v might be ahead in shortlex at sl_lev
            if  sl <> 1 or ug_lev >= sl_lev then
        #v is certainly smaller
        return false;
          fi;
          #v is ahead in shortlex at sl_lev, so keep
          #scanning u.
          m := m-1;
      elif vg_lev < ug_lev and sl_lev <= ug_lev then
          #u is now at a higher level than v
          n := n - 1;
          if sl_lev < ug_lev then
        #we are in situation (ii) (see above)
            sl_lev := 0;
            sl := 0;
          fi;
      elif ug_lev < vg_lev and sl_lev <= vg_lev  then
          #v is now at a higher level than u
          m := m - 1;
          if sl_lev < vg_lev then
        #we are in situation (ii) (see above)
            sl_lev := 0;
            sl := 0;
          fi;
      elif ug_lev = vg_lev and sl_lev <= vg_lev  then
          #u and v are at same level so use shortlex
          if ltgens(ug,vg) then
        sl := 1;
            sl_lev := ug_lev;
          elif ltgens(vg,ug) then
        sl := 2;
            sl_lev := ug_lev;
          elif sl_lev < ug_lev then
              #u and v are equal at this higher level.
        #everything to the right of u,v is now
        #irrelevant we are in situation (i) above.
        sl := 0;
            sl_lev := 0;
          fi;
          m := m - 1;
          n := n - 1;
      else
          #ug and vg are both at a lower level than sl_lev,
          #so can be ignored.
          m := m-1;
          n := n-1;
      fi;
    od;

    #We have reached the ends of both words, so sl tells us
    #which is the smaller.
    if sl = 1 then
      return true;
    elif sl = 2 then
      return false;
    else
      Error("There is a bug in WreathProductOrdering!");
    fi;
  end;

    ord := OrderingByLessThanFunctionNC(fam,ltfun,[IsTotalOrdering,
              IsWreathProductOrdering,
      IsOrderingOnFamilyOfAssocWords, IsReductionOrdering]);
    SetOrderingOnGenerators(ord,orderofgens);
    SetLevelsOfGenerators(ord,List([1..Length(gens)],j->
        levels[Position(orderofgens,j)]) );

    return ord;

end);

InstallOtherMethod(WreathProductOrdering,
  "for a family of associative words, a list of generators and a list with the levels of the generators", true,
  [IsAssocWordFamily,IsList and IsAssocWordCollection,IsList], 0,
  function(fam,alphabet,levels)
    local gens,gensord,n;

    # first find out if fam is a family of free semigroup or monoid
    if IsBound(fam!.freeSemigroup) then
      gens := GeneratorsOfSemigroup(fam!.freeSemigroup);
    elif IsBound(fam!.freeMonoid) then
      gens := GeneratorsOfMonoid(fam!.freeMonoid);
    else
      TryNextMethod();
    fi;

    # we have to do some checking
    # alphabet has to be a list of size Length(gens)
    # all gens have to appear in the list
    n := Length(gens);
    if Length(alphabet)<>n or Set(alphabet)<>gens then
      Error("`alphabet' is not compatible with `fam'");
    fi;

    # we have to turn the `alphabet' to a list giving the order of gens
    gensord := List([1..Length(gens)],i-> Position(gens,alphabet[i]));

    return WreathProductOrdering(fam,gensord,levels);
  end);

InstallOtherMethod(WreathProductOrdering,
  "for a free monoid and a list", true,
  [IsFreeMonoid,IsList,IsList], 0,
  function(f,gensorder,levels)
    return WreathProductOrdering(ElementsFamily(FamilyObj(f)),gensorder,levels);
  end);

InstallOtherMethod(WreathProductOrdering,
  "for a free semigroup", true,
  [IsFreeSemigroup,IsList], 0,
  function(f,levels)
        return WreathProductOrdering(ElementsFamily(FamilyObj(f)),levels);
  end);

InstallOtherMethod(WreathProductOrdering,
  "for a free monoid", true,
  [IsFreeMonoid,IsList], 0,
  function(f,levels)
        return WreathProductOrdering(ElementsFamily(FamilyObj(f)),levels);
  end);

InstallOtherMethod(WreathProductOrdering,
  "for a free semigroup and a list", true,
  [IsFreeSemigroup,IsList,IsList], 0,
  function(f,gensorder,levels)
    return WreathProductOrdering(ElementsFamily(FamilyObj(f)),gensorder,levels);
  end);

InstallOtherMethod(WreathProductOrdering,
  "for a free monoid and a list", true,
  [IsFreeMonoid,IsList,IsList], 0,
  function(f,gensorder,levels)
    return WreathProductOrdering(ElementsFamily(FamilyObj(f)),gensorder,levels);
  end);

[ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


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