with Ada.Text_IO, Logicals, Rationals, Flts, Scalars;
use Ada.Text_IO, Logicals, Rationals, Flts, Scalars;
with Recycling, Matrices, Vectors, Polynoms2;

pragma Elaborate_All (Ada.Text_IO,Logicals,Rationals,Flts);
pragma Elaborate_All (Recycling,Matrices,Vectors,Polynoms2);

generic

  PDeg: in Positive;           --- max degree

  -------------------- begin_include scalars Scalar

  type Scalar is private;

  --- basic
  with function Info(Dummy: Scalar) return Scalar_Info is <>;
  with function IsSharp(S: Scalar) return Boolean is <>;
  with function IsZero(S: Scalar) return Boolean is <>;
  with function "="(S1,S2: Scalar) return Boolean is <>;
  with procedure SetZero(S: in out Scalar) is <>;
  with procedure Copy(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Swap(S1,S2: in out Scalar) is <>;

  --- sets
  with function Center0(S: Scalar) return Boolean is <>;
  with function Contains0(S: Scalar) return Logical is <>;
  with function Contains(S1,S2: Scalar) return Logical is <>;
  with procedure BallAt0(R: in Flt; S: in out Scalar) is <>;
  with function BallAt0(R: Flt) return Scalar is <>;
  with procedure ToErr(S: in out Scalar) is <>;
  with procedure ToErr(S1: in Scalar; S2: in out Scalar) is <>;
  with function ToErr(S: Scalar) return Scalar is <>;
  with procedure Center(S: in out Scalar) is <>;
  with procedure Center(S1: in Scalar; S2: in out Scalar) is <>;
  with function Center(S: Scalar) return Scalar is <>;
  with procedure ModCenter(S: in out Scalar) is <>;
  with procedure ModCenter(S1: in Scalar; S2: in out Scalar) is <>;
  with function ModCenter(S: Scalar) return Scalar is <>;
  with procedure ErrMult(R: in Radius; S: in out Scalar) is <>;
  with procedure Union(S1: in Scalar; S2: in out Scalar) is <>;
  with function Union(S1,S2: Scalar) return Scalar is <>;
  with procedure Intersection(S1: in Scalar; S2: in out Scalar; Empty: out Logical) is <>;

  --- order
  with function Sign(S: Scalar) return Integer is <>;
  with function Compare(S1,S2: Scalar) return Integer is <>;
  with function "<"(S1,S2: Scalar) return Boolean is <>;
  with function "<="(S1,S2: Scalar) return Boolean is <>;
  with function ">"(S1,S2: Scalar) return Boolean is <>;
  with function ">="(S1,S2: Scalar) return Boolean is <>;
  with procedure Min(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Min(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function Min(S1,S2: Scalar) return Scalar is <>;
  with procedure Max(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Max(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function Max(S1,S2: Scalar) return Scalar is <>;
  with function Inf(S: Scalar) return Flt is <>; -- inf of real part
  with function Sup(S: Scalar) return Flt is <>; -- sup of real part

  --- arithmetic
  with procedure Neg(S: in out Scalar) is <>;
  with procedure Neg(S1: in Scalar; S2: in out Scalar) is <>;
  with function "-"(S: Scalar) return Scalar is <>;
  with procedure Add(I: in Integer; S: in out Scalar) is <>;
  with procedure Add(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Sum(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "+"(S1,S2: Scalar) return Scalar is <>;
  with procedure Sub(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Diff(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "-"(S1,S2: Scalar) return Scalar is <>;
  with procedure Mult(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Mult(R: in Flt; S: in out Scalar) is <>;
  with procedure Prod(R: in Flt; S1: in Scalar; S2: in out Scalar) is <>;
  with function "*"(R: Flt; S: Scalar) return Scalar is <>;
  with procedure AddProd(R: in Flt; S1: in Scalar; S2,Tmp: in out Scalar) is <>;
  with procedure AddProd(R: in Flt; S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Mult(Q: in Rational; S: in out Scalar) is <>;
  with procedure Mult(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Prod(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "*"(S1,S2: Scalar) return Scalar is <>;
  with procedure AddProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure AddProd(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with procedure SubProd(S1,S2: in Scalar; S3,Tmp: in out Scalar) is <>;
  with procedure Div(R: in Flt; S,Tmp: in out Scalar) is <>;
  with procedure Div(R: in Flt; S: in out Scalar) is <>;
  with procedure Quot(S1: in Scalar; R: in Flt; S2: in out Scalar) is <>;
  with function "/"(S: Scalar; R: Flt) return Scalar is <>;
  with procedure Div(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Quot(S1,S2: in Scalar; S3: in out Scalar) is <>;
  with function "/"(S1,S2: Scalar) return Scalar is <>;
  with procedure Inv(S1: in Scalar; S2: in out Scalar) is <>;
  with function Inv(S: Scalar) return Scalar is <>;
  with function "**"(S: Scalar; I: Integer) return Scalar is <>;

  --- fun
  with function IsReal(S: Scalar) return Boolean is <>;
  with procedure Adjoint(S: in out Scalar) is <>;
  with procedure Adjoint(S1: in Scalar; S2: in out Scalar) is <>;
  with function Adjoint(S: Scalar) return Scalar is <>;
  with procedure Real_Part(S: in out Scalar) is <>;
  with procedure Imag_Part(S: in out Scalar) is <>;
  with procedure Eval0(S: in out Scalar) is <>;
  with function "abs"(S: Scalar) return Scalar is <>;
  with procedure Norm(S1: in Scalar; S2: in out Scalar) is <>;
  with function Norm(S: Scalar) return Scalar is <>;
  with function MaxNorm(S: Scalar) return Radius is <>;
  with procedure Sqr(S: in out Scalar) is <>;
  with function Sqr(S: Scalar) return Scalar is <>;
  with procedure Sqr(S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Sqrt(S1: in Scalar; S2: in out Scalar) is <>;
  with function Sqrt(S: Scalar) return Scalar is <>;
  with procedure Root(K: in Positive; S1: in Scalar; S2: in out Scalar) is <>;
  with function Root(K: Positive; S: Scalar) return Scalar is <>;
  with procedure Exp(S1: in Scalar; S2: in out Scalar) is <>;
  with function Exp(S: Scalar) return Scalar is <>;
  with procedure ArcCos(S1: in Scalar; S2: in out Scalar) is <>;
  with function ArcCos(S: Scalar) return Scalar is <>;
  with procedure ArcSin(S1: in Scalar; S2: in out Scalar) is <>;
  with function ArcSin(S: Scalar) return Scalar is <>;
  with procedure Cos(S1: in Scalar; S2: in out Scalar) is <>;
  with function Cos(S: Scalar) return Scalar is <>;
  with procedure Sin(S1: in Scalar; S2: in out Scalar) is <>;
  with function Sin(S: Scalar) return Scalar is <>;
  with procedure Log(S1: in Scalar; S2: in out Scalar) is <>;
  with function Log(S: Scalar) return Scalar is <>;
  with function Pi return Scalar is <>;
  with procedure Simple_Random(S: in out Scalar) is <>;
  with procedure QPower(Q: in Rational; S1: in Scalar; S2: in out Scalar) is <>;
  with procedure Roots2(B,C: in Scalar; U1,U2,V: in out Scalar) is <>;
  with procedure Roots3(B,C,D: in Scalar; U0,U1,U2,V: in out Scalar) is <>;

  --- conversion and i/o
  with function Approx(S: Scalar) return Flt is <>;
  with procedure Assign(K: in Integer; S: in out Scalar) is <>;
  with procedure Assign(Q: in Rational; S: in out Scalar) is <>;
  with procedure Assign(R: in Flt; S: in out Scalar) is <>;
  with function Scal(I: Integer) return Scalar is <>;
  with function Scal(Q: Rational) return Scalar is <>;
  with function Scal(R: Flt) return Scalar is <>;
  with procedure Enclose(R1,R2: in Flt; S: in out Scalar) is <>;
  with function Enclose(R1,R2: Flt) return Scalar is <>;
  with procedure Show1(N: in String; S: in Scalar; Whatever: in Boolean := True) is <>;
  with procedure Show2(N: in String; S1,S2: in Scalar; Whatever: in Boolean := True) is <>;
  with procedure Put(F: in File_Type; S: in Scalar; Decimal: in Boolean := False) is <>;
  with procedure Get(F: in File_Type; S: in out Scalar; Decimal: in Boolean := False) is <>;

  --- misc
  with function Get_Precision(R: Scalar) return Positive is <>;
  with procedure Proper_Rounding is <>;
  with procedure Proper_Rounding(Dummy: in Scalar) is <>;

  -------------------- end_include scalars

  with package SM is new Matrices (Scalar => Scalar);
  with package SV is new Vectors (Component => Scalar);

package Taylors2 is -- Taylor series in 2 variables

  pragma Elaborate_Body;

  package Polys2 is new Polynoms2 (PDeg => PDeg, Scalar => Scalar, SM => SM);

  subtype Power is Polys2.Power;
  subtype Poly2 is Polys2.Polynom2;

  Rad: Radius   := One;               -- default domain
  Newton_Parallel: Boolean  := False; -- run parallel version of Newton
  FConst: constant Positive := 16384; -- needs to be larger than PDeg+1

  type Taylor2 is
    record
      C: Poly2;               -- coefficient C(I,J) with I+J<F have no general errors
      F: Natural := FConst;   -- this particular value means that P is constant
      R: Radius  := Rad;      -- domain of analyticity is |z_j|<R
    end record;

  --------------- standard Scalar procedures

  --- basic
  function Info(Dummy: Taylor2) return Scalar_Info;
  function IsSharp(P: Taylor2) return Boolean;       --- polynomial with sharp coeffs
  function IsZero(P: Taylor2) return Boolean;
  function "="(P1,P2: Taylor2) return Boolean;
  procedure SetZero(P: in out Taylor2);
  procedure Copy(P1: in Taylor2; P2: in out Taylor2);
  procedure Swap(P1,P2: in out Taylor2);

  --- sets
  function Center0(P: Taylor2) return Boolean;         --- symmetric about 0
  function Contains0(P: Taylor2) return Logical;
  function Contains(P1,P2: Taylor2) return Logical;
  procedure BallAt0(R: in Flt; P: in out Taylor2);     --- 0-centered ball of radius |R|
  function BallAt0(R: Flt) return Taylor2;             --- 0-centered ball of radius |R|
  procedure DiskAt0(R: in Flt; P: in out Taylor2);     --- constant 0-centered ball of radius |R|
  function DiskAt0(R: Flt) return Taylor2;             --- constant 0-centered ball of radius |R|
  procedure ToErr(P: in out Taylor2);                  --- 0-centered set containing P
  procedure ToErr(P1: in Taylor2; P2: in out Taylor2); --- 0-centered set containing P1
  function ToErr(P: Taylor2) return Taylor2;           --- 0-centered set containing P
  procedure Center(P: in out Taylor2);
  procedure Center(P1: in Taylor2; P2: in out Taylor2);
  function Center(P: Taylor2) return Taylor2;
  procedure ModCenter(P: in out Taylor2);                      --- zero center
  procedure ModCenter(P1: in Taylor2; P2: in out Taylor2);
  function ModCenter(P: Taylor2) return Taylor2;
  procedure ErrMult(R: in Radius; P: in out Taylor2);
  procedure Union(P1: in Taylor2; P2: in out Taylor2);
  function Union(P1,P2: Taylor2) return Taylor2;
  procedure Intersection(P1: in Taylor2; P2: in out Taylor2; Empty: out Logical);

  --- order
  function Sign(P: Taylor2) return Integer;
  function Compare(P1,P2: Taylor2) return Integer;
  function "<"(P1,P2: Taylor2) return Boolean;
  function "<="(P1,P2: Taylor2) return Boolean;
  function ">="(P1,P2: Taylor2) return Boolean;
  function ">"(P1,P2: Taylor2) return Boolean;
  procedure Min(P1: in Taylor2; P2: in out Taylor2);
  procedure Min(P1,P2: in Taylor2; P3: in out Taylor2);
  function Min(P1,P2: Taylor2) return Taylor2;
  procedure Max(P1: in Taylor2; P2: in out Taylor2);
  procedure Max(P1,P2: in Taylor2; P3: in out Taylor2);
  function Max(P1,P2: Taylor2) return Taylor2;
  function Inf(P: Taylor2) return Flt;
  function Sup(P: Taylor2) return Flt;

  --- addition and multiplication etc.
  procedure Neg(P: in out Taylor2);
  procedure Neg(P1: in Taylor2; P2: in out Taylor2);
  function "-"(P: Taylor2) return Taylor2;
  procedure Add(I: in Integer; P: in out Taylor2);
  procedure Add(P1: in Taylor2; P2: in out Taylor2);
  procedure Sum(P1,P2: in Taylor2; P3: in out Taylor2);
  function "+"(P1,P2: Taylor2) return Taylor2;
  procedure Sub(P1: in Taylor2; P2: in out Taylor2);
  procedure Diff(P1,P2: in Taylor2; P3: in out Taylor2);
  function "-"(P1,P2: Taylor2) return Taylor2;
  procedure Mult(R: in Flt; P,Tmp: in out Taylor2);
  procedure Mult(R: in Flt; P: in out Taylor2);
  procedure Prod(R: in Flt; P1: in Taylor2; P2: in out Taylor2);
  function "*"(R: Flt; P: Taylor2) return Taylor2;
  procedure AddProd(R: in Flt; P1: in Taylor2; P2,Tmp: in out Taylor2);
  procedure AddProd(R: in Flt; P1: in Taylor2; P2: in out Taylor2);
  procedure Mult(Q: in Rational; P: in out Taylor2);
  procedure Mult(P1: in Taylor2; P2,Tmp: in out Taylor2);
  procedure Mult(P1: in Taylor2; P2: in out Taylor2);
  procedure Prod(P1,P2: in Taylor2; P3: in out Taylor2);
  function "*"(P1,P2: Taylor2) return Taylor2;
  procedure AddProd(P1,P2: in Taylor2; P3,Dummy: in out Taylor2);
  procedure AddProd(P1,P2: in Taylor2; P3: in out Taylor2);
  procedure SubProd(P1,P2: in Taylor2; P3,Dummy: in out Taylor2);
  procedure Div(R: in Flt; P,Tmp: in out Taylor2);
  procedure Div(R: in Flt; P: in out Taylor2);
  procedure Quot(P1: in Taylor2; R: in Flt; P2: in out Taylor2);
  function "/"(P: Taylor2; R: Flt) return Taylor2;
  procedure Div(P1: in Taylor2; P2: in out Taylor2);
  procedure Quot(P1,P2: in Taylor2; P3: in out Taylor2);
  function "/"(P1,P2: Taylor2) return Taylor2;
  procedure Inv(P: in out Taylor2);
  procedure Inv(P1: in Taylor2; P2: in out Taylor2);
  function Inv(P: Taylor2) return Taylor2;
  function "**"(P: Taylor2; I: Integer) return Taylor2;
  function Pi return Taylor2;

  --- functions
  function IsReal(P: Taylor2) return Boolean;
  procedure Adjoint(P: in out Taylor2);
  procedure Adjoint(P1: in Taylor2; P2: in out Taylor2);
  function Adjoint(P: Taylor2) return Taylor2;
  procedure Real_Part(P: in out Taylor2);
  procedure Imag_Part(P: in out Taylor2);
  procedure Eval0(P: in out Taylor2);
  procedure Norm(P: in Taylor2; Q: in out Taylor2);
  function Norm(P: Taylor2) return Taylor2;
  function "abs"(P: Taylor2) return Taylor2 renames Norm;
  function MaxNorm(P: Taylor2) return Radius;
  procedure Sqr(P: in out Taylor2);
  function Sqr(P: Taylor2) return Taylor2;
  procedure Sqr(P1: in Taylor2; P2: in out Taylor2);
  procedure Sqrt(P1: in Taylor2; P2: in out Taylor2);
  function Sqrt(P: Taylor2) return Taylor2;
  procedure Root(K: in Positive; P1: in Taylor2; P2: in out Taylor2);
  function Root(K: Positive; P: Taylor2) return Taylor2;
  procedure Exp(P1: in Taylor2; P2: in out Taylor2);
  function Exp(P: Taylor2) return Taylor2;
  procedure ArcCos(P1: in Taylor2; P2: in out Taylor2);
  function ArcCos(P: Taylor2) return Taylor2;
  procedure ArcSin(P1: in Taylor2; P2: in out Taylor2);
  function ArcSin(P: Taylor2) return Taylor2;
  procedure Cos(P1: in Taylor2; P2: in out Taylor2);
  function Cos(P: Taylor2) return Taylor2;
  procedure Sin(P1: in Taylor2; P2: in out Taylor2);
  function Sin(P: Taylor2) return Taylor2;
  procedure Log(P1: in Taylor2; P2: in out Taylor2);
  function Log(P: Taylor2) return Taylor2;
  procedure Simple_Random(P: in out Taylor2);
  procedure QPower(Q: in Rational; P1: in Taylor2; P2: in out Taylor2);
  procedure Roots2(B,C: in Taylor2; U1,U2,V: in out Taylor2);
  procedure Roots3(B,C,D: in Taylor2; U0,U1,U2,V: in out Taylor2);

  --- conversion and i/o
  function Approx(P: Taylor2) return Flt;
  procedure Assign(I: in Integer; P: in out Taylor2);
  procedure Assign(Q: in Rational; P: in out Taylor2);
  procedure Assign(R: in Flt; P: in out Taylor2);
  function Scal(I: Integer) return Taylor2;
  function Scal(Q: Rational) return Taylor2;
  function Scal(R: Flt) return Taylor2;
  procedure Enclose(R1,R2: in Flt; P: in out Taylor2);
  function Enclose(R1,R2: Flt) return Taylor2;
  procedure Show1(N: in String; P: in Taylor2; Hide0: in Boolean := True);
  procedure Show2(N: in String; P1,P2: in Taylor2; Hide0: in Boolean := True);
  procedure Put(F: in File_Type; P: in Taylor2; Decimal: in Boolean := False);
  procedure Get(F: in File_Type; P: in out Taylor2; Decimal: in Boolean := False);
  procedure Write(FileName: in String; P: in Taylor2; Decimal: in Boolean := False);
  procedure Read(FileName: in String; P: in out Taylor2; Decimal: in Boolean := False);
  function Read(FileName: String; Decimal: Boolean := False) return Taylor2;

  --- misc
  function Get_Precision(P: Taylor2) return Positive;
  procedure Free_Cache(Dummy: in Taylor2);
  procedure Proper_Rounding(Dummy: in Taylor2);

  --------------- other standard procedures
  function Rho(P: Taylor2) return Radius;
  procedure SetRho(R: in Radius; P: in out Taylor2; Check: in Boolean := True);
  procedure AdjustF(P: in out Taylor2);                           -- adjust error index F
  procedure NonConst(P: in out Taylor2);                          -- use before modifying P.C
  procedure LiftErrs(P: in out Taylor2; F: in Power := 0);        -- make general errors start at degree F
  procedure HiErrs(P: in out Taylor2);                            -- LiftErrs(P,PDeg)
  procedure Assign(S: in Scalar; P: in out Taylor2);
  function Scal(S: Scalar) return Taylor2;
  procedure SetZero(R: in Radius; P: in out Taylor2);

  procedure Coeff(I,J: in Natural; P: in Taylor2; S: in out Scalar);
  function Coeff(I,J: Natural; P: Taylor2) return Scalar;
  procedure AddCoeff(I,J: in Natural; S: in Scalar; P: in out Taylor2);
  procedure Add(S: in Scalar; P: in out Taylor2);
  procedure Mult(S: in Scalar; P: in out Taylor2);
  procedure Prod(S: in Scalar; P1: in Taylor2; P2: in out Taylor2);
  function "*"(S: Scalar; P: Taylor2) return Taylor2;
  procedure AddProd(S: in Scalar; P1: in Taylor2; P2: in out Taylor2);
  procedure SubProd(S: in Scalar; P1: in Taylor2; P2: in out Taylor2);
  procedure Div(S: in Scalar; P: in out Taylor2);

  procedure Val(P: in Taylor2; S1,S2: in Scalar; S3: in out Scalar);
  function Val(P: Taylor2; S1,S2: Scalar) return Scalar;
  procedure Val(P1: in Taylor2; S1,S2: in Scalar; P2: in out Taylor2);
  procedure Norm1(R: in Radius; P: in Taylor2; S: in out Scalar);
  procedure Norm1(P: in Taylor2; S: in out Scalar);
  function Norm1(R: Radius; P: Taylor2) return Scalar;
  function Norm1(P: Taylor2) return Scalar;
  procedure Monom(I,J: in Power; P: in out Taylor2);
  procedure HiUnitBall(I,J: in Power; P: in out Taylor2; R: in Radius := Rad);
  procedure Compose(C: in SV.Polynom1; P1: in Taylor2; P2: in out Taylor2);
  procedure CosSin(P: in Taylor2; PC,PS: in out Taylor2);

  procedure Der1(R: in Radius; P: in out Taylor2);
  procedure Der2(R: in Radius; P: in out Taylor2);
  procedure ValDer1(P: in Taylor2; S1,S2: in Scalar; D1: in out Scalar);
  procedure ValDer2(P: in Taylor2; S1,S2: in Scalar; D2: in out Scalar);
  procedure ValDer(P: in Taylor2; S1,S2: in Scalar; D1,D2: in out Scalar);
  procedure Num_MDer(P: in out Taylor2);
  procedure Inv_MDer(P: in out Taylor2; CheckConst: in Boolean := True);
  function GuessRho(P: Taylor2) return RadPair;

  procedure HiCopy(P1: in Poly2; P2: in out Poly2);
  procedure HiErrMult(R: in Radius; P: in out Poly2);
  function HiContains(P1,P2: Poly2) return Logical;

  procedure Plot(Name: in String; G: in Taylor2; L: Positive := 50);

  --- for debugging
  procedure Test_Some_Ops;
  function Num_MDer(P: in Taylor2) return Taylor2;

  PDeg1: constant Integer := 1+PDeg;
  PDeg2: constant Integer := 2*PDeg;
  Scal_Label: access String := null;

private

  use Polys2;

  subtype PowerC is Integer range 0 .. PDeg2;
  subtype Poly2C is Triangular(PowerC,PowerC);

  procedure SubProd(S: in Scalar; C1: in Poly2; C2: in out Poly2);
  procedure Add(C: in Poly2C; Deg: in Natural; P: in out Taylor2);
  function VarNorm(P: Taylor2) return Radius;
  function Ran(P: Taylor2) return Scalar;
  function Simple(P: Taylor2) return Boolean;
  function TrueF(P: Taylor2) return Natural;
  function NotSharp(C: Poly2; F,L: Integer) return Boolean;
  procedure NewQuot(S0,S1: in Scalar; Q: in out Flt; N: in out Integer);

  procedure IPower(I: in Integer; P1: in Taylor2; P2: in out Taylor2);
  procedure Inv_Split(P1: in Taylor2; P2: in out Taylor2; S: in out Scalar);
  procedure QPower_Split(Q: in Rational; P1: in Taylor2; P2: in out Taylor2; S: in out Scalar);
  procedure Exp_Split(P1: in Taylor2; P2: in out Taylor2; S: in out Scalar);
  procedure CosSin_Split(P1: in Taylor2; P2: in out Taylor2; C,S: in out Scalar);
  procedure Log_Split(P1: in Taylor2; P2: in out Taylor2; S: in out Scalar);
  procedure ArcSin_Part(P1: in Taylor2; P2: in out Taylor2);

  PDegHalf:  constant Power       := PDeg/2;
  PDeg1Half: constant Power       := PDeg1/2;
  SZero:     constant Scalar      := Scal(0);
  SOne:      constant Scalar      := Scal(1);
  SInfo:     constant Scalar_Info := Info(SZero);
  STrunc:    constant Boolean     := SInfo.IsNumeric;
  Not_STrunc:constant Boolean     := not STrunc;
  Std:       constant Boolean     := SInfo.IsStandard;
  TInfo:     constant Scalar_Info := (RepType    => SInfo.RepType,
                                      IsStandard => SInfo.IsStandard,
                                      IsNumeric  => SInfo.IsNumeric,
                                      IsComplex  => SInfo.IsComplex,
                                      NReps      => SInfo.NReps*(PDeg1*(PDeg+2))/2,
                                      RMode      => SInfo.RMode);

  pragma Inline_Always (IsZero,IsSharp,Simple);

  package Alloc is new Recycling (Item => Taylor2);
  subtype LT_Pointer is Alloc.LD_Pointer;
  Pool: Alloc.Protected_Data;

  package AllocC is new Recycling (Item => Poly2C);
  subtype LT_PointerC is AllocC.LD_Pointer;
  PoolC: AllocC.Protected_Data;

end Taylors2;
