Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/gbnp/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 29.7.2024 mit Größe 31 kB image not shown  

SSL grobnerloops.gi   Sprache: unbekannt

 
######################### BEGIN COPYRIGHT MESSAGE #########################
# GBNP - computing Gröbner bases of noncommutative polynomials
# Copyright 2001-2010 by Arjeh M. Cohen, Dié A.H. Gijsbers, Jan Willem
# Knopper, Chris Krook. Address: Discrete Algebra and Geometry (DAM) group
# at the Department of Mathematics and Computer Science of Eindhoven
# University of Technology.
#
# For acknowledgements see the manual. The manual can be found in several
# formats in the doc subdirectory of the GBNP distribution. The
# acknowledgements formatted as text can be found in the file chap0.txt.
#
# GBNP is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by the
# Free Software Foundation (FSF); either version 2.1 of the License, or
# (at your option) any later version. For details, see the file 'LGPL' in
# the doc subdirectory of the GBNP distribution or see the FSF's own site:
https://www.gnu.org/licenses/lgpl.html
########################## END COPYRIGHT MESSAGE ##########################


#GBNP.SGrobnerLoops:=function(G,todo,funcs)
#GBNP.SGrobnerLoop:=function(G,todo)
#GBNP.GrobnerLoop:=function(G,todo)
#GBNP.SGrobnerTruncLoop:=function(G,todo,wtv,k)
#GBNP.GrobnerLoopAll:=function(G,todo,options)
#GBNP.SGrobnerTraceLoop:=function(G,todo)
#GBNP.ObsTall:=function(j,G,todo,OT,funcs)
#GBNP.StrongNormalFormTall:=function(f,G,GLOT,funcs)
#GBNP.StrongNormalForm2Tall:=function(f,G,G2,OT,funcs)
#GBNP.StrongNormalForm3Dall:=function(f,G,G2,OT,funcs,skip)
#GBNP.StrongNormalForm2TSPTS:=function(G,j,GLOT,prefix)
#GBNP.ReducePolTails:=function(G,todo,GLOT)
#GBNP.ReducePolTailsPTS:=function(G,todo,OT,funcs)
#GBNP.ReduceCancellation:=function(pol)
#GBNP.Find3Dnum:=function(l, skip)

############################
### GBNP.SGrobnerLoops
### - The loop in the SGrobner basis computation
###
###
### Assumptions:
### - G is a list of clean polynomials all of whose minimal S polynomials
###   have a rewritten form wrt G  lying in todo.
###   the arguments are preserved! So it is really a routine
###   acting on the lists G and todo
###
### Arguments:
### G           - list of non-commutative polynomials
### todo        - list of non-commutative polynomials
###
### observe:    - this loop may never end: the noncommutative GB is
###               not guaranteed to terminate: in general the word problem
###               is unsolvable.
### #GBNP.SGrobnerLoops  uses:#
### #GBNP.SGrobnerLoops is used in: GBNP.GrobnerLoop GBNP.GrobnerLoopAll GBNP.SGrobnerLoop GBNP.SGrobnerTruncLoop Grobner SGrobner#
###

GBNP.SGrobnerLoops := function(G,todo,funcs) local i,lG,count,ltspoly,spoly,sltspoly,spo,l,h,Gset,genlist,b,OT,todoheap,iterations;


    if not IsBound(funcs.pg) then
        funcs.pg:=GBNP.GetOptions().pg;
    else
        if (funcs.pg<>0) then
                GBNP.SetOption("pg",funcs.pg); # XXX check that funcs.pg is not
                                               # erroneously 0
        fi;
    fi;

    # if G is empty or one, no iterations are needed
    if (G=[]) or (Length(G)=1 and G[1][1]=[[]] and IsOne(G[1][2][1])) then
      return rec(G:=G, todo:=[], completed:=true, iterations:=0);
    fi;


    genlist:=[1..Maximum(Flat(List(G,x->x[1])))]; # largest generator used in G
    Gset:=List(LMonsNP(G),x->BlistList(genlist,Set(x)));
    OT:=rec();

    #if IsBound(funcs.GB) then
    #   OT.GBL:=GBNP.CreateOccurTreePTSLR(LMonsNP(funcs.GB),funcs.pg,true);
    #fi;
    OT.GL:=GBNP.CreateOccurTreePTSLR(LMonsNP(G),funcs.pg,true);
    OT.GR:=GBNP.CreateOccurTreePTSLR(LMonsNP(G),funcs.pg,false);

    OT.todoL:=GBNP.CreateOccurTreePTSLR(LMonsNP(todo),funcs.pg,true);
    lG:=Length(G);
    todoheap:=THeapOT(todo, OT.todoL);
    #Print("debug: start\n");
    #GBNP.THeapOTCheck(todoheap);
    #Print("debug: start 2\n");
    count:=[Length(todoheap)];
    iterations:=0;
    while not IsTHeapOTEmpty(todoheap) do
      iterations:=iterations+1;

