#############################################################################
##
#A  genVsumproc          CHEVIE library          Meinolf Geck & Frank L"ubeck
##
#Y  Copyright 1992--1993,  Lehrstuhl D f"ur Mathematik,    RWTH Aachen,   and
#Y                         IWR   der   Universit"at    Heidelberg,   Germany.
##
####################################################################
##
## Umformung von  NENNER fuer Ausgabe:
##
verkleinere:=proc(sn)
  local a,b,erg,weg,c;
  erg:={};
  for a in sn do
    weg:=false;
    for b in (sn minus {a}) do
      if weg=false then
        if type(normal((a[2]*b[1])/(a[1]*b[2]),expanded),
                                       polynom(integer)) then
          weg:=true;
        fi;
      fi;
    od;
    if not weg then
      c:=normal(a[1]/a[2]);
      if not type(c,rational) then
        erg:={op(erg),a};
      elif type(c,integer) then
        erg:={op(erg),[c,1,``.c.`/1 is always integer !!!`]};
      fi;
    fi;
  od;
  erg;
end:  


####################################################################
##
## Diese Funktion soll in den Summationsprozeduren
## statt `subs` genommen
## werden. Es ist darauf zu achten, dass nur ganzzahlige Polynome 
## substituiert werden.
##
eesubs:=proc()
  local z, n, s, tt, a, lst, i;
  a:=nargs;
  s:=args[1..(a-1)];
  lst:={};
  for i to a-1 do
    lst:={op(lst),op(1,args[i])};
  od;
  s:={s};
  tt:=args[a];
  if has(tt,lst) then
    z:=subs(s,tt[1]);
    n:=subs(s,tt[2]);
    z:=simpscew(map(nfcew,z));
    n:=simpscew(map(nfcew,n));
    tt:=kuerzqscew([z,n]);
  fi;
  tt;
end:

####################################################################
##
## Linearkombination [a1,qscew1,a2,qscew2,...] bedeutet:
## a1*qscew1+a2*qscew2+...
##
linkomb:=proc()
  local erg, i;
  erg:=[[],[[1,0,1]]];
  for i to nargs/2 do
    erg:=addqscew(erg,smalqscew(args[2*i-1],args[2*i]));
  od;
  erg;
end:

####################################################################
##
## Hier ist die neue Summenfunktion, die in den Summationsprozeduren
## statt `sum` zu nehmen ist. 
## Wenn die Formel fuer die geometrische Reihe benutzt wird, 
## schreibt sie 
## zur Kontrolle in die Menge `NENNER` (globale Variable) ein Paar
## [f,g] von Polynomen. Die Umformung war genau dann falsch (!), wenn
## f ein ganzzahliges Vielfaches von g ist.
##
nesum:=proc(tt,rg)
  local sv, erg, bl, ugr, ogr, z, n, cew, zw, 
        tl, cl, co, k, ke, fs, s1;
  sv:=op(1,rg);
  ugr:=op(1,op(2,rg));
  ogr:=op(2,op(2,rg));
  # Wenn die Summe nicht bei 0 anfaengt, wird sie als Differenz
  # zweier Summen, die bei 0 anfangen, geschrieben:
  if ugr=1 then
    s1:=eesubs(sv=0,tt);
    erg:=nesum(tt,sv=0..ogr);
    RETURN(linkomb(1,erg,-1,s1));
  elif ugr>1 then
    s1:=nesum(tt,sv=0..(ugr-1));
    erg:=nesum(tt,sv=0..ogr);
    RETURN(linkomb(1,erg,-1,s1));
  fi;
  # Ab hier kann ugr=0 angenommen werden:
  bl:=expand(ogr+1);
  z:=tt[1];
  n:=tt[2];
  erg:=[[],[[1,0,1]]];
  for cew in z do
    zw:=cew[2];
    k:=cew[1];
    if has(zw,sv) then
      zw:=collect(zw,sv);
      cl:=coeff(zw,sv);
      co:=subs(sv=0,zw);
      ke:=nfcew([1,cl,cew[3]]);
      tl:=kuerzqscew([simpscew(
            [nfcew([k,expand(cl*(ogr+1)+co),cew[3]]),
            nfcew([-k,expand(co),cew[3]])]),
            malscew([ke,[-1,0,1]],n)]);
      if not (cew[3]=2 and cl=1) then
        fs:=expand(nfew(cl,cew[3]));
        NENNER:={op(NENNER),[sign(fs[1])*fs[1],fs[2]]};
      fi;
    else
      tl:=[[[expand(cew[1]*bl),cew[2],cew[3]]],n];
    fi;
    if tl[1]<>[] then
      erg:=addqscew(erg,tl);
    fi;
  od;
  erg;
end:

