Changes http://wiki.axiom-developer.org/Guess/diff
--

??changed:
-This package requires:
-\begin{axiom}
-)lib RINTERPA RINTERP PCDEN
-\end{axiom}
+This is the source from [mantepse.spad.pamphlet]
 

 \begin{spad}
++added:
+)abbrev domain UFPS UnivariateFormalPowerSeries
+UnivariateFormalPowerSeries(Coef: Ring) == 
+    UnivariateTaylorSeries(Coef, 'x, 0$Coef)
+
+)abbrev package UFPS1 UnivariateFormalPowerSeriesFunctions
+UnivariateFormalPowerSeriesFunctions(Coef: Ring): Exports == Implementation 
+  where
+
+    UFPS ==> UnivariateFormalPowerSeries Coef
+
+    Exports == with
+
+      hadamard: (UFPS, UFPS) -> UFPS
+
+    Implementation == add
+
+      hadamard(f, g) ==
+        series map(#1*#2, coefficients f, coefficients g)
+                  $StreamFunctions3(Coef, Coef, Coef) 
+
+)abbrev domain GOPT GuessOption
+++ Author: Martin Rubey
+++ Description: GuessOption is a domain whose elements are various options used
+++ by \spadtype{Guess}.
+GuessOption(): Exports == Implementation where 
+
+  Exports == SetCategory with
+
+    maxDerivative: Integer -> %
+      ++ maxDerivative(d) specifies the maximum derivative in an algebraic
+      ++ differential equation. maxDerivative(-1) specifies that the maximum
+      ++ derivative can be arbitrary. This option is expressed in the form
+      ++ \spad{maxDerivative == d}.
+
+    maxShift: Integer -> %
+      ++ maxShift(d) specifies the maximum shift in a recurrence
+      ++ equation. maxShift(-1) specifies that the maximum shift can be
+      ++ arbitrary. This option is expressed in the form \spad{maxShift == d}.
+  
+    maxPower: Integer -> %
+      ++ maxPower(d) specifies the maximum degree in an algebraic differential
+      ++ equation. For example, the degree of (f'')^3 f' is 4. maxPower(-1)
+      ++ specifies that the maximum exponent can be arbitrary. This option is
+      ++ expressed in the form \spad{maxPower == d}.
+
+    homogeneous: Boolean -> %
+      ++ homogeneous(d) specifies whether we allow only homogeneous algebraic
+      ++ differential equations. This option is expressed in the form
+      ++ \spad{homogeneous == d}.
+
+    maxLevel: Integer -> %
+      ++ maxLevel(d) specifies the maximum number of recursion levels operators
+      ++ guessProduct and guessSum will be applied.  maxLevel(-1) specifies
+      ++ that all levels are tried. This option is expressed in the form
+      ++ \spad{maxLevel == d}.
+
+    maxDegree: Integer -> %
+      ++ maxDegree(d) specifies the maximum degree of the coefficient
+      ++ polynomial in an algebraic differential equation or a recursion with
+      ++ polynomial coefficients.  maxDegree(-1) specifies that the maximum
+      ++ degree can be arbitrary. This option is expressed in the form
+      ++ \spad{maxDegree == d}.
+
+    allDegrees: Boolean -> %
+      ++ allDegrees(d) specifies whether all possibilities of the degree vector
+      ++ - taking into account maxDegree - should be tried. This is mainly
+      ++ interesting for rational interpolation. This option is expressed in
+      ++ the form \spad{allDegrees == d}.
+
+    safety: NonNegativeInteger -> %
+      ++ safety(d) specifies the number of values reserved for testing any
+      ++ solutions found. This option is expressed in the form \spad{safety ==
+      ++ d}.
+
+    one: Boolean -> %
+      ++ one(d) specifies whether we are happy with one solution. This option
+      ++ is expressed in the form \spad{one == d}.
+
+    debug: Boolean -> %
+      ++ debug(d) specifies whether we want additional output on the
+      ++ progress. This option is expressed in the form \spad{debug == d}.
+
+    functionName: Symbol -> %
+      ++ functionName(d) specifies the name of the function given by the
+      ++ algebraic differential equation or recurrence. This option is
+      ++ expressed in the form \spad{functionName == d}.
+
+    variableName: Symbol -> %
+      ++ variableName(d) specifies the variable used in by the algebraic
+      ++ differential equation. This option is expressed in the form
+      ++ \spad{variableName == d}.
+
+    indexName: Symbol -> %
+      ++ indexName(d) specifies the index variable used for the formulas. This
+      ++ option is expressed in the form \spad{indexName == d}.
+
+    displayAsGF: Boolean -> %
+      ++ displayAsGF(d) specifies whether the result is a generating function
+      ++ or a recurrence. This option should not be set by the user, but rather
+      ++ by the HP-specification.
+
+    option : (List %, Symbol) -> Union(Any, "failed")
+      ++ option() is not to be used at the top level; 
+      ++ option determines internally which drawing options are indicated in 
+      ++ a draw command.
+
+    option?: (List %, Symbol) -> Boolean
+      ++ option?() is not to be used at the top level;
+      ++ option? internally returns true for drawing options which are 
+      ++ indicated in a draw command, or false for those which are not.
+
+    checkOptions: List % -> Void
+      ++ checkOptions checks whether an option is given twice
+  
+  Implementation ==> add
+    import AnyFunctions1(Boolean)
+    import AnyFunctions1(Symbol)
+    import AnyFunctions1(Integer)
+    import AnyFunctions1(NonNegativeInteger)
+
+    Rep := Record(keyword: Symbol, value: Any)
+  
+    maxLevel d      == ["maxLevel"::Symbol,      d::Any]
+    maxDerivative d == ["maxDerivative"::Symbol, d::Any]
+    maxShift d      == maxDerivative d
+    maxDegree d     == ["maxDegree"::Symbol,     d::Any]
+    allDegrees d    == ["allDegrees"::Symbol,    d::Any]
+    maxPower d      == ["maxPower"::Symbol,      d::Any]
+    safety d        == ["safety"::Symbol,        d::Any]
+    homogeneous d   == ["homogeneous"::Symbol,   d::Any]
+    debug d         == ["debug"::Symbol,         d::Any]
+    one d           == ["one"::Symbol,           d::Any]
+    functionName d  == ["functionName"::Symbol,  d::Any]
+    variableName d  == ["variableName"::Symbol,  d::Any]
+    indexName d     == ["indexName"::Symbol,     d::Any]
+    displayAsGF d   == ["displayAsGF"::Symbol,   d::Any]
+
+    coerce(x:%):OutputForm == x.keyword::OutputForm = x.value::OutputForm
+    x:% = y:%              == x.keyword = y.keyword and x.value = y.value
+
+    option?(l, s) ==
+      for x in l repeat
+        x.keyword = s => return true
+      false
+
+    option(l, s) ==
+      for x in l repeat
+        x.keyword = s => return(x.value)
+      "failed"
+
+    checkOptions l ==
+      if not empty? l then
+        if find((first l).keyword = #1.keyword, rest l) case "failed"
+        then checkOptions rest l
+        else error "GuessOption: Option specified twice"
+
+)abbrev package GOPT0 GuessOptionFunctions0
+++ Author: Martin Rubey 
+++ Description: GuessOptionFunctions0 provides operations that extract the
+++ values of options for \spadtype{Guess}.
+GuessOptionFunctions0(): Exports == Implementation where 
+
+  LGOPT ==> List GuessOption
+
+  Exports == SetCategory with
+
+    maxLevel: LGOPT -> Integer
+      ++ maxLevel returns the specified maxLevel or -1 as default.
+
+    maxPower: LGOPT -> Integer
+      ++ maxPower returns the specified maxPower or -1 as default.
+
+    maxDerivative: LGOPT -> Integer
+      ++ maxDerivative returns the specified maxDerivative or -1 as default.
+
+    maxShift: LGOPT -> Integer
+      ++ maxShift returns the specified maxShift or -1 as default.
+  
+    maxDegree: LGOPT -> Integer
+      ++ maxDegree returns the specified maxDegree or -1 as default.
+
+    allDegrees: LGOPT -> Boolean
+      ++ allDegrees returns whether all possibilities of the degree vector
+      ++ should be tried, the default being false.
+
+    safety: LGOPT -> NonNegativeInteger
+      ++ safety returns the specified safety or 1 as default.
+
+    one: LGOPT -> Boolean
+      ++ one returns whether we need only one solution, default being true.
+
+    homogeneous: LGOPT -> Boolean
+      ++ homogeneous returns whether we allow only homogeneous algebraic
+      ++ differential equations, default being false
+
+    functionName: LGOPT -> Symbol
+      ++ functionName returns the name of the function given by the algebraic
+      ++ differential equation, default being f
+
+[98 more lines...]
 )abbrev package GUESS Guess