# Fase IIIa, Take the first element 'spoly' of todo and add it to 'G'
# - Take the first element of the todo list and remove it from todo
# - Add this to the basis

      spoly:=HeapMin(todoheap);
      ltspoly := spoly[1][1];
      sltspoly:=BlistList(genlist,Set(ltspoly)); # jwk -set
      Info(InfoGBNP,3,"added Spolynomial is:\n", spoly);
      Add(G,spoly);
      Add(Gset,sltspoly);       # jwk - Gset/todoset
      Remove(todoheap,1);       # only remove after it is added to G
                # XXX this removing might be expensive for large todo lists,
                # it might be worthwhile to implement todo as a 3-tree

      lG:=lG+1;

      # update the tree
      GBNP.AddMonToTreePTSLR(ltspoly,-1,OT.GL,true);
      GBNP.AddMonToTreePTSLR(ltspoly,-1,OT.GR,false);
      #GBNP.RemoveMonFromTreePTSLR(ltspoly,1,OT.todoL,true);

# Fase IIIb, update todo

      GBNP.ObsTall(lG,G,todoheap,OT,funcs); # jwk - tree variant of GBNP.Obs, no sorting needed here

# Fase IIIc, reduce the list G with the new polynomial 'spoly'

      if not IsBound(funcs.SkipIIIc) then

        i:=1;
        l:=lG;
        while i < l do
          h := G[i];
              b:=IsSubsetBlist(Gset[i],sltspoly) and
                  GBNP.Occur(ltspoly,h[1][1]) > 0;
          if b=true then # -jwk check for set
              RemoveElmList(G,i);
              RemoveElmList(Gset,i);
              GBNP.RemoveMonFromTreePTSLR(h[1][1],i,OT.GL,true);
              GBNP.RemoveMonFromTreePTSLR(h[1][1],i,OT.GR,false);

              spo:=GBNP.StrongNormalForm2Tall(h,G,todoheap!.list,OT,funcs);
              # XXX uses todo XXX
              if spo = [[],[]] then
                  lG:=lG-1;
              else
                  Add(G,MkMonicNP(spo));
                  Add(Gset,BlistList(genlist,Set(spo[1][1])));
                  GBNP.AddMonToTreePTSLR(spo[1][1],-1,OT.GL,true);
                  GBNP.AddMonToTreePTSLR(spo[1][1],-1,OT.GR,false);

                  funcs.CentralT(lG,G,todoheap,OT,funcs); # - jwk use tree variant
                  GBNP.ObsTall(lG,G,todoheap,OT,funcs); # - jwk use tree variant, no sorting needed here
              fi;
              l:=l-1;
          else
              i:=i+1;
          fi;
        od;
      fi;

      Info(InfoGBNP,2,"length of G =",lG);

# Fase IIId, reducing todo with respect to 'spoly'

      l:=Length(todoheap);
      i:=1;
      while i <= l do
          h := todoheap[i];
          # b is true if h can be reduced
          # first check G
          b:= GBNP.OccurInLstT(h[1][1],OT.GL)[1] +
          # then check todo
              GBNP.Find3Dnum(
                  GBNP.LookUpOccurTreeAllLstPTSLR(h[1][1],OT.todoL,true), i
              )[1] > 0;
          if b=true then # -jwk check for set
              #Remove(todoheap,i);
              #GBNP.RemoveMonFromTreePTSLR(h[1][1],i,OT.todoL,true);
              spo:=GBNP.StrongNormalForm3Dall(h,G,todoheap,OT,funcs,i);
              if spo<>[[],[]] then
                  Replace(todoheap,i,MkMonicNP(spo));
                  # allowed because: replacing an element in the todo heap with
                  # a smaller element does not effect elements with a higher
                  # index (but may change parent-nodes of the element that was
                  # changed, which have a smaller index)

                  #GBNP.AddMonToTreePTSLR(spo[1][1],i,OT.todoL,true);
                  i:=i+1;
              else
                  l:=l-1;
                  Remove(todoheap,i);
              fi;
          else
              i:=i+1;
          fi;
      od;
      Info(InfoGBNP,2,"length of todo is ",l);
      Info(InfoGBNP,4,"elements are\n",todoheap!.list);
      Add(count,l);

      if (GBNP.cleancount > 0) and (Length(count) mod GBNP.cleancount = 0) then
        GBNP.cleanpolys:=true;
      fi;

      if IsBound(GBNP.cleanpolys) then
        Unbind(GBNP.cleanpolys);
        GBNP.ReducePolTailsPTS(G,todoheap,OT,funcs);
      fi;

      if IsBound(GBNP.GetOptions().CheckQA) then
        Info(InfoGBNP,1,"size QA (max ",GBNP.GetOptions().CheckQA,")",
                GBNP.NondivMonsPTSenum(LMonsNP(G),LMonsNP(todoheap),
                        GBNP.GetOptions().Alphabetsize,0,
                        GBNP.GetOptions().CheckQA
                )
        );
      fi;
      # sort here: possibly cheaper XXX

      if IsBound(funcs.maxiterations) then
        if iterations >= funcs.maxiterations then
          return rec(G:=G, todo:=todoheap!.list, completed:=false,
            iterations:=iterations
          );
        fi;
      fi;
    od;
    Info(InfoGBNP,2,"List of todo lengths is ",count);
    return rec(G:=G, todo:=[], completed:=true, iterations:=iterations);
end;


#########################
### GBNP.SGrobnerLoop ###
#########################
###
### Loop function for Strong Gröbner basis
### When the input (G,todo) is a partial Gröbner pair, the output will be a
### Gröbner basis.
###
### Arguments:
### - G     a basis of the ideal I
### - todo  a basic set of G belonging to I and in strong normal form wrt G
###
### Returns:
### - a strong Gröbnerbasis of I
###
### #GBNP.SGrobnerLoop uses: GBNP.SGrobnerLoops#
### #GBNP.SGrobnerLoop is used in:#
###

GBNP.SGrobnerLoop:=function(G,todo)
        GBNP.SGrobnerLoops(G,todo,GBNP.SGrobnerLoopRec);
end;

########################
### GBNP.GrobnerLoop ###
########################
###
### Loop function for Strong Gröbner basis
### When the input (G,todo) is a partial Gröbner pair, the output will be a
### Gröbner basis.
###
### Arguments:
### - G     a basis of the ideal I
### - todo  a basic set of G belonging to I and in strong normal form wrt G
###
### Returns:
###   a Gröbner basis of I
###
### #GBNP.GrobnerLoop uses: GBNP.SGrobnerLoops#
### #GBNP.GrobnerLoop is used in:#

GBNP.GrobnerLoop:=function(G,todo)
        GBNP.SGrobnerLoops(G,todo,GBNP.GrobnerLoopRec);
end;

##############################
### GBNP.SGrobnerTruncLoop ###
##############################
###
### Loop function for a truncated Gröbner basis
### When the input (G,todo) is a partial Gröbner pair, the output will be a
### truncated Gröbner basis, with respect to the list of weights wtv and the
### number of generators k.
###
### Arguments:
### - G     a basis of the ideal I
### - todo  a basic set of G belonging to I and in strong normal form wrt G
### - wtv   a list of weights
### - k     the number of generators
###
### Returns:
###   a Gröbner basis of I
###
### #GBNP.SGrobnerTruncLoop uses: GBNP.SGrobnerLoops#
### #GBNP.SGrobnerTruncLoop is used in: GBNP.SGrobnerTruncLevel#


GBNP.SGrobnerTruncLoop:=function(G,todo,wtv,k)
local r;
        r:=ShallowCopy(GBNP.SGrobnerTruncLoopRec);

        r.k:=k;
        r.wtv:=wtv;
        r.trunc:=true;

        GBNP.SGrobnerLoops(G,todo,r);
end;

# following function not used yet

###########################
### GBNP.GrobnerLoopAll ###
###########################
###
### Grobner loop entry based on options record
### When the input (G,todo) is a partial Gröbner pair, the output will be a
### Gröbner basis.
###
### *not used yet*
###
### Arguments:
### - G     a basis of the ideal I
### - todo  a basic set of G belonging to I and in strong normal form wrt G
### - options record used to choose the right variant
###
### Returns:
### - a strong Gröbnerbasis of I corresponding to the options chosen
###
### #GBNP.GrobnerLoopAll uses: GBNP.SGrobnerLoops#
### #GBNP.GrobnerLoopAll is used in:#

GBNP.GrobnerLoopAll:=function(G,todo,options)
local o,r;
        r:=ShallowCopy(GBNP.SGrobnerLoopRec);
        for o in options do
                if o.name="trunc" then
                        r.k             :=      o.k;
                        r.wtv           :=      o.wtv;
                        r.SkipIIIc      :=      true;
                        r.trunc         :=      true;
                elif o.name="strong" then
                        r.strong        :=      true;
                elif o.name="normal" then
                        r.strong        :=      false;
                elif o.name="trace" then
                        r.trace         :=      true;
                fi;
        od;
        GBNP.SGrobnerLoops(G,todo,r);
end;

# some records

GBNP.GrobnerLoopRec:=rec(
        strong          :=      false,
        CentralT        :=      GBNP.CentralT,
);
GBNP.SGrobnerLoopRec:=rec(
        strong          :=      true,
        CentralT        :=      GBNP.CentralT,
);
GBNP.SGrobnerTruncLoopRec:=rec(
        strong          :=      true,
        SkipIIIC        :=      true,
        CentralT        :=      GBNP.CentralT,
        trunc           :=      true
);
GBNP.SGrobnerLoopPTSRec:=rec(
        strong          :=      true,
        CentralT        :=      GBNP.CentralT,
        PTS             :=      true
);

##################
### GBNP.SGrobnerTraceLoop
### - Computing a grobner basis
### (loop of the algorithm).
###
###
### Arguments:
### G           - set of non-commutative polynomials
### todo        - list of non trivial S-polynomials.
###
### Returns:
### G           - non-commutative grobner basis
###
### #GBNP.SGrobnerTraceLoop uses: GBNP.CentralTrace GBNP.MkMonicNPTrace GBNP.ObsTrace GBNP.StrongNormalFormTrace2#
### #GBNP.SGrobnerTraceLoop is used in: SGrobnerTrace#
###

GBNP.SGrobnerTraceLoop:=function(G,todo) local i,j,count,ltspoly,spoly,spo,temp,lt;

    j:=Length(G);
    count:=[Length(todo)];
    while todo <> [] do

# Fase IIIa, Take the first element 'spoly' of todo and add it to 'G'
# - Take the first element of the todo list and remove it from todo
# - Add this to the basis

      temp:=StructuralCopy(todo[1]);
      todo:=todo{[2..Length(todo)]};
      ltspoly := temp.pol[1][1];

      Add(G,temp);
      j:=j+1;


# Fase IIIb, update todo

      GBNP.ObsTrace(j,G,todo);


# Fase IIIc, reduce the set G with the new polynomial 'term.pol'


      i:=1;
      lt:=j;
      while i < lt do
        if PositionSublist(G[i].pol[1][1],ltspoly) <> fail
        then
           spo:= StructuralCopy(G[i]);
               RemoveElmList(G,i);
               spo:=GBNP.StrongNormalFormTrace2(spo,G,todo);
               if spo.pol=[[],[]]
                   then
                     j:=j-1;
                   else
                     spo:=GBNP.MkMonicNPTrace(spo);
                     Add(G,StructuralCopy(spo));
                     GBNP.CentralTrace(j,G,todo);
                     GBNP.ObsTrace(j,G,todo);
             fi;
             lt:=lt-1;
                     else
         i:=i+1;
        fi;
      od;
      Info(InfoGBNP,2,"j =",j);


# Fase IIId, reducing todo with respect to 'ter,.pol'

      lt:=Length(todo);
      i:=1;
      while i <= lt do
        if PositionSublist(todo[i].pol[1][1],ltspoly) <> fail
           then
                spo:=StructuralCopy(todo[i]);
                RemoveElmList(todo,i);
                spo :=GBNP.StrongNormalFormTrace2(spo,G,todo);
               if spo.pol=[[],[]]
                   then
                        lt:=lt-1;
                   else
                        spo:=GBNP.MkMonicNPTrace(spo);
                        InsertElmList(todo,i,StructuralCopy(spo));
                        i:=i+1;
                fi;
           else
                i:=i+1;
        fi;
      od;
      Info(InfoGBNP,2,"Current number of elements in todo is ",lt);
      Add(count,lt);
    od;
    Info(InfoGBNP,1,"List of todo lengths is ",count);
end;;


##################
### GBNP.ObsTall
### - Finding all self, left and right obstructions of u, leading term of G[j],
### w.r.t. the list of leading terms of G.
### - uses lterm-sets
###
### Assumptions:
### - Central obstructions are already done, so only self, left and right.
###
### Arguments:
### j           - index of a non-commutative polynomial in G
### G           - list of non-commutative polynomials
### lst         - list of S-polynomials (todo)
###
### Returns:
### todo        - new list of S-polynomials. S-polynomials with G[j] added
###
### #GBNP.ObsTall uses: GBNP.AddMonToTreePTSLR GBNP.LeftObsT GBNP.RightObsT GBNP.SortParallelOT GBNP.Spoly GBNP.StrongNormalForm2Tall GBNP.WeightedDegreeMon LMonsNP MkMonicNP#
### #GBNP.ObsTall is used in: GBNP.AllObs GBNP.SGrobnerLoops#
###

