module T_

  (module DExport,  -- so, after Test is loaded, all the DoCon
                    -- export is accessible from Test
   test, 
   t_permut_,
   primesBySieve, t_primes_,   
   t_rse_,   
   t_polarit_,  
   t_finfield_,  
   t_rpol_,  
   t_demo1_, 
   t_diagmatr_,  
   pControlSum, t_grbas1_, 
   t_grbas2_,  
   cubicExt, t_cubeext_,
   t_sphGeo_, 
   t_symfunc_,  
   t_detinterp_,
   pFactorizControlSum, testFFPolFactrz, t_pfactor1_, 
   t_pfactor2_, testFactorBi
  )

where
import Maybe (isJust)
import Prelude hiding (minimum, maximum)

import DExport 
import T_permut    (t_permut_                )
import T_primes    (primesBySieve, t_primes_ )
import T_reseuc    (t_rse_                   )
import T_polArit   (t_polarit_               ) 
import T_finfield  (t_finfield_              ) 
import T_rpol      (t_rpol_                  ) 
import T_demo1     (t_demo1_                 )
import T_diagmatr  (t_diagmatr_              )
import T_grbas1    (pControlSum, t_grbas1_   )
import T_grbas2    (t_grbas2_                )
import T_cubeext   (cubicExt, t_cubeext_     )
import T_sphGeo    (t_sphGeo_                )
import T_symfunc   (t_symfunc_               )
import T_detinterp (t_detinterp_             )

import T_pfactor  (pFactorizControlSum, testFFPolFactrz,
                   t_pfactor1_, t_pfactor2_, testFactorBi
                  )



----------------------------------------------------------------------
header = ("===============\n"++)
finsep = ("--- RESULT: \n"++)