??changed:
 )abbrev package GUESS Guess
-++ Description:
-++ This package implements guessing of sequences
+++ Author: Martin Rubey
+++ Description: This package implements guessing of sequences. Packages for the
+++ most common cases are provided as \spadtype{GuessInteger},
+++ \spadtype{GuessPolynomial}, etc.
 Guess(F, S, EXPRR, R, retract, coerce): Exports == Implementation where

??changed:
 
--- in guessExpRat mchte ich die Wurzeln von Polynomen ber F bestimmen. Wenn F
--- ein Quotientenkrper ist, dann kann ich den Nenner loswerden.
--- F wre dann also QFCAT S
+-- in guessExpRat möchte ich die Wurzeln von Polynomen über F bestimmen. Wenn F
+-- ein Quotientenkörper ist, dann kann ich den Nenner loswerden.
+-- F wäre dann also QFCAT S
 

??changed:
 -- die Ergebnisse werden aber in EXPRR dargestellt
-    EXPRR: Join(ExpressionSpace, IntegralDomain, 
+--    EXPRR: Join(ExpressionSpace, IntegralDomain,
+    EXPRR: Join(FunctionSpace Integer, IntegralDomain,
                 RetractableTo R, RetractableTo Symbol, 

??changed:
                 RetractableTo R, RetractableTo Symbol, 
-                RetractableTo Integer, CombinatorialOpsCategory) with
+                RetractableTo Integer, CombinatorialOpsCategory,
+                PartialDifferentialRing Symbol) with
               _* : (%,%) -> %

               denominator : % -> %
++added:
+              ground? : % -> Boolean
 

??changed:
 -- verwenden
--- EXPRR existiert, falls irgendwann einmal EXPR PF 5 untersttzt wird.
-
-
--- das folgende mchte ich eigentlich loswerden.
+-- EXPRR existiert, falls irgendwann einmal EXPR PF 5 unterstützt wird.
+
+
+-- das folgende möchte ich eigentlich loswerden.
   

 
++added:
+    LGOPT ==> List GuessOption
+    GOPT0 ==> GuessOptionFunctions0
+
     NNI ==> NonNegativeInteger

??changed:
     EXPRI ==> Expression Integer
-    GUESSRESULT ==> List Record(function: EXPRR, order: PI)
-    GUESSER ==> (Symbol, List F, BASIS) -> GUESSRESULT
-    BASIS ==> EXPRI -> EXPRR                 -- zB.: i+->q^i
--- brauche hier EXPRI, weil das Ergebnis ja die allgemeine Form enthlt
+    GUESSRESULT ==> List Record(function: EXPRR, order: NNI)
+
+    UFPSF ==> UnivariateFormalPowerSeries F
+    UFPS1 ==> UnivariateFormalPowerSeriesFunctions
+
+    UFPSS ==> UnivariateFormalPowerSeries S
+
+    SUP ==> SparseUnivariatePolynomial
+
+    UFPSSUPF ==> UnivariateFormalPowerSeries SUP F
+
+    FFFG ==> FractionFreeFastGaussian
+    FFFGF ==> FractionFreeFastGaussianFractions
+
+-- CoeffAction
+    DIFFSPECA ==> (NNI, NNI, SUP S) -> S
+
+    DIFFSPECAF ==> (NNI, NNI, UFPSSUPF) -> SUP F
+
+    DIFFSPECAX ==> (NNI, Symbol, EXPRR) -> EXPRR
+
+-- the diagonal of the C-matrix
+    DIFFSPECC ==> NNI -> List S
+
+
+    HPSPEC ==> Record(guessStream:  UFPSF -> Stream UFPSF,
+                      degreeStream: Stream NNI,
+                      testStream:   UFPSSUPF -> Stream UFPSSUPF, 
+                      exprStream:   (EXPRR, Symbol) -> Stream EXPRR,
+                      A:  DIFFSPECA,
+                      AF: DIFFSPECAF,
+                      AX: DIFFSPECAX,
+                      C:  DIFFSPECC)
+
+-- note that empty?(guessStream.o) has to return always. In other words, if the
+-- stream is finite, empty? should recognize it.
+
+    DIFFSPECN ==> EXPRR -> EXPRR             -- eg.: i+->q^i
+
+    GUESSER ==> (List F, LGOPT) -> GUESSRESULT
+
+    FSUPS ==> Fraction SUP S
+    FSUPF ==> Fraction SUP F
+
+    V ==> OrderedVariableList(['a1, 'A])
+    POLYF ==> SparseMultivariatePolynomial(F, V)
+    FPOLYF ==> Fraction POLYF
+    FSUPFPOLYF ==> Fraction SUP FPOLYF
+    POLYS ==> SparseMultivariatePolynomial(S, V)
+    FPOLYS ==> Fraction POLYS
+    FSUPFPOLYS ==> Fraction SUP FPOLYS
+
+-- brauche hier EXPRI, weil das Ergebnis ja die allgemeine Form enthält
 

??changed:
     Exports == with
-      guess: (Symbol, List F, BASIS, List GUESSER, List Symbol, NNI) -> 
GUESSRESULT
-
-      guessRat: (Symbol, List F, BASIS) -> GUESSRESULT
-
-      guessExpRat: (Symbol, List F, BASIS) -> GUESSRESULT
-
-      guessPade: (Symbol, List F, BASIS) -> GUESSRESULT
-
-      guessPRec: (Symbol, List F, BASIS) -> GUESSRESULT
-
+
+      guess: List F -> GUESSRESULT
+        ++ \spad{guess l} applies recursively \spadfun{guessRec} and
+        ++ \spadfun{guessADE} to the successive differences and quotients of
+        ++ the list. Default options as described in
+        ++ \spadtype{GuessOptionFunctions0} are used.
+
+      guess: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guess(l, options)} applies recursively \spadfun{guessRec} and
+        ++ \spadfun{guessADE} to the successive differences and quotients of
+        ++ the list. The given options are used.
+
+      guess: (List F, List GUESSER, List Symbol) -> GUESSRESULT
+        ++ \spad{guess(l, guessers, ops)} applies recursively the given
+        ++ guessers to the successive differences if ops contains the symbol
+        ++ guessSum and quotients if ops contains the symbol guessProduct to
+        ++ the list. Default options as described in
+        ++ \spadtype{GuessOptionFunctions0} are used.
+
+      guess: (List F, List GUESSER, List Symbol, LGOPT) -> GUESSRESULT
+        ++ \spad{guess(l, guessers, ops)} applies recursively the given
+        ++ guessers to the successive differences if ops contains the symbol
+        ++ \spad{guessSum} and quotients if ops contains the symbol
+        ++ \spad{guessProduct} to the list. The given options are used.
+
+      guessExpRat: List F -> GUESSRESULT
+        ++ \spad{guessExpRat l} tries to find a function of the form n+->(a+b
+        ++ n)^n r(n), where r(n) is a rational function, that fits l.
+
+      guessExpRat: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessExpRat(l, options)} tries to find a function of the form
+        ++ n+->(a+b n)^n r(n), where r(n) is a rational function, that fits l.
+
+      guessExpRat: DIFFSPECN -> GUESSER
+        ++ \spad{guessExpRat D} returns a guesser that tries to find a function
+        ++ of the form n+->(a+b D(n))^n r(D(n)), where r(n) is a rational
+        ++ function, that fits l.
+
+      guessHP: (LGOPT -> HPSPEC) -> GUESSER
+        ++ \spad{guessHP f} constructs an operation that applies Hermite-Pade
+        ++ approximation to the series generated by the given function f.
+
+      guessADE: List F -> GUESSRESULT
+        ++ \spad{guessADE l} tries to find an algebraic differential equation
+        ++ for a generating function whose first Taylor coefficients are given
+        ++ by l, using the default options described in
+        ++ \spadtype{GuessOptionFunctions0}.
+
+      guessADE: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessADE(l, options)} tries to find an algebraic differential
+        ++ equation for a generating function whose first Taylor coefficients
+        ++ are given by l, using the given options.
+
+      guessAlg: List F -> GUESSRESULT
+        ++ \spad{guessAlg l} tries to find an algebraic equation for a
+        ++ generating function whose first Taylor coefficients are given by l,
+        ++ using the default options described in
+        ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+        ++ \spadfun{guessADE}(l, maxDerivative == 0).
+
+      guessAlg: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessAlg(l, options)} tries to find an algebraic equation for
+        ++ a generating function whose first Taylor coefficients are given by
+        ++ l, using the given options. It is equivalent to
+        ++ \spadfun{guessADE}(l, options) with \spad{maxDerivative == 0}.
+
+      guessHolo: List F -> GUESSRESULT
+        ++ \spad{guessHolo l} tries to find an ordinary linear differential
+        ++ equation for a generating function whose first Taylor coefficients
+        ++ are given by l, using the default options described in
+        ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+        ++ \spadfun{guessADE}\spad{(l, maxPower == 1)}.
+
+      guessHolo: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessHolo(l, options)} tries to find an ordinary linear
+        ++ differential equation for a generating function whose first Taylor
+        ++ coefficients are given by l, using the given options. It is
+        ++ equivalent to \spadfun{guessADE}\spad{(l, options)} with
+        ++ \spad{maxPower == 1}.
+
+      guessPade: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessPade(l, options)} tries to find a rational function whose
+        ++ first Taylor coefficients are given by l, using the given
+        ++ options. It is equivalent to \spadfun{guessADE}\spad{(l,
+        ++ maxDerivative == 0, maxPower == 1, allDegrees == true)}.
+
+      guessPade: List F -> GUESSRESULT
+        ++ \spad{guessPade(l, options)} tries to find a rational function whose
+        ++ first Taylor coefficients are given by l, using the default options
+        ++ described in \spadtype{GuessOptionFunctions0}. It is equivalent to
+        ++ \spadfun{guessADE}\spad{(l, options)} with \spad{maxDerivative == 0,
+        ++ maxPower == 1, allDegrees == true}.
+
+      guessRec: List F -> GUESSRESULT
+        ++ \spad{guessRec l} tries to find an ordinary difference equation
+        ++ whose first values are given by l, using the default options
+        ++ described in \spadtype{GuessOptionFunctions0}.
+
+      guessRec: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessRec(l, options)} tries to find an ordinary difference
+        ++ equation whose first values are given by l, using the given options.
+
+      guessPRec: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessPRec(l, options)} tries to find a linear recurrence with
+        ++ polynomial coefficients whose first values are given by l, using the
+        ++ given options. It is equivalent to \spadfun{guessRec}\spad{(l,
+        ++ options)} with \spad{maxPower == 1}.
+
+      guessPRec: List F -> GUESSRESULT
+        ++ \spad{guessPRec l} tries to find a linear recurrence with polynomial
+        ++ coefficients whose first values are given by l, using the default
+        ++ options described in \spadtype{GuessOptionFunctions0}. It is
+        ++ equivalent to \spadfun{guessRec}\spad{(l, maxPower == 1)}.
+
+      guessRat: (List F, LGOPT) -> GUESSRESULT
+        ++ \spad{guessRat(l, options)} tries to find a rational function whose
+        ++ first values are given by l, using the given options. It is
+        ++ equivalent to \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower ==
+        ++ 1, allDegrees == true)}.
+
+      guessRat: List F -> GUESSRESULT
+        ++ \spad{guessRat l} tries to find a rational function whose first
+        ++ values are given by l, using the default options described in
+        ++ \spadtype{GuessOptionFunctions0}. It is equivalent to
+        ++ \spadfun{guessRec}\spad{(l, maxShift == 0, maxPower == 1, allDegrees
+        ++ == true)}.
+
+      diffHP: LGOPT -> HPSPEC
+        ++ \spad{diffHP options} returns a specification for Hermite-Pade
+        ++ approximation with the differential operator
+
+      shiftHP: LGOPT -> HPSPEC
+        ++ \spad{shiftHP options} returns a specification for Hermite-Pade
+        ++ approximation with the shift operator
+
+      if F has RetractableTo Symbol and S has RetractableTo Symbol then
+        qShiftHP: Symbol -> (LGOPT -> HPSPEC)
+          ++ \spad{qshiftHP options} returns a specification for Hermite-Pade
+          ++ approximation with the $q$-shift operator
+
+        guessqRec: Symbol -> GUESSER
+          ++ \spad{guessqRec q} returns a guesser that finds an ordinary
+          ++ q-difference equation whose first values are given by l, using the
+          ++ given options.
+  
+        guessqPRec: Symbol -> GUESSER
+          ++ \spad{guessqPRec q} returns a guesser that tries to find
+          ++ a linear q-recurrence with polynomial coefficients whose first
+          ++ values are given by l, using the given options. It is equivalent
+          ++ to \spadfun{guessqRec}\spad{(q)} with \spad{maxPower == 1}.
+  
+        guessqRat: Symbol -> GUESSER
+          ++ \spad{guessqRat q} returns a guesser that tries to find a
+          ++ q-rational function whose first values are given by l, using the
+          ++ given options. It is equivalent to \spadfun{guessqRec} with
+          ++ \spad{(l, maxShift == 0, maxPower == 1, allDegrees == true)}.
+
+      ord1: Integer -> Integer
+
+      ord2: (Integer, Integer) -> Integer
+
+      deg1: (Integer, Integer) -> Integer
+
+      deg2: (Integer, Integer) -> Integer
+
+  
     Implementation == add