GBNP.ObsTall:=function(j,G,todo,OT,funcs)
local R,sob,ob,temp,temp2,obs,spo,added;
   R:=LMonsNP(G);
   if IsBound(OT.pGL) then
        # generating all obstructions: use only a partial tree to generate
        # obstructions
        temp:=GBNP.LeftObsT(j,R,OT.pGL);
   else
        temp:=GBNP.LeftObsT(j,R,OT.GL);
   fi;
   if IsBound(OT.pGR) then
        # generating all obstructions: use only a partial tree to generate
        # obstructions
        temp2:=GBNP.RightObsT(j,R,OT.pGR);
   else
        temp2:=GBNP.RightObsT(j,R,OT.GR);
   fi;
        # self obstructions should be both a non-reducible left
        # obstruction and a non-reducible right obstruction. If either
        # is reducible it can be removed. The following code will only
        # leave one if both temp and temp2 contain a selfobstruction
   if temp.sobnr<>0 then
       RemoveElmList(temp.obs,temp.sobnr);
   elif temp2.sobnr<>0 then
       RemoveElmList(temp2.obs,temp2.sobnr);
   fi;
   obs:=Concatenation(temp.obs,temp2.obs);

   added:=0;
   Info(InfoGBNP,5,"ObsTall(",j,"): obs: ",obs);
   for ob in obs do
     if IsBound(funcs.trunc) then
         temp := GBNP.WeightedDegreeMon(ob[1],funcs.wtv);
         temp := temp + GBNP.WeightedDegreeMon(R[ob[2]],funcs.wtv);
         temp := temp + GBNP.WeightedDegreeMon(ob[3],funcs.wtv);
     fi;
     # temp:=GBNP.WeightedDegreeMon(Concatenation(ob[1],R[ob[2]],ob[3]),wtv);
     if (not IsBound(funcs.trunc)) or (temp=funcs.k) then
       spo:=GBNP.Spoly(ob,G);
       if spo <> [[],[]] then
                if IsTHeapOT(todo) then
                   spo:=GBNP.StrongNormalForm2Tall(spo,G,todo!.list,OT,funcs);
                else
                   spo:=GBNP.StrongNormalForm2Tall(spo,G,todo,OT,funcs);
                fi;
           if spo <> [[],[]] then
               Add(todo,MkMonicNP(spo));
               if not IsTHeapOT(todo) then
                   GBNP.AddMonToTreePTSLR(spo[1][1],-1,OT.todoL,true); # also add it to the tree for
               fi;
               added:=added+1;
           fi;
       fi;
     fi;
   od;
   if not IsTHeapOT(todo) then
        temp:=LMonsNP(todo);
        temp2:=StructuralCopy(temp);
        SortParallel(temp,todo,LtNP);
        GBNP.SortParallelOT(temp2,OT.todoL,LtNP);
   fi;
   Info(InfoGBNP,3,"ObsTall(",j,"): ",added,"/",Length(obs)," new obstructions added");
end;;

#################################
### GBNP.StrongNormalFormTall ###
#################################
###
###
###
### Arguments:
### - f         non commutative polynomial
### - G         a list of non-commutative polynomials
### - GLOT      an left occur tree of G
### - funcs     an info record
###
### Returns:
### pol         - strong normalform of f w.r.t. G
###
### #GBNP.StrongNormalFormTall uses: GBNP.CreateOccurTreePTSLR GBNP.StrongNormalForm2Tall#
### #GBNP.StrongNormalFormTall is used in: GBNP.AllObs GBNP.IsGrobnerBasisTest IsGrobnerPair MakeGrobnerPair#
###

GBNP.StrongNormalFormTall:=function(f,G,GLOT,funcs)

        if f=[[],[]] then return f;
        else
                return GBNP.StrongNormalForm2Tall(f,G,[],rec(GL:=GLOT,
                        todoL:=GBNP.CreateOccurTreePTSLR([],funcs.pg,true)),
                        funcs);
        fi;
end;