test path =   -- the result prints to standard output 
  let         -- and duplicates in the given file `path'
    hd = 
     "\n\nDoCon-2.09   T E S T   for mathematical computation  \n\n"++
     "Each part of the test produces the message ending with the \n"++
     "line of kind  [True,True..].                               \n"++
     "If it appears any  False  or the program breaks, then here \n"++
     "the error locates.                                       \n\n"++
     "The output COPIES to the FILE given in argument.  Say,     \n"++
     "`test \"log\"'  creates a copy in the file  ./log          \n"++
     "source/demotest/T_*.hs  show precisely the examples chosen.\n"++
     "Also T_*.hs show how to run them for  Demo and Benchmark.\n\n"++
     "The simpler examples requiring less of DoCon functionality,\n"++
     "run first, then the more complex ones.                   \n\n"++
     "PRESS  ENTER  to start                                   \n\n"

    (ok, f) = tt
    msg'    = if ok then "*** NO errors detected ***\n\n"
              else         
              "*** ERROR ***\n\nLook for the occurrences of  False"
              ++"\nin the above messages to locate the errors. \n"

    msg1 = f ("\n\n*** Test FINISHED ***\n\n"++msg')
  in
  putStr hd >> writeFile path hd >> getChar >> putStr msg1 >> 
  appendFile path msg1 





------------------------------------------------------------------------
-- This function chooses examples and applies to them more generic
-- functions generated by the tests from the modules T_* 

tt = (ok, f)
  where
  f = 
    permut'            . primes'             . rse'                 .
    polArithm1'        . polArithm2'         . rpol'                . 
    finField1'         . finField2'          . demo1'               . 
    diagmatr'          . gbasCone'           . gbasBu12'            .
    gbasCst'           . gbasCyclRoot'       . gbasMoe12'           . 
    gbasOverP'         . syzAl'              . syzCocoa'            . 
    cyclicInt5'        . cubeext'            . sphGeo'              .
    charKostka'        . discrSym'           . symMonToE'           .
    upolInterp1'       . upolInterp2'        . factor1overPrimeFin' .
    factor1overGenFin' . factor2overPrimeFin'

  ok = and $ ((concat permut)             ++) $
             (primesT                     ++) $
             (rse                         ++) $
             (polArithm                   ++) $
             ((tuple31 t_rpol_)           ++) $
             (finField                    ++) $
             ((take 2 $ tuple31 t_demo1_) ++) $
             ((fst t_diagmatr_)           ++) $
             ((fst gbasCone)              ++) $
             ((fst gbasBu1 )              ++) $
             ((fst gbasBu2 )              ++) $
             ((fst gbasCst)               ++) $
             ((fst gbasCyclRoot)          ++) $
             ((fst gbasMoe1)              ++) $
             ((fst gbasMoe2)              ++) $
             ((fst gbasOverP)             ++) $
             ((tuple51 al)                ++) $
             ((tuple51 cocoa)             : ) $
             ((tuple31 cyclicInt5)        ++) $
             ((tuple41 t_cubeext_)        ++) $
             ((tuple31 t_sphGeo_ )        ++) $
             ((concat charKostkaTest)     ++) $
             ((concat discrSymTest)       ++) $
             (symMonToETest               ++) $
             (((fst interp):(snd interp)) ++) $
             (factor1overPrimeFin         ++) $
             (factor1overGenericFin       ++) 
             factor2overPrimeFin         

  permut  = map (fst . t_permut_) [1 .. nN]  where nN = 7 -- old: 6
  primesT = let ((s, s'), (t, t'), _) = t_primes_  in  [s, t]  
                                           -- s',t' may be expensive

  rse = let (t, t', psTest, sumRs) = t_rse_  in  [t, psTest]
                                              -- t' may be expensive
  polArithm = 
      let ((fromH, cspps), gcds, powBench, gcdBench, _) = t_polarit_ 
          gcds' = map and $ map fst gcds
      in  [fromH, cspps, and gcds']

  finField = tuple41 t_finfield_

  [gbasCone, gbasBu1, gbasBu2, gbasCst, gbasArL, gbasCyclRoot] =
                                                   tuple31 t_grbas1_
  (gbasMoe1, gbasMoe2, gbasOverP) = tuple32 t_grbas1_

  (al, cocoa, _, cyclicInt) = t_grbas2_    -- abya  skipped here
  cyclicInt5                = cyclicInt 5
  (charKostka, discrSym, symMonToE) = t_symfunc_
  charKostkaTest = map (tuple41 . charKostka) [1 .. 9]  -- old: 8
  discrSymTest   = 
      map tuple31 [discrSym "mn" 3, discrSym "m" 3, discrSym "mn" 4]

  symMonToETest = 
           map tuple41 
               [symMonToE "mn" 3, symMonToE "m" 3, symMonToE "mn" 4]
  interp = 
      let q    = 11
          sf1  = "(t+1)*x^2 + t^2*x + 2" 
          sg1  = "t*x^2 + 3*x^3 + t" 
          sf2  = "(t^2+1)*x^4 + 3*x^3 + t^2*x^2 + t^3 +t + 2" 
          sg2  = "x^4 - (t+1)*x^3 + t^2*x " 
          fsts = map tuple51 $ 
                      zipWith (t_detinterp_ q) [sf1, sf2] [sg1, sg2]

          intr = head $ head fsts   -- direct interpolation test 
                                   -- for several polynomials in t
          dIntr = map last fsts    -- finding resultants in two ways
      in  
      (intr, dIntr)

  factor1overPrimeFin = 
      let 
        tfs@[tf2,tf3,tf5,tf13,tf17] = map t_pfactor1_ [2,3,5,13,17]
                                                         -- old: 13
        ts@ [t2,  t3 , t5,  t13,  t17 ] = map tuple43 tfs
        [    op2, op3, op5, op13, op17] = map tuple41 tfs
        (f1Test:_   , _) = op5
        (_:knuTest:_, _) = op13
        testp q t n =
          and 
          [testFFPolFactrz d (factor (t^(q^d) - t)) | d <- [1 .. n]]
      in
      [f1Test, knuTest,  testp 2 t2 6, testp 3 t3 4]

  factor1overGenericFin = let (_, _, t, og) = t_pfactor1_ 5
                              i2            = fromi t 2
                          in  tuple31 $ og (t^3-t-i2)

  factor2overPrimeFin = 
    let
      (unP, family1, _) = t_pfactor2_ 5
      y                 = smParse unP "y"
      [p0, p1, p2]      = map (fromi unP) [0 .. 2]
      [fS, gS] = ["x^3 + y*(x + 1)", "x^3 + y*(y*x^2 + 2)"]

      biTest = [fst (testFactorBi p1 fS gS i j) | 
                (i, j) <- [(0,1), (1,0), (1,1), (1,2), (2,1)]
               ]
      m                  = 2
      family1test (b, p) = 
             [not $ isJust $ fst $ family1 b p n m | n <- [3, 4, 5]]
                                                           -- old: 4
    in
    biTest ++ (family1test (p1, y+p1)) ++ (family1test (p1, y+p2))
  ------------------------------------------------------------------
  permut' =
    (("\n\nPermutation group S = S(n)  \n"++
      (header "")++
      "List all permutations p from S and test each p as follows\n"++
      "cG     = cyclicGroup(p)  in S(n)                         \n"++
      "cycles = [cl(1)..cl(k)] = decomposition of p to cycles   \n"++
      "Verify                                          \n"++
      "  0 < card cG <= card S,                        \n"++
      "  cG is free of repetitions and contains unity, \n"++
      "  composition of cycles   == p,                 \n"++
      "  lcM (map length cycles) == card cG.           \n"++
      "And for  n,  test  osetCard S == n!             \n"++
      "Do this all for  n <- [1..nN].   Here  nN = 7.  \n"
     )++
    ) . finsep . shows permut 

  primes' =
    (("\n\nInteger factorization and List of primes test - sieve and"
      ++" other\n"
     )++
    ) . finsep . shows primesT 

  rse' =
     (("\n\nProperties and division in a residue ring  Z/(b)  \n"++
       "- modelled as ResidueE Z:                             \n"
      )++
     ) . finsep . shows rse 

  polArithm1' =
     (("\n\nArithmetic in  P = Z[z,y,x]  and in  Z[x][y][z]. \n"++
       "The isomorphism test for these domains:  verify      \n"++
       "(^n) == fromP .(^n) .toP                             \n"
      )++
     ) . finsep . shows (init polArithm) 

  polArithm2' =
    (("\n\nGCD in P  \n"++
      (header "")++
      "For  d,f,g,  find  f' = d*f, g' = d*g,  h = gcd f' g' and\n"++
      "verify that  h  divides f',g'  and that  f'/h, g'/g  are \n"++
      "reciprocally prime. There are chosen                     \n"++
      "  d = (2*z + 3*y + 4*x)*(z*y*x^2 + y^3 + 1)  \n"++
      "  f = (z + y + x)^m                          \n"++
      "  g = (z - y + x + 2)^m,  m = 1,2,3          \n"
     )++
    ) . finsep . shows (last polArithm) 

  rpol' =
    (("\n\nR-polynomials. Set of variables, conversion Pol--RPol,\n"
      ++"testing  (^2) == fromRPol.(^2).toRPol:                  \n"
     )++
    ) . finsep . shows (tuple31 t_rpol_) 

  finField1' =
    (("\n\nArithmetic of finite field  F = F25 = Z5[x]/(x^2+2). \n"++
      "Full division test;  x^8==1;                             \n"++ 
      "generating the full multiplicative group with  2x+3      \n"
     )++
    ) . finsep . shows (init finField) 

  finField2' =
    ("\n\nGCD in F25[v,w]. gcd (v*(v^5+1)) (w*(v+1)^2) = (v+1)^2\n"++
    ) . 
    finsep . shows (last finField) 

  demo1' =
    (("\n\nSolving Linear System M*x = 0  for a matrix over Z, \n"++
      "Inversion of a matrix M' over Rational and verifying    \n"++
      "M'*inv(M')==unityMatrix.                                \n"++
      "M,M' are chosen of sizes 3 by 6, 6 by 6.                \n"
     )++
    ) . finsep . shows (take 2 $ tuple31 t_demo1_)

  diagmatr' =
    (("\n\nDiagonalization of a matrix M over K[x], K a field.   \n"++
      "Applying generalized Gauss method,  find such invertible  \n"++
      "T,U \nthat T*M*U = D  is a diagonal matrix.               \n"++
      "Then, check the above equality and that  det(D) = +-det(M)\n"++
      "M is chosen of size 3 by 3.                               \n"++
      "Here, we choose K = Z/(p).                                \n"
     )++
    ) . finsep . shows (fst t_diagmatr_) 

  gbasCone' =
    (("\n\nGroebner basis over a field K. \n"++
      (header "\n")++
      "Deriving the cone equation in  K^3  from the polynomial   \n"++
      "parameterization  fs = [x(u,v),y(u,v),z(u,v)].            \n"++
      "Find  gs = GroebnerBasis(fs)  respectively to lex ordering\n"++
      "for [u,v,x,y,z].  (head gs) is the required equation.   \n\n"++
      "gxBasis_test  is also applied that                        \n"++
      "  finds gs' = Groebner basis gs,                          \n"++
      "  tests the reduction of  fs by gs, gs' by gs, gs by gs', \n"++
      "  tests the transformation matrix fs -> gs                \n"
     )++
    ) . finsep . shows (fst gbasCone) 

  gbasBu12' = (("\n\nGroebner basis over a field.        \n"++
                "Small Buchberger's examples No 1, No2.  \n"++
                "gxBasis_test  applied as before.        \n"
               )++
              ) . finsep . shows (map fst [gbasBu1,gbasBu2]) 

  gbasCst' =
    (("\n\nGroebner basis over a field K.                        \n"++
      "The consistency conditions for the three generic quadratic\n"++
      "equations over K.                                         \n"++
      "fs = [x^2*a + x*b + c, x^2*d + x*e + f, x^2*g + x*h + l]. \n"++
      "Find  gs = GroebnerBasis(fs)  for the variables           \n"++
      "[x,l,h,g,f,e,d,c,b,a]  and lex  pp ordering, x > l >..> a.\n"++
      "gs  provides certain conditions on the values of  a..l for\n"++
      "the consistency of the system in extension of K.          \n"++
      "For example, the elements of  gs  constant in x,  should  \n"++
      "necessarily equal zero.                                   \n"
     )++
    ) . finsep . shows (fst gbasCst) 

  gbasCyclRoot' =
    (("\n\nGroebner basis over a field K.  Cyclic roots.       \n"++
      "fs = [x1 + x2 + ... + xn,                               \n"++
      "      x1*x2 + x2*x3 + ... + x(n-1)*xn + xn*x1,          \n"++
      "      ...                                               \n"++
      "      x1*x2..*x(n-1) + x2*x3..*xn +...+ xn*x1..*x(n-2), \n"++
      "      x1*x2..*xn - 1                                    \n"++
      "     ]                                                  \n"++
      "For  n = 2,3,5,  it appears that Ideal(fs)  has zero    \n"++
      "dimension (visible from [lpp g| g<- Groebner basis]).   \n"++
      "For the test, we take  n = 4:                           \n"
     )++
    ) . finsep . shows (fst gbasCyclRoot) 

  gbasMoe12' =
    (("\n\nGroebner basis over a Euclidean ring Z = Integer. \n"++
      (header "")++
      "Two examples from Moeller's papers.          \n"++
      "gxBasis fs, gxBasis fs'  for                 \n"++
      "fs  = [2*y*x^2 -17*y, 5*y^2*x -3*x],         \n"++
      "fs' = [7*x^2*y - 3*x, 4*x*y^2 - x*y, 3*y^3]  \n"++
      "- in Z[y,x], degLex pp ordering.             \n"++
      "The extended  gxBasis_test  is also applied. \n"
     )++
    ). finsep . shows (map fst [gbasMoe1,gbasMoe2]) 


  gbasOverP' =
    (("\n\nGroebner basis over a Euclidean ring X = K[x],  K a field\n"
      ++(header "")++
      "fs = [x^2*y^2 - z^2, x*y^2*z - x*y*z, x^3*y*z - x*z^2]    \n"++
      "reads to K[x,y,z] and to X[y,z]. The pp ordering is set so\n"++ 
      "that  x^k < y,z  for any k > 0.                           \n"++
      "Compute the Groebner bases  gs, gs' in these rings,  and  \n"++
      "check  gs==(map fromOverX gs'),  where                    \n"++
      "fromOverX: X[y,z] -> K[x,y,z] is the canonical isomorphism.\n"
     )++
    ) . finsep . shows (fst gbasOverP)

  syzAl' = 
    (("\n\nGroebner basis in the module P^2  over P = K[a,b,c,d],\n"++
      (header "")++
      "K a field,  and syzygies for a list of elements of P^2.   \n"++
      "Three small vectors in  P^2  are taken to  fs,            \n"++
      "set TOP e-comparison  for  P^2  represented by  VecPol.   \n"++
      "Then,  fst (gxBasisM _ fs) has to be certain [g1,g2,g3,g4]\n"++
      "- which is checked.                                       \n"++
      "The syzygy generators  rels = syzygyGensM _ _ fs  \n"++
      "has to be certain singleton - which is checked.   \n"
     )++
    ) . finsep . shows (tuple51 al) 

  syzCocoa' = 
    (("\n\nComparing Syzygies from CoCoA and DoCon. \n"++
      "Example from CoCoA manual of 1990.           \n"++
      (header "")++
      "In  fs = [f1..f7]  fi <- P = K[x,y,z,w],                  \n"++
      "fs  occurs a Groebner basis.                              \n"++
      "rels = syzygyGens _ fs  are the syzygies from DoCon,      \n"++
      "  - a list of vectors from P^7.                           \n"++
      "relsCo  are the syzygy generators computed by CoCoA.      \n"++
      "The submodule equality for  rels, relsCo  is verified.    \n"++
      "The TOP e-comparison is set on P^7 induced by the weights \n"++
      "[lpp f| f <- fs].  With this,  rels  also becomes a Groebner\n"
      ++"basis in P^7.  Hence, reducing  rels  mutually and finding\n"
      ++"the Groebner basis  relsCoG  for  relsCo,  we obtain    \n"++
      "relsReduced  and  relsCoG.  It is tested that the latters \n"++
      "coincide as the sets.                                     \n"
     )++
    ) . finsep . shows (tuple51 cocoa) 

  cyclicInt5' = 
    (("\n\nArithmetic of Cyclic Integer ring     \n"++
      "modelled via Groebner basis over Integer. \n"++
      (header "")++
      "The cyclic integers are the elements of   CI = Z[x]/(g),  \n"++
      "        g = x^p' + x^(p'-1) +..+ 1,   p'= p-1,  p prime.\n\n"++
      "It is known that  g = (x^p-1)/(x-1)   is irreducible.     \n"++
      "With DoCon, we can simply put  CI = ResidueI $ UPol Z.    \n"++
      "And this relies on the Groebner basis technique over an   \n"++
      "Euclidean ring Z.  Build Z[x]/(g)  and test the properties\n"++
      "(IsField,No),(HasZeroDiv,No).  Then, take, for example,   \n"++
      "some f, g and test the division and algebraic norm.       \n"++
      "Here, we put  p = 5,  f = 38*x^3 + 62*x^2 + 56*x + 29,    \n"++
      "                      g =  3*x^3 +  4*x^2 +  7*x +  1.    \n"++
      "  f  should be a multiple of  g,                          \n"++
      "  norm(f) should be a multiple of norm(g).                \n"
     )++
    ) . finsep . shows (tuple31 cyclicInt5) 

  cubeext' = 
    (("\n\ncubicExt a b dK   builds the radical extension tower  \n"++
      "                      k -- k(d) -- E = k(d)(u,v,r)        \n"++
      (header "")++
      "for the given field  k,  where E is generated by the roots\n"++
      "of irreducible   f = t^3 + a*t + b,                       \n"++
      "a,b from k, a /= 0.                                       \n"++
      "d,r,u,v  stand for the (square) root of discriminant,     \n"++
      "         root of -3,  Cardano cubic radicals.             \n"++
      "B = k(d)[u,v,r]  is built,  and  E = B/Ideal(eqs),        \n"++
      "where  eqs  are certain quadratic and cubic relations for \n"++
      "u,v,r  over k(d). \n"++
      "B/Ideal(eqs)  requires GroebnerBasis(eqs) to evaluate over\n"++
      "k(d). \n"++
      "The Cardano values x,y,z  for the roots of  f  are formed \n"++
      "in E.  And  (domainE, [x,y,z], kToE)  is returned.        \n"++
      "For this particular example,  cubicExt (1:/1) (-1:/1) dQ  \n"++
      "builds the extension of k = Q = Rational with t^3 - t + 1.\n"++
      "Then, the Viete relations are tested for  x,y,z.          \n"++
      "And certain interesting quadratic expression for y  via  x\n"++
      "over k(d)  is found - it should exist according to the    \n"++
      "extension dimension considerations.                       \n"
     )++
    ) . finsep . shows (tuple41 t_cubeext_) 

  sphGeo' =
    (("\n\nArithmetic of the field Q(S)  of rational functions on\n"++
      "sphere S:  x^2 + y^2 + z^2 = 1.                           \n"++
      (header "")++
      "Build  K = F[z]/(p),  with  p = x^2 + y^2 + z^2 - 1,      \n"++
      "F = Fraction Z[x,y].                                      \n"++
      "In particular,  1/(1+z)  should equal to  (1-z)/(x^2+y^2) \n"++
      "in K.  And this is tested.                                \n"++
      "The arithmetic in  F  requires gcd cancellation in Z[x,y],\n"++
      "and  F[z]/(p)  requires the Euclidean structure for F[z]. \n"
     )++
    ) . finsep . shows (tuple31 t_sphGeo_) 

  charKostka' = 
    (("\n\nSymmetric function transformation. \n"++
      (header "\n")++
      "Character matrix  C  for the permutation group  S(w),     \n"++
      "Kostka matrix  K(w),    w  the weight parameter.          \n"++
      (header "")++
      "For  C,  there are checked the orthogonality of rows,     \n"++
      "control sum.                                              \n"++
      "For  K,  there are checked the triangularity, control sum,\n"++
      "1 on diagonal, inverse(K).                                \n"++
      "This repeats for  w <- [2..8]                             \n"
     )++
    ) . finsep . shows charKostkaTest 

  discrSym' = 
    (("\n\nSymmetric function transformation.                    \n"++
      "Find  d = discriminant [x1..xn] = product [(xi-xj)^2 ...] \n"++ 
      "as polynomial over Q = Rational,                          \n"++
      "convert it to  dsym = toSymPol .. dsym :: SymPol Q,    \n"++
      "decompose  dsym  to elementary symmetrics:             \n"++
      "(to_e_pol mode.. dsym).                                \n"++
      "There are checked the results of these two conversions \n"++
      "- for  n = 3, mode = \"mn\", \"m\",                    \n"++
      "       n = 4, mode = \"mn\".                           \n"
     )++
    ) . finsep . shows discrSymTest 

  symMonToE' =
    (("\n\nSymmetric function transformation.                    \n"++
      "Decomposing symmetric monomial                            \n"++
      "                   m[jjj] = symmetricOrbit( x^j*y^j*z^j ) \n"++
      "into polynomial h <- Q[e1,e2..]  in elementary symmetrics \n"++
      "over Rational.                                            \n"++
      "ContorlSum(h) is checked for n = 3, mode = \"mn\", \"m\", \n"++
      "                             n = 4, mode = \"mn\".        \n"
     )++
    ) . finsep . shows symMonToETest 

  upolInterp1' = 
    (("\n\nUnivariate Polynomial Interpolation. \n"++
      "Small direct test.                       \n"++
      (header "")++
      "For a prime  p,  K = Z/(p),  f <- K[t],  deg f < p,       \n"++
      "take the values of f in  (deg f)+1  points, interpolate by\n"++
      "these values and compare the result to  f.  Here we take  \n"++
      "q = 11,  f = 1, 2*t+3, (2*t^2 +3*t +4)^3,  t^10 +t^9 +t   \n"
     )++
    ) . finsep . shows (fst interp)

  upolInterp2' = 
    (("\n\nUnivariate Polynomial Interpolation.                  \n"++
      "Finding Determinant over Polynomials via interpolation.   \n"++
      (header "")++ 
      "The idea is that for a  finite field K,  P = K[t],        \n"++
      "matrix M over P,  det M  costs much less when it is       \n"++
      "computed via interpolation  (instead of Gauss method with \n"++
      "repeated remainder division).                             \n"++
      "deg det(M)  is estimated by degBound found via deg M(i,j),\n"++  
      "degBound+1  values  det(i)  of  det(M(i)) compute over K, \n"++
      "and the polynomial  det(M)  is interpolated from  det(i). \n"++
      "If  degBound >= card K  then K  is extended to appropriate\n"++
      "K' - certain prime polynomial to be found!  Everything is \n"++
      "found over  K',  the result projected to  K[t].           \n"++
      "We apply this method to  det M,  M = resultantMatrix f g, \n"++ 
      "                                          f,g <- K[t][x], \n"++
      "det(M)  computed by interpolation is compared to  det(M)  \n"++
      "computed via Gauss method                                 \n"++
      "(in  T_detinterp.hs  you can also see how to run these    \n"++
      "methods separately to compare the cost).                  \n"++
      "Here we put                                               \n"++
      "K     = Z/(11)                                            \n"++
      "(f,g) = ((t+1)*x^2 + t^2*x + 2,      t*x^2 + 3*x^3 + t),  \n"++
      "        ((t^2+1)*x^4 + 3*x^3 + t^2*x^2 + t^3 +t + 2,      \n"++
      "                                  x^4 - (t+1)*x^3 + t^2*x)\n"++
      "- the second pair causes the extension of K.              \n"
     )++
    ) . finsep . shows (snd interp) 

  factor1overPrimeFin' =
    (("\n\nFactorization in K[t],  K= Z/(p) a prime finite field.\n"++
      (header "")++
      "factor (t^10 +t^7 +t^5 +t^3 +t^2 + 2*t + 2)  over Z/(5),  \n"++
      "factor (t^8+t^6+10t^4+ 10t^3+ 8t^2 + 2t + 8)  over Z/(13).\n"++
      "It is also known that  factor (t^(p^d) - t)               \n"++
      "has to be exactly all the irreducible polynomials  f  over\n"++
      "Z/(p),  with  d  a multiple of  deg f,  lc f = 1          \n"++
      "- test this for (p = 2, d<- [1..6]), (p=3, d<- [1..4]).   \n"
     )++
    ) . finsep . shows factor1overPrimeFin 

  factor1overGenFin' = 
    (("\n\nFactorization in  K1[x],  K1  a generic finite        \n"++
      "extension of a prime field K = Z/(p),                     \n"++
      (header "")++ 
      "K1 = K[t]/(g)  for the chosen irreducible  g  over K.     \n"++
      "Here we take  p = 5,  g = t^3 - t - 2                     \n"++
      "and test the factorization of polynomials f1,f2,f3.       \n"++
      "f1 = t^10 + t^7 + t^5 + t^3 + t^2 + 2*t + 2   over K1,    \n"++
      "  starts to factor as f1 over K (from the previous test), \n"++
      "  only the factor  x^3-x+3  splits further to the linear  \n"++
      "  factors over K1.                                        \n"++
      "f2 = x^10 + 2*t*x^5 + t^2 + 2                             \n"++
      "  factors to certain [(h,5)], because f= sum [ak*x^(5*k)] \n"++
      "  and each  ak(t)  is a 5-th degree in K1.                \n"++
      "f3  is certain large polynomial (see T_pfactor.hs)        \n"
     )++
    ) . finsep . shows factor1overGenericFin 

  factor2overPrimeFin' =
    (("\n\nFactorization in  K[x,y],  K = Z/(p) a prime field.   \n"++
      (header "")++
      "First, take different irreducible f,g, small in total deg \n"++
      "And test  [factor (f^i*g^j) |  0 < i, j < bound].         \n"++
      "Here, we take  f = x^3 + y*(x + 1),                       \n"++
      "               g = x^3 + y*(y*x^2 + 2),                   \n"++
      "               (i,j) <- [(0,1),(1,0),(1,1),(1,2),(2,1)].  \n"++
      "Second test.                                              \n"++
      "Take a prime  b <- [0..p-1],  p <- K[t],  n = 3,4, ...  \n\n"++
      "gs = [p^(n-1)*x^(n-1) + (a+b)*y*x^(n-2) + (a-b)*p^2*x +a |\n"++
      "      a <- [1..(q-1)] ],                                  \n"++
      "irreds = [x^n + p*g | g <- gs]                            \n"++
      "        - all of them irreducible by Eisenstein condition,\n"++
      "fs = [g*h | g,h <- irreds]                                \n"++
      "  - fi have  deg_x fi = deg_y fi = 2*n  and have to factor\n"++
      "  to above pairs of the elements of  irreds.              \n"++
      "Here we take   b = 1,  p = y + b,   n = 3, 4, 5           \n"++
      "and first 2 of the  fs  factorizations.                   \n"++ 
      "W A I T, \n"++
      "this may take a couple of minutes: \n"
     )++
    ) . finsep . shows factor2overPrimeFin





{- Statistics  -----------------------------------------------------


Note: 
we have to take in account that, in rare cases, the example set, and
parameters, may change from version to version.

---------------------------------------------------------
docon-2.09-pre-July-21-2005,   ghc-6.4.1-pre-July-10-2005
docon compiled with -0,  tests compiled with -Onot.

./a.out  for Main  on  512 Mb memory takes  36 seconds.

--------------------------------------------------------------------
-}