??changed:
 
-      basis2: (BASIS, Integer) -> F
-      basis2 (basis, i) == retract(retract(basis(i::EXPRI))@R)
-
-      SUP ==> SparseUnivariatePolynomial
-      SUPF ==> SUP F
-      FSUPF ==> Fraction SUP F
-      V ==> OrderedVariableList(['a1, 'A])
-      POLYF ==> SparseMultivariatePolynomial(F, V)
-      FPOLYF ==> Fraction POLYF
-      FSUPFPOLYF ==> Fraction SUP FPOLYF
-      POLYS ==> SparseMultivariatePolynomial(S, V)
+-------------------------------------------------------------------------------
+-- order and degree for the resultants in guessExpRat
+-------------------------------------------------------------------------------
+
+-- Note that this expression are only conjectured - in fact, using guessRat.
+
+-- We have to put them at the beginning, because otherwise they will
+-- take very long to compile.
+
+      ord1(n: Integer): Integer == (3*n**4-4*n**3+3*n*n-2*n) quo 12
+
+      ord2(n: Integer, i: Integer): Integer == 
+        if i=0 
+        then ord1 n + ((n*n-n) quo 2)
+        else ord1 n
+         
+
+      deg1(n: Integer, i: Integer): Integer == 
+        (12*n*n*i*i+_
+         12*n**3*i+6*n*n*i+30*n*i+_
+          3*n**4+2*n**3+21*n*n+10*n) quo 12
+
+-- if the first element of the list is f(1), we get the following expression:
+--        (3*n**4+12*i*n**3+2*n**3+12*i*i*n*n-6*i*n*n+15*n*n
+--                        -24*i*i*n+6*i*n-8*n+12*i*i-12*i-12) quo 12
+
+
+      deg2(n: Integer, i: Integer): Integer == 
+        deg1(n, i) + ((2*n*i+n*n+n+4) quo 2)
+
+-- if the first element of the list is f(1), we get the following expression:
+--        deg1(n,i) + (n**2+2*i*n+n-2*i+2) quo 2
+
+-------------------------------------------------------------------------------
+
+      checkResult(res: EXPRR, n: Symbol, l: Integer, list: List F, 
+                  options: LGOPT): NNI ==
+        for i in l..1 by -1 repeat
+          den := eval(denominator res, n::EXPRR, (i-1)::EXPRR)
+          if den = 0 then return i::NNI
+          num := eval(numerator res, n::EXPRR, (i-1)::EXPRR)
+          if list.i ~= retract(retract(num/den)@R)
+          then return i::NNI
+        0$NNI
+
+-------------------------------------------------------------------------------
+-- helpers for guessExpRat
+-------------------------------------------------------------------------------
+
+      F2FPOLYS(p: F): FPOLYS ==
+        if F is S then 
+          p::POLYF::FPOLYF pretend FPOLYS
+        else if F is Fraction S then
+          numer(p)$Fraction(S)::POLYS/denom(p)$Fraction(S)::POLYS
+        else error "Type parameter F should be either equal to S or equal _
+                     to Fraction S"
+
+
+-- applies n+->q^n to i
+      DN2DL: (DIFFSPECN, Integer) -> F
+      DN2DL(DN, i) == retract(retract(DN(i::EXPRR))@R)
+
+      resl(p1: POLYS, p2: POLYS, o: Integer, d: Integer, vA: V): List S == 
+        [(resultant(univariate(eval(p1, vA, k::S)),
+                    univariate(eval(p2, vA, k::S)))$SUP(S) exquo _
+         ((k::S)**(o::NNI)))::S for k in 1..d]
+
+
+      defaultD: DIFFSPECN
+      defaultD(expr: EXPRR): EXPRR == expr
+
+
+      p(len: Integer, i: Integer, va1: V, vA: V, basis: DIFFSPECN): FPOLYS == 
+--     a0 + a1*DN2DL(basis, i)
+-- setting A=a0+basis(len+3)*a1, hence a0=A-(len+3)*a1 makes poly3 a lot
+-- smaller
+        vA::POLYS::FPOLYS + va1::POLYS::FPOLYS _ 
+                           *F2FPOLYS(DN2DL(basis, i)-DN2DL(basis, len+3))
+
+
+      p2(len: Integer, i: Symbol, a1v: F, Av: F, basis: DIFFSPECN): EXPRR == 
+--     a0 + a1*DN2DL(basis, i)
+-- setting A=a0+basis(len+3)*a1, hence a0=A-(len+3)*a1 makes poly3 a lot 
+-- smaller
+        coerce(Av) + coerce(a1v)*(basis(i::EXPRR)
+                                 -basis((len+3)::EXPRR))
 