###################
### GBNP.StrongNormalForm2Tall
### - Computes the strong normal form of a non-commutative polynomial
### - occur trees
###
### Assumptions:
### -  monomials of each polynomial are ordered. (highest degree first)
### -  polynomials in G union G2 are monic and clean.
### -  polynomial f is clean.
### -  polynomial f is not empty (that is, f <> [[],[]]).
###
### Arguments:
### f           - a non-commutative polynomial
### G           - list of non-commutative polynomials
### G2          - list of non-commutative polynomials
### Gset        - list of the leading term-sets
### G2set       - list of the leading term-sets
###
### Returns:
### pol         - strong normalform of f w.r.t. G
###
### #GBNP.StrongNormalForm2Tall uses: AddNP BimulNP GBNP.OccurInLstT GBNP.ReduceCancellation#
### #GBNP.StrongNormalForm2Tall is used in: GBNP.CentralT GBNP.ObsTall GBNP.SGrobnerLoops GBNP.StrongNormalFormTall IsGrobnerPair MakeGrobnerPair#
###

GBNP.StrongNormalForm2Tall:=function(f,G,G2,OT,funcs)
    local g,h,i1,i2,j,l,dr,ga,tt,lth,iid;
    tt:=Runtime();
    h:=StructuralCopy(f);
    iid := 1;
    repeat # iid <= Length(h[i]) since h=f is nonempty
      lth:=h[1][iid];
      i1:=GBNP.OccurInLstT(lth,OT.GL);
      i2:=GBNP.OccurInLstT(lth,OT.todoL);
      while i1[1]+i2[1]>0 do
            if i1[1]>0 then
                g:=G[i1[1]];
                ga:=lth{[1..i1[2]-1]};
                dr:=lth{[i1[2]+Length(g[1][1])..Length(lth)]};
                h:=AddNP(h,BimulNP(ga,g,dr),One(g[2][1]),-h[2][iid]/g[2][1]);
                if h=[[],[]] then return(h);  fi;
                if iid <= Length(h[1]) then
                   lth := h[1][iid];
                   i1:=GBNP.OccurInLstT(lth,OT.GL);
                   i2:=GBNP.OccurInLstT(lth,OT.todoL);
                else
                   return(GBNP.ReduceCancellation(h));
                fi;
            elif i2[1]>0 then
                g:=G2[i2[1]];
                ga:=lth{[1..i2[2]-1]};
                dr:=lth{[i2[2]+Length(g[1][1])..Length(lth)]};
                h:=AddNP(h,BimulNP(ga,g,dr),One(g[2][1]),-h[2][iid]/g[2][1]);
                if h=[[],[]] then return(h);  fi;
                if iid <= Length(h[1]) then
                   lth := h[1][iid];
                   i1:=GBNP.OccurInLstT(lth,OT.GL);
                   i2:=GBNP.OccurInLstT(lth,OT.todoL);
                else
                   return(GBNP.ReduceCancellation(h));
                fi;
            fi;
       od;
       iid := iid+1;
    until not (IsBound(funcs.strong) and iid <= Length(h[1]));
    # while (IsBound(funcs.strong) and iid <= Length(h[1]));

    return(GBNP.ReduceCancellation(h));
end;;

###################
### GBNP.StrongNormalForm3DAll
### - Computes the strong normal form of a non-commutative polynomial
### - occur trees
###
### Assumptions:
### -  monomials of each polynomial are ordered. (highest degree first)
### -  polynomials in G union G2 are monic and clean.
### -  polynomial f is clean.
### -  polynomial f is not empty (that is, f <> [[],[]]).
###
### Arguments:
### f           - a non-commutative polynomial
### G           - list of non-commutative polynomials
### G2          - list of non-commutative polynomials
### OT          - record with occur trees
### j           - item of G2 not to skip
###
### Returns:
### pol         - strong normalform of f w.r.t. G
###
### #GBNP.StrongNormalForm2Tall uses: AddNP BimulNP GBNP.OccurInLstT GBNP.ReduceCancellation#
### #GBNP.StrongNormalForm2Tall is used in: GBNP.CentralT GBNP.ObsTall GBNP.SGrobnerLoops GBNP.StrongNormalFormTall IsGrobnerPair MakeGrobnerPair#
###