??changed:
                                       POLYS, POLYF)
-      MPCFS ==> MPolyCatFunctions2(V, IndexedExponents V, 
-                                      IndexedExponents V, F, S,
-                                      POLYF, POLYS)
-
-      SUPF2EXPRR: (Symbol, SUP F) -> EXPRR
-      SUPF2EXPRR(xx, p) ==
+
+      SUPF2EXPRR(xx: Symbol, p: SUP F): EXPRR ==
         zero? p => 0

??changed:
 
-      FSUPF2EXPRR: (Symbol, FSUPF) -> EXPRR
-      FSUPF2EXPRR(xx, p) ==
+      FSUPF2EXPRR(xx: Symbol, p: FSUPF): EXPRR ==
         (SUPF2EXPRR(xx, numer p)) / (SUPF2EXPRR(xx, denom p))

??changed:
 
-      SUPS2SUPF: SUP S -> SUP F
-      SUPS2SUPF p ==
+
+      SUPS2SUPF(p: SUP S): SUP F ==
         if F is S then 

??changed:
                     to Fraction S"
-
-      POLYS2POLYF: POLYS -> POLYF
-      POLYS2POLYF p ==
+ 
+ 
+      POLYS2POLYF(p: POLYS): POLYF ==
         if F is S then 

??changed:
 
-      SUPFPOLYF2SUPF: (SUP FPOLYF, F, F) -> SUP F
-      SUPFPOLYF2SUPF(p, a1v, Av) ==
+      SUPPOLYS2SUPF(p: SUP POLYS, a1v: F, Av: F): SUP F ==
         zero? p => 0

??changed:
         zero? p => 0
-        lc: FPOLYF := leadingCoefficient(p)
-        num: POLYF := eval(numer lc, [index(1)$V, index(2)$V]::List V, [a1v, 
Av])
-        den: POLYF := eval(denom lc, [index(1)$V, index(2)$V]::List V, [a1v, 
Av])
-        monomial(retract(num)/retract(den), degree p) 
-          + SUPFPOLYF2SUPF(reductum p, a1v, Av)
-
-      SUPPOLYF2SUPF: (SUP POLYF, F, F) -> SUP F
-      SUPPOLYF2SUPF(p, a1v, Av) ==
-        zero? p => 0
-        lc: POLYF := leadingCoefficient(p)
+        lc: POLYF := POLYS2POLYF leadingCoefficient(p)
         monomial(retract(eval(lc, [index(1)$V, index(2)$V]::List V, 

??changed:
                  degree p) 
-          + SUPPOLYF2SUPF(reductum p, a1v, Av)
-
-      SUPFPOLYF2FSUPPOLYF: (SUP FPOLYF) -> Fraction SUP POLYF
-      SUPFPOLYF2FSUPPOLYF p ==
+          + SUPPOLYS2SUPF(reductum p, a1v, Av)
+
+
+      SUPFPOLYS2FSUPPOLYS(p: SUP FPOLYS): Fraction SUP POLYS  ==
         cden := splitDenominator(p)

??changed:
         cden := splitDenominator(p)
-               $UnivariatePolynomialCommonDenominator(POLYF, FPOLYF,SUP FPOLYF)
-        
-        pnum: SUP POLYF 
-             := map(retract(#1 * cden.den)$FPOLYF, p)
-                   $SparseUnivariatePolynomialFunctions2(FPOLYF, POLYF)
-        pden: SUP POLYF := (cden.den)::SUP POLYF
+               $UnivariatePolynomialCommonDenominator(POLYS, FPOLYS,SUP FPOLYS)
+        
+        pnum: SUP POLYS 
+             := map(retract(#1 * cden.den)$FPOLYS, p)
+                   $SparseUnivariatePolynomialFunctions2(FPOLYS, POLYS)
+        pden: SUP POLYS := (cden.den)::SUP POLYS
 

??changed:
 
-      POLYF2EXPRR: POLYF -> EXPRR
-      POLYF2EXPRR p ==
+      POLYF2EXPRR(p: POLYF): EXPRR ==
         map(convert(#1)@Symbol::EXPRR, coerce(#1)@EXPRR, p)

--removed:
 
-      checkResult: (EXPRR, Symbol, Integer, List F) -> PI
-      checkResult (res, n, l, list) ==
-        for i in l..1 by -1 repeat
-          den := eval(denominator res, n::EXPRR, i::EXPRR)
-          if den = 0 then return (i+1)::PI
-          num := eval(numerator res, n::EXPRR, i::EXPRR)
-          if list.i ~= retract(retract(num/den)@R)
-          then return (i+1)::PI
-        1
-
-      PCD ==> PolynomialCommonDenominator(S, F, POLYF, IndexedExponents V, V)
-
-      cden: POLYF -> POLYS
-      cden p == 
-        if F is S then 
-          p pretend POLYS
-        else if F is Fraction S then
-          map(retract(#1)$Fraction(S), clearDenominator(p)$PCD)$MPCFS
-        else error "Type parameter F should be either equal to S or equal _
-[121 more lines...]
 

 
++added:
+
       GF ==> GeneralizedMultivariateFactorize(SingletonAsOrderedSet,

??changed:
                                               IndexedExponents V, F, F,
-                                              SparseUnivariatePolynomial F)
-
-      resl: (POLYS, POLYS, Integer, Integer, V) -> List S
-      resl(p1, p2, o, d, A) == 
-        [(resultant(univariate(eval(p1, A, k::S)),
-                    univariate(eval(p2, A, k::S)))$SUP(S) exquo _
-         ((k::S)**(o::NNI)))::S for k in 1..d]
-
-      p: (Integer, Integer, V, V, BASIS) -> POLYF 
-      p(len, i, a1, A, basis) == 
---     a0 + a1*basis2(basis, i)
--- setting A=a0+basis(len+3)*a1, hence a0=A-(len+3)*a1 makes poly3 a lot
--- smaller
-        A::POLYF + a1::POLYF*(basis2(basis, i)-basis2(basis, len+3))
-
-      p2: (Integer, Symbol, F, F, BASIS) -> EXPRR 
-      p2(len, i, a1v, Av, basis) == 
---     a0 + a1*basis2(basis, i)
--- setting A=a0+basis(len+3)*a1, hence a0=A-(len+3)*a1 makes poly3 a lot 
smaller
-[22 more lines...]
+                                              SUP F)
+
+      guessExpRatAux(xx: Symbol, list: List F, basis: DIFFSPECN, 
+                     xValues: List Integer, options: LGOPT): List EXPRR ==
+-- FIXME: we don't take safety into account yet, but that would be very useful!
+
         a1: V := index(1)$V

??changed:
 
-        len:NNI := (#list-3)::NNI
-        if len < 1 then return []
-        xlist := [basis2(basis, xValues.i)::POLYF::FPOLYF for i in 1..len]
-        x1 := basis2(basis, xValues.(len+1))::POLYF::FPOLYF
-        x2 := basis2(basis, xValues.(len+2))::POLYF::FPOLYF
-        x3 := basis2(basis, xValues.(len+3))::POLYF::FPOLYF
-
-        y: NNI -> FPOLYF := 
-          (list.#1)::F::POLYF::FPOLYF * p(len, (xValues.#1)::Integer, a1, A, 
basis)::FPOLYF**(-(xValues.#1)::Integer)
-
-        ylist: List FPOLYF := [y i for i in 1..len]
+        len: NNI := #list
+        if len < 4 then return []
+                   else len := (len-3)::NNI
+
+        xlist := [F2FPOLYS DN2DL(basis, xValues.i) for i in 1..len]
+        x1 := F2FPOLYS DN2DL(basis, xValues.(len+1))
+        x2 := F2FPOLYS DN2DL(basis, xValues.(len+2))
+        x3 := F2FPOLYS DN2DL(basis, xValues.(len+3))
+
+        y: NNI -> FPOLYS := 
+          F2FPOLYS(list.#1) * _
+          p(len, (xValues.#1)::Integer, a1, A, basis)**(-(xValues.#1)::Integer)
+
+        ylist: List FPOLYS := [y i for i in 1..len]
 

??changed:
         for i in 0..len-1 repeat
-          output(hconcat("degree ExpRat "::OutputForm, 
i::OutputForm))$OutputPackage
-          ri: FSUPFPOLYF
-             := interpolate(xlist, ylist, (len-1-i)::NNI, i)
-                           $RationalInterpolation(xx, FPOLYF)
-
-          poly1:POLYS := cden(numer(elt(ri, x1)$SUP(FPOLYF) - y1)$FPOLYF)
-          poly2:POLYS := cden(numer(elt(ri, x2)$SUP(FPOLYF) - y2)$FPOLYF)
-          poly3:POLYS := cden(numer(elt(ri, x3)$SUP(FPOLYF) - y3)$FPOLYF)
-
-          n:Integer := len - i + 1
-          if n > 5 then
-            output("interpolating"::OutputForm)$OutputPackage
+          if debug(options)$GOPT0 then
+            output(hconcat("degree ExpRat "::OutputForm, i::OutputForm))
+                  $OutputPackage
+          ri: FSUPFPOLYS
+             := interpolate(xlist, ylist, (len-1-i)::NNI) _
+                           $FFFG(FPOLYS, SUP FPOLYS)
+
+          poly1:POLYS := numer(elt(ri, x1)$SUP(FPOLYS) - y1)
+          poly2:POLYS := numer(elt(ri, x2)$SUP(FPOLYS) - y2)
+          poly3:POLYS := numer(elt(ri, x3)$SUP(FPOLYS) - y3)
+
+          n:Integer := len - i
+          if n > 0 then
+            if debug(options)$GOPT0 then
+              output("interpolating"::OutputForm)$OutputPackage
             o1:Integer := ord1(n)

--removed:
 
--- RINTERP seems to be a lot faster than PINTERP
 -- another compiler bug: using i as iterator here makes the loop break

??changed:
             res1: SUP S
-                 := retract(interpolate([j::S for j in 1..d1-o1+1], 
-                                        resl(poly1, poly3, o1, d1-o1+1, A), 
-                                        (d1-o1)::NNI, 0)
-                                       $RationalInterpolation(xx, S)
-                            ::Fraction(SUP(S)))$Fraction(SUP(S))
+                 := newton(resl(poly1, poly3, o1, d1-o1+1, A))
+                          $NewtonInterpolation(S)
 

??changed:
             res2: SUP S
-                 := retract(interpolate([j::S for j in 1..d2-o2+1], 
-                                        resl(poly2, poly3, o2, d2-o2+1, A), 
-                                        (d2-o2)::NNI, 0)
-                                       $RationalInterpolation(xx, S)
-                            ::Fraction(SUP(S)))$Fraction(SUP(S))
+                 := newton(resl(poly2, poly3, o2, d2-o2+1, A))
+                          $NewtonInterpolation(S)
+
           else

??changed:
           else
-            output("resultants"::OutputForm)$OutputPackage
+            if debug(options)$GOPT0 then
+              output("resultants"::OutputForm)$OutputPackage
             res1: SUP S := univariate(resultant(poly1, poly3, a1))

??changed:
 
--- res3 ist ein Polynom in A=a0+(len+3)*a1
--- jetzt muss ich das loesen
+-- res3 is a polynomial in A=a0+(len+3)*a1
+-- now we have to find the roots of res3
 

??changed:
 
-                        ri1: Fraction SUP POLYF 
-                            := SUPFPOLYF2FSUPPOLYF(numer ri)
-                             / SUPFPOLYF2FSUPPOLYF(denom ri)
-
-                        num: SUP F := SUPPOLYF2SUPF(numer ri1, a1v, Av)
-                        den: SUP F := SUPPOLYF2SUPF(denom ri1, a1v, Av)
-
-                        if den ~= 0 then
-                          res7: EXPRR := eval(FSUPF2EXPRR(xx, num/den),
+                        ri1: Fraction SUP POLYS 
+                            := SUPFPOLYS2FSUPPOLYS(numer ri)
+                             / SUPFPOLYS2FSUPPOLYS(denom ri)
+
+                        numr: SUP F := SUPPOLYS2SUPF(numer ri1, a1v, Av)
+                        denr: SUP F := SUPPOLYS2SUPF(denom ri1, a1v, Av)
+
+                        if denr ~= 0 then
+                          res7: EXPRR := eval(FSUPF2EXPRR(xx, numr/denr),
                                               kernel(xx), 

??changed:
                                               kernel(xx), 
-                                              basis(xx::EXPRI))
+                                              basis(xx::EXPRR))
                                         *p2(len, xx, a1v, Av, basis)**xx::EXPRR

??changed:
                           res := cons(res7, res)
-                        else if num = 0 then
+                        else if numr = 0 then
                           output("numerator and denominator vanish!")

??changed:
   
-          if not null(res) then return res
+          if not null(res) and one(options)$GOPT0 then return res
 

??changed:
 
-      guessExpRat(xx, list, basis) ==
+      guessExpRatAux0(list: List F, basis: DIFFSPECN, options: LGOPT)
+                     : GUESSRESULT ==
 -- guesses Functions of the Form (a1*n+a0)^n*rat(n)

 -- guesses Functions of the Form (a1*n+a0)^n*rat(n)
++added:
+        xx := indexName(options)$GOPT0
 

??changed:
         xValues: List Integer
-        i: Integer
-
-        i := 0
+
+        i: Integer := -1
         for x in list repeat

??changed:
           i := i+1
-          if x = 0 then zeros := zeros * (basis(xx::EXPRI) - basis(i::EXPRI))
-
-        i := 0
+          if x = 0 then zeros := zeros * (basis(xx::EXPRR) - basis(i::EXPRR))
+
+        i := -1
         for x in list repeat

??changed:
         res: List EXPRR 
-            := [zeros * f for f in guessExpRatAux(xx, newlist, basis, xValues)]
-        
-        map([#1, checkResult(#1, xx, len, list)], res)
-           $ListFunctions2(EXPRR,
-                           Record(function: EXPRR, order: PI))
+            := [eval(zeros * f, xx::EXPRR, xx::EXPRR) _
+                for f in guessExpRatAux(xx, newlist, basis, xValues, options)]
+        
+        map([#1, checkResult(#1, xx, len, list, options)], res)
+           $ListFunctions2(EXPRR, Record(function: EXPRR, order: NNI))
+
+      guessExpRat(list : List F): GUESSRESULT ==
+        guessExpRatAux0(list, defaultD, [])
+
+      guessExpRat(list: List F, options: LGOPT): GUESSRESULT ==
+        guessExpRatAux0(list, defaultD, options)
+
+      guessExpRat(D: DIFFSPECN): GUESSER ==
+        guessExpRatAux0(#1, D, #2)
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+-- some useful types for Ore operators that work on series
+
+-- the differentiation operator
+      DIFFSPECX ==> (EXPRR, Symbol, NonNegativeInteger) -> EXPRR
+                                               -- eg.: f(x)+->f(q*x)
+                                               --      f(x)+->D(f, x)
+      DIFFSPECS ==> (UFPSF, NonNegativeInteger) -> UFPSF
+                                               -- eg.: f(x)+->f(q*x)
+  
+      DIFFSPECSF ==> (UFPSSUPF, NonNegativeInteger) -> UFPSSUPF
+                                               -- eg.: f(x)+->f(q*x)
+  
+-- the constant term for the inhomogeneous case
+  
+      DIFFSPEC1 ==> UFPSF
+  
+      DIFFSPEC1F ==> UFPSSUPF
+  
+      DIFFSPEC1X ==> Symbol -> EXPRR
+
+-------------------------------------------------------------------------------
+-- functions that provide streams for HermitePade
+-------------------------------------------------------------------------------
+
+-- returns \prod f^(l.i)
+      termAsUFPSF(f: UFPSF, l: List Integer, 
+                  DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
+        if empty? l then D1
+        else
+          ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+          fl: List UFPSF := [DS(f, (first part -1)::NonNegativeInteger) _
+                             ** second(part)::NNI for part in ll]
+
+          reduce(_*, fl)
+
+
+-- returns \prod f^(l.i)
+      termAsUFPSF2(f: UFPSF, l: List Integer, 
+                   DS: DIFFSPECS, D1: DIFFSPEC1): UFPSF ==
+        if empty? l then D1
+        else
+          ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+          fl: List UFPSF 
+             := [map(#1** second(part)::NNI, DS(f, (first part -1)::NNI)) _
+                 for part in ll]
+
+          reduce(hadamard$UFPS1(F), fl)
+
+
+
+-- returns \prod f^(l.i), but as an EXPRR
+      termAsEXPRR(f: EXPRR, xx: Symbol, l: List Integer, 
+                  DX: DIFFSPECX, D1X: DIFFSPEC1X): EXPRR ==
+        if empty? l then D1X(xx)
+        else
+          ll: List List Integer := powers(l)$Partition
+
+          fl: List EXPRR := [DX(f, xx, (first part-1)::NonNegativeInteger)
+                             ** second(part)::NNI for part in ll]
+          reduce(_*, fl)
+
+
+      termAsUFPSSUPF(f: UFPSSUPF, l: List Integer, 
+                     DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
+        if empty? l then D1F
+        else
+          ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+          fl: List UFPSSUPF
+             := [DSF(f, (first part -1)::NonNegativeInteger)
+                 ** second(part)::NNI for part in ll]
+
+          reduce(_*, fl)
+
+
+-- returns \prod f^(l.i)
+      termAsUFPSSUPF2(f: UFPSSUPF, l: List Integer, 
+                   DSF: DIFFSPECSF, D1F: DIFFSPEC1F): UFPSSUPF ==
+        if empty? l then D1F
+        else
+          ll: List List Integer := powers(l)$Partition
+
+-- first of each element of ll is the derivative, second is the power
+
+          fl: List UFPSSUPF 
+             := [map(#1 ** second(part)::NNI, DSF(f, (first part -1)::NNI)) _
+                 for part in ll]
+
+          reduce(hadamard$UFPS1(SUP F), fl)
+
+-------------------------------------------------------------------------------
+
+      FilteredPartitionStream(options: LGOPT): Stream List Integer ==
+        maxD := 1+maxDerivative(options)$GOPT0
+        maxP := maxPower(options)$GOPT0
+
+        if maxD > 0 and maxP > -1 then
+          s := partitions(maxD, maxP)$PartitionsAndPermutations
+        else
+          s1: Stream Integer := generate(inc, 1)$Stream(Integer)
+          s2: Stream Stream List Integer 
+             := map(partitions(#1)$PartitionsAndPermutations, s1)
+                   $StreamFunctions2(Integer, Stream List Integer)
+          s3: Stream List Integer 
+             := concat(s2)$StreamFunctions1(List Integer)
+  
+          s := cons([],
+                    select(((maxD = 0) or (# #1 <= maxD)) _
+                       and ((maxP = -1) or (first #1 <= maxP)), s3))
+
+        s := conjugates(s)$PartitionsAndPermutations
+        if homogeneous(options)$GOPT0 then rest s else s
+
+      ADEguessStream(f: UFPSF, partitions: Stream List Integer, 
+                DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
+        map(termAsUFPSF(f, #1, DS, D1), partitions)
+           $StreamFunctions2(List Integer, UFPSF)
+
+      ADEguessStream2(f: UFPSF, partitions: Stream List Integer, 
+                DS: DIFFSPECS, D1: DIFFSPEC1): Stream UFPSF ==
+        map(termAsUFPSF2(f, #1, DS, D1), partitions)
+           $StreamFunctions2(List Integer, UFPSF)
+
+      ADEdegreeStream(partitions: Stream List Integer): Stream NNI ==
+        scan(0, max((if empty? #1 then 0 else (first #1 - 1)::NNI), #2),
+             partitions)$StreamFunctions2(List Integer, NNI)
+
+      ADEtestStream(f: UFPSSUPF, partitions: Stream List Integer, 
+                    DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
+        map(termAsUFPSSUPF(f, #1, DSF, D1F), partitions)
+           $StreamFunctions2(List Integer, UFPSSUPF)
+
+      ADEtestStream2(f: UFPSSUPF, partitions: Stream List Integer, 
+                    DSF: DIFFSPECSF, D1F: DIFFSPEC1F): Stream UFPSSUPF ==
+        map(termAsUFPSSUPF2(f, #1, DSF, D1F), partitions)
+           $StreamFunctions2(List Integer, UFPSSUPF)
+
+      ADEEXPRRStream(f: EXPRR, xx: Symbol, partitions: Stream List Integer, 
+                     DX: DIFFSPECX, D1X: DIFFSPEC1X): Stream EXPRR ==
+        map(termAsEXPRR(f, xx, #1, DX, D1X), partitions)
+           $StreamFunctions2(List Integer, EXPRR)
+
+-------------------------------------------------------------------------------
+-- the differentiation setting
+-------------------------------------------------------------------------------
+
+-- differentiating an expression
+      diffDX: DIFFSPECX
+      diffDX(expr, x, n) == D(expr, x, n)
+
+-- differentiating a series
+      diffDS: DIFFSPECS
+      diffDS(s, n) == D(s, n)
+
+-- differentiating a series with a transcendental element
+      diffDSF: DIFFSPECSF
+      diffDSF(s, n) == 
+-- I have to help the compiler here a little to choose the right signature...
+        if SUP F has _*: (NonNegativeInteger, SUP F) -> SUP F
+        then D(s, n)
+
+-- the coefficient of x^k in z^l f(x), for series
+      diffA: DIFFSPECA
+      diffA(k: NNI, l: NNI, f: SUP S): S ==
+        DiffAction(k, l, f)$FFFG(S, SUP S)
+
+-- the coefficient of x^k in z^l f(x), for series with a transcendental element
+      diffAF: DIFFSPECAF
+      diffAF(k: NNI, l: NNI, f: UFPSSUPF): SUP F ==
+        DiffAction(k, l, f)$FFFG(SUP F, UFPSSUPF)
+
+-- the coefficient of x^k in z^l f(x), for expressions
+      diffAX: DIFFSPECAX
+[560 more lines...]
 

??changed:
 
-      guess(xx, list, basis, guessers, ops, maxlevel) ==
-        output(hconcat("New guessing level "::OutputForm, 
maxlevel::OutputForm))
-             $OutputPackage
-        res: List Record(function: EXPRR, order: PI) := []
-        len:= #list :: PositiveInteger
+      guess(list: List F): GUESSRESULT == 
+        guess(list, [guessADE$%, guessRec$%], ['guessProduct, 'guessSum], [])
+
+      guess(list: List F, options: LGOPT): GUESSRESULT == 
+        guess(list, [guessADE$%, guessRat$%], ['guessProduct, 'guessSum], 
+              options)
+
+      guess(list: List F, guessers: List GUESSER, ops: List Symbol)
+           : GUESSRESULT == 
+        guess(list, guessers, ops, [])
+
+      guess(list: List F, guessers: List GUESSER, ops: List Symbol, 
+            options: LGOPT): GUESSRESULT ==
+        maxLevel := maxLevel(options)$GOPT0
+        xx := indexName(options)$GOPT0
+        if debug(options)$GOPT0 then
+          output(hconcat("guessing level ", maxLevel::OutputForm))
+                $OutputPackage
+          output(hconcat("guessing ", list::OutputForm))$OutputPackage
+        res: GUESSRESULT := []
+        len := #list :: PositiveInteger
         if len > 1 then

??changed:
           for guesser in guessers repeat
-            res := append(guesser(xx, list, basis), res)
-
-            if member?('guessOne, ops) and not null(res) then return res
-
-          if (maxlevel <= 0) then return res
-
+            res := append(guesser(list, options), res)
+
+            if debug(options)$GOPT0 then
+              output(hconcat("res ", res::OutputForm))$OutputPackage
+
+            if one(options)$GOPT0 and not empty? res then return res
+ 
+          if (maxLevel = 0) then return res
+ 
           if member?('guessProduct, ops) and not member?(0$F, list) then

??changed:
               prodGuess := 
-                  [[coerce(list.(guess.order)) 
+                  [[coerce(list.(guess.order+1)) 
                     * product(guess.function, _

??changed:
                     guess.order] _
-                   for guess in guess(var, prodList, basis, guessers, 
-                                      ops, (maxlevel-1)::NNI)$%]
+                   for guess in guess(prodList, guessers, ops,  
+                                      append([indexName(var)$GuessOption,
+                                              maxLevel(maxLevel-1)
+                                                      $GuessOption],
+                                             options))$%]
+
+              if debug(options)$GOPT0 then
+                output(hconcat("prodGuess "::OutputForm, 
+                               prodGuess::OutputForm))
+                      $OutputPackage
 

??changed:
             if not every?(#1=sumList.1, sumList) then
-              var: Symbol := subscript('s, [maxlevel::OutputForm])
+              var: Symbol := subscript('s, [len::OutputForm])
               sumGuess := 

??changed:
               sumGuess := 
-                  [[coerce(list.(guess.order)) _
+                  [[coerce(list.(guess.order+1)) _
                     + summation(guess.function, _

??changed:
                     guess.order] _
-                   for guess in guess(var, sumList, basis, guessers, 
-                                      ops, (maxlevel-1)::NNI)$%]
+                   for guess in guess(sumList, guessers, ops,
+                                      append([indexName(var)$GuessOption,
+                                              maxLevel(maxLevel-1)
+                                                      $GuessOption],
+                                             options))$%]
 

??changed:
         res
-\end{spad}
-
-\begin{spad}
+
+-- concerning algebraic functions, it may make sense to look at A.J.van der
+-- Poorten, Power Series Representing Algebraic Functions, Section 6.
 )abbrev package GUESSINT GuessInteger

??changed:
 GuessInteger() == Guess(Fraction Integer, Integer, Expression Integer, 
-                        Fraction Integer,
-                        id$MappingPackage1(Fraction Integer), 
-                        coerce$Expression(Integer))
-\end{spad}
-
-\begin{spad}
+                     Fraction Integer,
+                     id$MappingPackage1(Fraction Integer), 
+                     coerce$Expression(Integer))
+
+)abbrev package GUESSF1 GuessFiniteFunctions
+++ Description:
+++ This package exports guessing of sequences of numbers in a finite field
+GuessFiniteFunctions(F:Join(FiniteFieldCategory, ConvertibleTo Integer)):
+  Exports == Implementation where
+ 
+    EXPRR ==> Expression Integer
+ 
+    Exports == with
+
+      F2EXPRR: F -> EXPRR
+ 
+    Implementation == add
+ 
+      F2EXPRR(p: F): EXPRR == convert(p)@Integer::EXPRR
+
+)abbrev package GUESSF GuessFinite
+++ Description:
+++ This package exports guessing of sequences of numbers in a finite field
+GuessFinite(F:Join(FiniteFieldCategory, ConvertibleTo Integer)) ==
+  Guess(F, F, Expression Integer, Integer, coerce$F,
+        F2EXPRR$GuessFiniteFunctions(F))
+
 )abbrev package GUESSP GuessPolynomial

                            coerce$Expression(Integer))
++added:
+
 \end{spad}

--
forwarded from http://wiki.axiom-developer.org/[EMAIL PROTECTED]

Reply via email to