GBNP.StrongNormalForm3Dall:=function(f,G,G2,OT,funcs,skip)
    local g,h,i1,i2,j,l,dr,ga,tt,lth,iid;
    tt:=Runtime();
    h:=StructuralCopy(f);
    iid := 1;
    repeat # iid <= Length(h[i]) since h=f is nonempty
      lth:=h[1][iid];
      i1:=GBNP.OccurInLstT(lth,OT.GL);
      i2:=GBNP.LookUpOccurTreeAllLstPTSLR(lth,OT.todoL,true);
      i2:=GBNP.Find3Dnum(i2,skip);
      while i1[1]+i2[1]>0 do
            if i1[1]>0 then
                g:=G[i1[1]];
                ga:=lth{[1..i1[2]-1]};
                dr:=lth{[i1[2]+Length(g[1][1])..Length(lth)]};
                h:=AddNP(h,BimulNP(ga,g,dr),One(g[2][1]),-h[2][iid]/g[2][1]);
                if h=[[],[]] then return(h);  fi;
                if iid <= Length(h[1]) then
                   lth := h[1][iid];
                   i1:=GBNP.OccurInLstT(lth,OT.GL);
                   i2:=GBNP.LookUpOccurTreeAllLstPTSLR(lth,OT.todoL,true);
                   i2:=GBNP.Find3Dnum(i2,skip);
                else
                   return(GBNP.ReduceCancellation(h));
                fi;
            elif i2[1]>0 then
                g:=G2[i2[1]];
                ga:=lth{[1..i2[2]-1]};
                dr:=lth{[i2[2]+Length(g[1][1])..Length(lth)]};
                h:=AddNP(h,BimulNP(ga,g,dr),One(g[2][1]),-h[2][iid]/g[2][1]);
                if h=[[],[]] then return(h);  fi;
                if iid <= Length(h[1]) then
                   lth := h[1][iid];
                   i1:=GBNP.OccurInLstT(lth,OT.GL);
                   i2:=GBNP.LookUpOccurTreeAllLstPTSLR(lth,OT.todoL,true);
                   i2:=GBNP.Find3Dnum(i2,skip);
                else
                   return(GBNP.ReduceCancellation(h));
                fi;
            fi;
       od;
       iid := iid+1;
    until not (IsBound(funcs.strong) and iid <= Length(h[1]));
    # while (IsBound(funcs.strong) and iid <= Length(h[1]));

    return(GBNP.ReduceCancellation(h));
end;;

###################
### GBNP.StrongNormalForm2TSall
### - Computes the strong normal form of a non-commutative polynomial
### - occur trees
### - special case G[j] reduced by the rest
###
### Assumptions:
### -  monomials of each polynomial are ordered. (highest degree first)
### -  polynomials in G union G2 are monic and clean.
### -  polynomial f is clean.
### -  polynomial f is not empty (that is, f <> [[],[]]).
###
### Arguments:
### f           - a non-commutative polynomial
### G           - list of non-commutative polynomials
### G2          - list of non-commutative polynomials
### Gset        - list of the leading term-sets
### G2set       - list of the leading term-sets
###
### Returns:
### pol         - strong normalform of f w.r.t. G
###
### #GBNP.StrongNormalForm2TSPTS uses: AddNP BimulNP GBNP.LookUpOccurTreeAllLstPTSLR#
### #GBNP.StrongNormalForm2TSPTS is used in: GBNP.ReducePolTailsPTS#
###

GBNP.StrongNormalForm2TSPTS:=function(G,j,GLOT,prefix)
    local g,h,il,i1,l,dr,ga,lth,iid;

    h:=StructuralCopy(G[j]);
    iid := 1;
    while iid <= Length(h[1]) do
      lth:=h[1][iid];
      if prefix then
          il:=GBNP.LookUpOccurTreeAllLstPTSLRPos(lth,GLOT,true,1);
      else
          il:=GBNP.LookUpOccurTreeAllLstPTSLR(lth,GLOT,true);
      fi;
      il:=Filtered(il,x->x[1]<>j);
      while il<>[] do
           i1:=il[1];
           g:=G[i1[1]];
           ga:=lth{[1..i1[2]-1]};
           dr:=lth{[i1[2]+Length(g[1][1])..Length(lth)]};
           h:=AddNP(h,BimulNP(ga,g,dr),One(g[2][1]),-h[2][iid]/g[2][1]);
           if h=[[],[]] then return(h);  fi;
           if iid <= Length(h[1]) then
                lth := h[1][iid];
                if prefix then
                    il:=GBNP.LookUpOccurTreeAllLstPTSLRPos(lth,GLOT,true,1);
                else
                    il:=GBNP.LookUpOccurTreeAllLstPTSLR(lth,GLOT,true);
                fi;
                il:=Filtered(il,x->x[1]<>j);
           else
                return(h);
           fi;
       od;
       iid := iid+1;
    od;
    return(h);
end;;

###########################
### GBNP.ReducePolTails ###
###########################
###
###
###
### Arguments:
### - G
### - todo
### - OT
### - funcs
###
### Returns:
###
### #GBNP.ReducePolTails uses: GBNP.StrongNormalForm2TS#
### #GBNP.ReducePolTails is used in: SGrobner#
###

GBNP.ReducePolTails:=function(G,todo,GLOT)
local   i,
        newg,
        count,
        tt,
        OT2;

        tt:=Runtime();
        count:=0;

        for i in [1..Length(G)] do

#       directly assigning to G[i] is faster, but doesn't allow statistics
                newg:=GBNP.StrongNormalForm2TS(G,i,GLOT);
                #
                if (newg<>G[i]) then count:=count+1; fi;
                G[i]:=newg;
        od;

        Info(InfoGBNP,2,"G: Cleaning finished, ", count, " polynomials reduced");

        Info(InfoGBNPTime,2,"Time needed to clean G :", Runtime()-tt);
end;

##############################
### GBNP.ReducePolTailsPTS ###
##############################
###
###
###
### Arguments:
### - G
### - todo
### - OT
### - funcs
###
### Returns:
###
### #GBNP.ReducePolTailsPTS uses: GBNP.StrongNormalForm2TSPTS#
### #GBNP.ReducePolTailsPTS is used in: GBNP.SGrobnerLoops#
###

GBNP.ReducePolTailsPTS:=function(G,todo,OT,funcs)
local   i,
        newg,
        count,
        tt,
        OT2;

        tt:=Runtime();
        count:=0;

        for i in [1..Length(G)] do

#       directly assigning to G[i] is faster, but doesn't allow statistics
                newg:=GBNP.StrongNormalForm2TSPTS(G,i,OT.GL,
                                IsBound(funcs.PTS));
                #
                if (newg<>G[i]) then count:=count+1; fi;
                G[i]:=newg;
        od;

        Info(InfoGBNP,2,"G: Cleaning finished, ", count, " polynomials reduced");

        Info(InfoGBNPTime,2,"Time needed to clean G :", Runtime()-tt);
end;


###############################
### GBNP.ReduceCancellation ###
###############################
###
###
###
### Arguments:
### - pol
###
### #GBNP.ReduceCancellation uses: GBNP.GetOptions#
### #GBNP.ReduceCancellation is used in: GBNP.ReducePol2 GBNP.StrongNormalForm2Tall GBNP.StrongNormalForm3Dall#

GBNP.ReduceCancellation:=function(pol)
local   nummon, # the number of monomials in pol
        bound,  # boolean, true if all monomials are longer than 1
        same,   # boolean, true if all checked symbols are the same
        i,j,    # counters
        sym,    # symbol to check (generator that is first or last in the lt)
        lenmin, # minimum length (if 0 -> no further cancellation possible)
        n,      # alphabetsize how to get this ?
        pre,
        post,
        new;

        if not IsBound(GBNP.GetOptions().CancellativeMonoid) then
                return pol;
        fi;

        n := GBNP.GetOptions().Alphabetsize;

        nummon := Length(pol[1]);
        if nummon < 2 then
                return pol; # cancellation only if there are at least 2 words
        fi;

        # calculate min len
        lenmin:=Minimum(List(pol[1],x->Length(x)));

        same:=true;
        while lenmin>0 and same do
                sym:=pol[1][1][Length(pol[1][1])];
                if sym<0 then           # prefix generator (do not cancel now)
                        same:=false;    # XXX prefix not cancelled
                fi;
                i:=2;
                while i<=nummon and same do
                        same:=same and pol[1][i][Length(pol[1][i])]=sym;
                        i:=i+1;
                od;

                if same then
                        for i in [1..nummon] do
                                RemoveElmList(pol[1][i],Length(pol[1][i]));
                        od;
                        lenmin:=lenmin-1;
                fi;
        od;

        same:=true;
        while lenmin>0 and same=true do
                sym:=pol[1][1][1];
                if sym<0 then           # prefix generator (do not cancel now)
                        same:=false;    # XXX prefix not cancelled
                fi;
                i:=2;
                while i<=nummon and same do
                        same:=same and pol[1][i][1]=sym;
                        i:=i+1;
                od;
                if same then
                        for i in [1..nummon] do
                                RemoveElmList(pol[1][i],1);
                        od;
                        lenmin:=lenmin-1;
                fi;
        od;

        return pol;
end;

######################
### GBNP.Find3Dnum ###
######################
###
###
###
### Arguments:
### - l
### -  skip
###
### Returns:
###
### #GBNP.Find3Dnum uses:#
### #GBNP.Find3Dnum used in:#
###

GBNP.Find3Dnum:=function(l, skip)
local   i,
        ans;
                ans:=[0,0];
        for i in l do
                if i[1]<>skip then
                        if ans[1]=0 or ans[1]>l[1] then
                                ans:=i;
                        fi;
                fi;
        od;
        return ans;
end;

[ Verzeichnis aufwärts0.51unsichere Verbindung  Übersetzung europäischer Sprachen durch Browser  ]