\documentclass[12pt]{article}
%
\usepackage{amsfonts}
%
\renewcommand\baselinestretch{1.2}  
%                                  increase skip between lines
%
\font\dsr=dsrom10
\def\R{\mbox{\dsr R}}
\def\N{\mbox{\dsr N}}
\def\Q{\mbox{\dsr Q}}
\def\Z{\mbox{\dsr Z}}
%
\def\mod{\mathop{\rm mod}}
\def\lc{\mathop{\rm lc}}
\def\lm{\mathop{\rm lm}}
\def\lpp{\mathop{\rm lpp}}
\def\cont{\mathop{\rm cont}}
\def\resultant{\mathop{\rm resultant}}
\def\logD{\mathop{\rm logD}}
\def\mod{\mathop{\rm mod}}
%
\addtolength{\oddsidemargin}{-15mm}
\addtolength{\evensidemargin}{-15mm}
\addtolength{\textwidth}{30mm}
\addtolength{\textheight}{40mm}
\addtolength{\topmargin}{-10mm}
%
\begin{document}
\thispagestyle{empty}
\vspace*{40mm}
\begin{center}
 {\bf\LARGE  D o C o n}                              \\ \vspace{10mm}
 {\bf\LARGE  The \ Algebraic \ Domain \ Constructor} \\ \vspace{10mm} 
 {\bf\large  V e r s i o n \ \ 2.11 }                \\ \vspace{20mm} 
 {\bf\LARGE  U s e r \ \ M a n u a l }               \\ \vspace{30mm} 
 {\bf\large  Serge \ Mechveliani}                    \\ \vspace{5mm}  
 {\bf\large  Pereslavl - Zalessky, \ \ 2007.}               
\end{center}
\newpage
\newpage
\tableofcontents






\newpage
\section{Introduction}
% --------------------
\label{sec-i}
  
\subsection{Aim}
% --------------

The first attempt with {\tt DoCon} program \cite{Me1} dates of 1989.  
The reason for starting the project was absence of any freely
available, powerful and generic enough tool for programming 
mathematics.

The aims of the {\tt DoCon} project are
\begin{itemize}
\setlength\itemsep{0pt}
\item to provide the author himself with the computation tool based 
  on categorial approach and functional programming,
\item to make this approach to mathematical computation programming
  freely accessible, comprehensive and transparent at all design 
  levels.
\end{itemize}

Now, it starts a long introduction. But 

(1) read first the paper \cite{Me2} to get the general author's 
  idea about the relation of {\tt Haskell} to computer algebra,

(2) Section \ref{sec-prp.ske} formulates briefly the whole {\tt DoCon} notion.
\\
So, if the reader is familiar with the {\tt Haskell} type classes and 
wants to know immediately what really  {\tt DoCon} is,  one  should  skip 
directly to the Section \ref{sec-prp.ske}.
\medskip

The following example is for  the  readers  not  familiar  with  the 
``categorial'' kind of CA programs. It shows what it is possible to do
with the CA system based on the category principle.  Suppose we have 
to represent symbolically an algebraic surface, say a sphere 
$$
                   S: \ x^2 + y^2 + z^2 = 1 
$$
in the rational space $\Q^3$.  It is known that the  geometry  of  a
surface of such kind is given by the field \ $K = \Q(S)$  \ 
of rational functions on  $S$. Mapping the rational coordinates \ 
$x$, $y$  \ to  $S$  and defining  $z$  by an algebraic equation 
over  $\Q(x,y)$  we express $K$ as a composition of the functors \ 
Polynomial, Fraction, Residue ring: 
\footnotesize
\begin{verbatim}
           Q(x,y) = Fraction (Z[x,y]);
           K      = Q(x,y)[z]/(p);     p = x^2 + y^2 + z^2-1.
\end{verbatim}
\normalsize
After scripting this in {\tt DoCon} constructors {\tt DoCon} evaluates expressions 
like 
\begin{center}     \verb# (1+z)*(1-z)/(x^2 + y^2)  :: K #
\end{center}
\normalsize
being able convert them automatically to canonical form and do the 
arithmetic operations on them.
So, applying the constructors we build automatically  the  algebraic 
representation of such surface.

The implementation idea for this is that any domain constructor 
{\it C} is considered as a functor that builds certain  standard  
algebraic algorithms for the result domain starting with appropriate 
algorithms for the argument domains.
For example, ``to program polynomial arithmetics'' means  to  relate
the above functors to the constructor {\tt Pol}. Given the arithmetic 
and certain other algorithms for the domain {\tt R}, these functors 
build certain subset of the aforementioned algorithms for the domain 
{\tt (Pol R)}.

The representation and processing mechanism for an algebraic  domain 
depends on the programming tool.
{\tt DoCon} applies the \ {\tt Haskell} \ language \cite{Ha,HFP} for this and 
models a category mostly as a {\it class}, a domain --- as several 
{\it class instances}, together with certain explicit domain terms.


\subsubsection{Acknowledgements}
% ------------------------------

The author is grateful to 
\begin{itemize}
\setlength\itemsep{0pt}
\item  Dr. S.V.Duzhin \ 
       for his administrative support during many years,

\item  Marc van Dongen  (Cork College, Ireland) \\ 
       for the consultation on Gr\"obner bases and programming matters,

\item  Russian Foundation for Basic Research: \\ 
       in 1998-99  {\tt DoCon} was the part of the project supported by
       the grant No 98-01-00980,

\item  INTAS foundation of European Community: \\
       in 1995-96  {\tt DoCon} was the part of the project supported by 
       INTAS grant (coordinator Professor B.Jacob),

\item  Computer Algebra Center MEDICIS: \\
  Unite' Mixte de Service 
  (under the supervision of CNRS and Ecole Polytechnique) \\
  \verb#<http//www.medicis.polytechnique.fr># \\
  for kindly making it possible to compare {\tt DoCon} and other CA 
  systems at the same machine (Section \ref{sec-pe}).
\end{itemize}



\newpage
\subsubsection{ Programming language }
% ------------------------------------
\label{sec-i.lg} 

The main {\tt Haskell} language \cite{Ha} features are
\begin{itemize}
\setlength\itemsep{0pt}
\item Typed lambda calculus machine as the basic computation model.
      The program compiles into something like typed lambda
      expression and runs by reducing to the head normal form.

\item `Pure' functionality.
\item High order functions (consequence of lambda model).
\item Pattern matching. 

\item `lazy' (non-strict) evaluation 
      --- the head normal form computation strategy.

\item Polymorphic values. \\
    The type of expression is defined by the constructors  and  type
    parameters. Say \\ 
    \verb#Ord a => (Char, [a], U a b)# 
    \\  
    defines the type of triplets with the components of different 
    types depending on parameter types \ {\tt a}, {\tt b}, \  
    where {\tt Char}, {\tt []} \ are the standard constructors 
    for Character and \\
    {\tt List}, \ {\tt U} introduced by the user.

\item Recursive type descriptions. Example:  \\
      \verb# data Tree a = Leaf a | Node a (Tree a) (Tree a) #

\item Strong static typing: \ the types are resolved at the compilation stage.

\item Data classes and instances. \\
      This is something to replace the object oriented programming. \\
      Mathematically, it is similar to joining algebraic domains 
      into categories.
\end{itemize}

See \cite{HFP} as the introduction into programming in 
{\tt Haskell}.

{\tt Haskell} belongs to the so-called {\tt Miranda} family of 
languages.
\medskip

({\tt Miranda} is a trademark of Research Software Ltd.)
\medskip

The particular features of the language are discussed specially in
the Section \ref{sec-i.lg1};  the summary of further requirements  
to the language is given in Section \ref{sec-lne}.  
We also hope for the future extended versions of the language and  
its implementations.

{\tt DoCon} is programmed in what we call here {\tt Haskell-2-pre}.

{\tt Haskell-2-pre} === 
                 {\tt Haskell-98} + Extension (functional).

{\tt Haskell-98} \ is the standard accepted in January 1999 \cite{Ha}.

{\tt Haskell-2}  \ is the future language extension project, is under a
                   (long) discussion.

{\tt Haskell-2-pre} \ is the subset of the language that was implemented 
                      in 1990-ties by at least two systems.

Extension === \\
  (mp)       multi-parameter classes,  \\
  (oi)       overlapping instances, \\
  (\verb#*#) composed data constructors and repeated type variables in 
             the instances.
\medskip

Example with (mp): 
\begin{center}
          {\tt class (AddGroup a, Ring r) => LeftModule r a where} \ldots
\end{center}
Example with (oi): 
\footnotesize
\begin{verbatim}
    instance GCDRing a => Ring (Fraction a)       where ...
    instance              Ring (Fraction Integer) where ...
\end{verbatim}
\normalsize
%
Here the second instance defines some operations in a more special 
way, since \ {`a = Integer'} \ tells more than only \ 
{\tt GCDRing a}. \ Similarly, the domain attributes for the type \\
\verb#EuclideanRing a => ResidueE a# \ \ \
can be computed more precisely for the special case of \ \  
\verb#a = Field k => UPol k#
\medskip
    
{\bf Libraries used:}
\\
Among the non-standard libraries, {\tt DoCon} imports \ \ 
{\tt Data.Map} \ and \ {\tt Debug.Trace} 
\\
(see documentation on \cite{GH}).
We hope, \ {\tt Map} \ will become standard in future {\tt Haskell}.

From \ {\tt Debug.Trace}, \ {\tt DoCon} uses only the function \ 
{\tt trace}. \ This usage is very slight: for some {\tt DoCon} 
functions it is appropriate to issue intermediate messages, if the 
corresponding mode is given. 



\newpage
\subsection{ Current {\tt DoCon} abilities }
% ------------------------------------------
\label{sec-i.abil} 

{\bf Mathematical library:}
%
\begin{itemize}
\setlength\itemsep{0pt} 
\item Permutation group: composition, inversion, decomposition to 
      cycles.
\item Fraction field over a gcd-ring: arithmetic.

\item Linear algebra over an Euclidean domain: 
  vector, matrix arithmetic (dense form), \\
  reduction to staircase and diagonal form of matrix, solving a system.

\item Polynomial arithmetic in $P = R[x_1,\ldots,x_n]$, \ $R$ a 
  commutative ring. Possible models for $P$, \ free module over $P$, \ 
  symmetric functions over $R$ \ are unified into the \\ 
  {\tt class PolLike} \ and are presented by the constructors \\
  {\tt UPol} \ (sparse univariate polynomial), \\
  {\tt Pol}  \ (multivariate polynomial with dense power products), \\
  {\tt RPol} \ (``recursive'' form), \ \ {\tt EPol} \ (vector over P), \ \  
  {\tt SymPol} \ (symmetric).

\item g.c.d. in $R[x_1,\ldots,x_n]$, \ 
      $R$ a factorial ring with given {\tt gcd} function.

\item Gr\"obner basis, \ normal form, \ syzygy generators functions for \  
  $P = R[x_1,\ldots,x_n]$, \\
  $R$ an Euclidean ring, \ and in a free module over $P$ \ \cite{Bu,Mo,MoM}.

\item Some items for non-commutative polynomials over a commutative ring:\\
      arithmetics, reduction to normal form, some others.

\item Symmetric function package and partition operations \cite{Ma}.

\item Factorization in \ $k[x,y]$ \ for a finite field $k$ \ 
  \cite{CG,Me3}, \ building finite extension of \\
  $k$ \ of given dimension, \ Hensel lift in $R[x]$ for an Euclidean $R$.

\item Special interpolation technique for $k[x]$, \ $k$ a finite field,\\
      its application to determinant computation over $k[x]$.
\end{itemize}
\medskip

{\bf Category hierarchy expressed partially via the data classes:}
%
\begin{itemize}
\setlength\itemsep{0pt} 
\item {\tt Set}, {\tt Semigroup}, {\tt Group}, {\tt Ring}, 
      {\tt LinSolvRing} \ldots \ {\tt LeftModule} \ldots
\item some operations with the description terms of {\tt Subset},  
      {\tt Subgroup}, {\tt Subring}, {\tt Ideal} \ldots 
\end{itemize}
\medskip

{\bf Domain constructors:}
%
\begin{itemize}
\setlength\itemsep{0pt} 
\item {\tt Permutation}. 
\item {\tt Fraction} field for a gcd-ring.

\item Direct product of Sets, (semi)Groups, Rings, \\
      Free (vector) module over a ring.

\item {\tt Matrix} algebra over a commutative ring.

\item {\tt Polynomial} algebra over a commutative ring: \\
      {\tt UPol}, {\tt Pol}, {\tt RPol} \ models.

\item {\tt Vector} module over a ring P, in some cases, with the 
      Gr\"obner bases structure.

\item {\tt Residue} ring by an ideal: \\
      {\tt ResidueI}, {\tt ResidueE} \ 
      models for the generic and Euclidean cases.
\end{itemize}
\medskip

{\bf Property processing:}

evaluation of certain small set of the most important  algebraic 
domain property values is supported, such as \ \ 
{\tt Finite}, {\tt IsCyclicGroup}, {\tt IsMaxIdeal}, 
{\tt Factorial} (ring), \ and such. \\
They serve as correctness conditions for various methods, 
are used to determine dynamically the membership to categories, and
also present an important information by themself.



\subsection{ Examples of possible contribution }
% ----------------------------------------------
\label{sec-i.ctr} 

The scientific library described in previous subsection has to grow. 
It is a good idea to write a package, consistent with {\tt DoCon},
adding some methods. Let us list the tasks, that we would like to 
program in the first order.
%
\begin{itemize}
\setlength\itemsep{0pt} 
%
\item {\bf (an)} 
      Setting interface to some freely available advanced 
      computational number theory library (maybe, by Lenstra).\\
      This will join many efficiently implemented methods, such as 
      for large integer factorization, for integer extensions, 
      and others. 

\item Permutations implemented via binary trees (for large sets).

\item Chinese remainder method for GCD in $\Z[x]$, $R[x_1,\ldots,x_n]$
      (so far it is done only for $k[t][x]$, $k$ a finite field).

\item Chinese remainder method for various tasks, like solving 
      systems, etc.

\item Gr\"obner bases: optimizations for syzygies, Gr\"obner walk, 
      change of Gr\"obner basis, and such.

\item Factoring in $R[x_1,\ldots,x_n]$ for generic enough $R$. \\
      Primary decomposition of ideal in $R[x_1,\ldots,x_n]$. \\
      Efficient methods for Primitive element and other attributes
      for a field extension.

\item Fraction ring by a multiplicative subset, \ 
      local ring by a prime ideal.

\item {\bf (tr)} Term rewriting, prover based on it, AC-completion,
                 and so on.
\end{itemize} 


\underbar{{\bf Remark on (tr)}} 

It can be based on the conditional term rewriting, various versions of 
unfailing completion procedure, equational prover.

Currently (2007) the author is developing such a library ({\tt Dumatel})
aiming to link it to {\tt DoCon}. We have implemented the many-sorted 
(unconditional) term rewriting, completion, AC-completion, with 
extention to Boolean terms, proof search in the predicate logic via 
this completion, inductive prover, with a certain proof search strategy, 
and with heuristics for the lemma invention.

And there always remains a huge space for the contributions in this area.

Also there are possible various optimizations in {\tt DoCon}. 
\medskip



\underbar{{\bf Performance comparison}}

The Section~\ref{sec-pe} presents certain bit of this, relatively 
to {\tt Axiom} \cite{Al,Je} and {\tt MuPAD} \cite{Mu} programs. 
\medskip

({\tt Axiom} is a trademark of the Numerical Algorithms Group Ltd.)
\medskip

But any further experiments would be interesting.





\subsection{ Comparing it to other CA systems. On Aldor, Axiom}
% -------------------------------------------------------------
\label{sec-i.cp} 

The first profound categorial approach to programming of mathematics
had started before 1980 and has grown into the {\tt Aldor} language 
\cite{Al} and {\tt Axiom} system \cite{Je}.
 
{\tt Axiom} can be considered as a large algebraic library for 
{\tt Aldor}. \\
In 2002, {\tt Axiom} was said being rewritten to {\tt Aldor}.

And it looks like {\tt Axiom} has somewhat out of date language.

{\tt Aldor} is a language somewhat similar to {\tt ML}, with some 
respects --- to {\tt Haskell}. But it is extended with the  
{\it dependent types} feature.

The algebaic domains are represented as {\it abstract data types}.
The (abstract) types  can be treated as  regular {\it values}  and
their resolution can be delayed to the run-time.

{\tt Aldor}  is non-functonal and `strict'. 
{\tt Aldor} has separated from the {\tt Axiom} system in about 2000.
Before this event, it was hard to understand where in {\tt Axiom}  
was a language and where a library.

We think, the CA language and system developers and implementors have 
now a task to provide a tool which 
\begin{itemize}
\setlength\itemsep{0pt} 
\item  has the main part of {\tt Aldor} paradigm (like dependent types),
\item  is functional, `lazy' and elegant as {\tt Haskell},
\item  is extended with some library for term rewriting, completion,
       equational reasoning,
\item  has several implementations distributing freely with source. 
\end{itemize}

The {\tt Cayenne} language \cite{Au} steps in this path, but it 
needs some extension and reliable implementation. 

Such a rich type system as {\tt Aldor}'s is `undecidable'. 
But it is not neccessary to solve all types at compilation time.
Some of them can be solved at the run-time.

Here are the main points of DoCon difference with respect to 
{\tt Aldor}-{\tt Axiom}.
%
\begin{itemize}
\setlength\itemsep{0pt} 
%
\item {\tt DoCon} is a library for {\tt Haskell} written in {\tt Haskell}. 
      \\
      {\tt Axiom} is a library for {\tt Aldor} written in {\tt Aldor}.

\item {\tt DoCon} applies functional programming and `lazy' evaluation 
      --- a consquence of using {\tt Haskell}. 
      
\item {\tt DoCon} uses the so-called sample argument approach to replace the
      dependent types tool of {\tt Aldor}, in particular ---     
      to model a domain depending on a dynamic value.
      This leads to some complications in architecture.

\item {\tt DoCon} has a comparably small library of algorithms, 
      certain part of commutative algebra (it has to develop).

\item {\tt DoCon} distributes freely with source, as well as {\tt Haskell}
      implementations do. \\
      In 2003 {\tt Axiom} was announced as open-source and free.\\
      In April 2002 {\tt Aldor} has become freely-executable \\
      (but not open-source). 

\item {\tt Haskell} has 2-3 reliable implementations.\\
      {\tt Aldor} has one, and we have to test its reliability.
\end{itemize}

The  {\tt Weyl}  program, as it is described in \cite{Zi} in 1993,  
looked like developing in the similar directions --- from algebraic 
point of view. Though {\tt Common Lisp}, its object system, bring in
a very different programming style and architecture.

The {\tt MuPAD} system \cite{Mu} claims that it supports the domains
and categories. The \verb#C++# language for the kernel and the 
{\tt MuPAD} language, its {\it procedures} and other features, show 
that this system is not functional, and again, assumes a very 
different programming technology.

Recalling the situation of about 2000, the advanced release of 
{\tt MuPAD} was commercial. We do not know what is the current status,
what open-source release is available.

Not only {\tt DoCon} experiments with the {\tt Haskell} application to  
algebra. Thus, \cite{Fo,Ka} describe certain plain approach to the 
subject. 

Also it is a good idea to read a paper \cite{Me2} before dealing 
with {\tt DoCon}.

The main architecture points relatively to \cite{Fo} are: 
\begin{itemize}
\setlength\itemsep{0pt} 
%
\item In {\tt DoCon}, the Set of a domain is not only a type, 
      it is defined also by the so-called base set term.

\item {\tt DoCon} can do some operations with the domain description terms.

\item {\tt DoCon} operates with the residue group and residue ring
      elements and provides in certain generic case a canonical map 
      modulo subgroup, ideal (so far, for the commutative case only).

\item For some reasons, {\tt DoCon} treats the \ zero, unity, 
  characteristic, and other constants of a domain {\tt `a'} not as 
  formal constants, --- say \ \verb#zero :: a#, \ --- but as the 
  maps, say \ \verb#zero :: a -> a#, \ with sample argument.
  Though, each such function has actually to be constant
  (Section \ref{sec-prp.ske}, SA).
\end{itemize}




\subsection{ More on programming language }
% -----------------------------------------
\label{sec-i.lg1} 

The {\tt Haskell} language is a comprehensive tool for scientific 
programming (far from being perfect, though). 
A general scheme for the user for such programming in 
the {\tt DoCon} package environment is to set the algorithms in 
{\tt Haskell} importing {\tt DoCon} entities from {\tt DoCon} interface 
(or its library).

But one needs to take in account certain particular properties of
{\tt Haskell} language.
\medskip

\underbar{{\bf Functionality, `laziness' and efficiency}}
\medskip

{\tt DoCon} exploits a non-strict computation,  for this helps to  write 
clear programs.  For example, the function for the staircase form of 
matrix returns 
\begin{center}       {\tt (s, t, sign)},
\end{center}
where \ {\tt s} \ is the resulting staircase matrix, \ \ \ 
{\tt t} \ the transformation matrix, \\
{\tt sign} \ the row permutation sign of transformation.  

If the program does not use further the variables \ 
{\tt t}, {\tt sign}, \ then the whole corresponding subtree of 
computation would never perform.

If evaluation was strict (as, say in Common Lisp) we would have
to provide extra (faster) function for the case when \ {\tt t} \ 
is not needed.  There are other examples when a non-strict  
evaluation helps to bring more clarity to the program. 

But we have to pay for the advantage.  For a long time, no efficient
implementations for `lazy' languages were known. In 1990-ies, a 
significant progress has been achieved, maybe, due to implementation 
of the so-called graph reduction model of evaluation \cite{Jo,FH}.

Also many people consider pure functional programming as impractical, 
saying there is a necessity to use a pointer, to update a list 
``in place'' or introduce a mutable array. 

Concerning this, {\tt DoCon} insists on the total functionality and tries 
to prove that the advantages cost the restrictions. 
And the Section~\ref{sec-pe} reveals a good practical performance 
test.

Among usually mentioned benefits of functionality, we stress the 
one that we consider as the most important: \\
a functional program, when it is brought to the kernel language,  
is an explicit symbolic expression 
(compare it to polynomial in mathematics) 
which is transformed step by step to the `reduced' expression --- 
even if not all of arguments are given.

Similarly as \ $(x+y)*(x-y)$ \ ``simplifies'' to \ $x^2-y^2$ \
in algebra, the program term is simplified by the interpreter 
(and partly, by the compiler) to another, equivalent one.  
This provides a large  field for automatic symbolic optimization of 
programs.

The main point here is: \\
the programs defining the same mathematical data map should be 
considered as equivalent \\
--- this should be the intention of a functional tool. 

Most `functional' systems (and Haskell) do not satisfy this property
in full. 
This is why we take sometimes the words `purely functional' in 
quotes.

The reader may ask: ``how a real program can be functional,
when input and output of the data is a side effect?''

We think that a program can be ``less functional'' or 
``more functional''. And qualify {\tt DoCon} as functional, because it is
itself free of side effects. The user program \ P \ that computes
something with {\tt DoCon} and  outputs  the result is almost functional.
Because the most part of the program  \ P + {\tt DoCon} \ can be a
subject of symbolic simplification. 
\bigskip

\underbar{On period and dollar denotation}

In the sequel, we apply in Haskell programs the usual Haskell 
denotations of \ \ \verb#`.'# \ \ and \ \ \verb#`$'# \ \ 
for the composition of fuctions and fuction application respectively.
This helps to write many composition levels with less parentheses.

{\bf Example.}

  \verb#map (+1) . map (^2)  :: [Integer] -> [Integer]# 
\\
means composing the above two maps on integer lists. Thus, 

  \verb# (map (+1) . map (^2)) [1,2]      :: [Integer]  --> [2,5], #

  \verb# sum $ map (+1) $ map (^2) [2,5]  :: Integer    --> 31 #
\bigskip


\underbar{{\bf Illustration for `laziness'}}

The below example with the generating of the infinite list of primes
and its re-use bases on the `lazy' evaluation principles.

This program is elegant, but we note that for the large numbers, 
there exist more efficient methods.
%
\footnotesize
\begin{verbatim}
  primes' = s [2..]  :: [Int]                           -- sieve method
            where
            s (p:ns) =  p: (s (filter (notm p) ns))
            notm p n = (mod n p) /= 0     -- "n is not a multiple of p"

  p n = primes'!!(n+1)                                  -- (P1)
        -- (primes'!!n, primes'!!(n+1))                 -- (P2)
        -- (primes'!!n, primes'!!(n+1), primes'!!500)   -- (P3)
\end{verbatim}
\normalsize
%
For example, to compute \ {\tt (p 1000)}, \ 
{\tt primes'} evaluates as follows:
\footnotesize
\begin{verbatim}
  2: (s (filter (notm 2) [3..]))        = 2:(s $ filter (notm 2) [3..])
  2: (s (3:(filter (notm 2) [4..])))
  2:3:(s$  filter (notm 3)$ filter (notm 2) [4..])
  2:3:(s$ filter (notm 3)$ (5:(filter (notm 2) [6..])))
  2:3:(s (5 :(filter (notm 3)$ filter (notm 2) [6..])))
  2:3:5:(s$ filter (notm 5)$ filter (notm 3)$ filter (notm 2) [6..])
  ...
\end{verbatim}
\normalsize
An important point: how much may differ the computation costs of 
expressions {\tt (P1)}, {\tt (P2)}, {\tt (P3)} ?

{\tt DoCon} relies only on such (reasonable) systems in which {\tt (P2)}, 
{\tt (P3)} do {\it not} cost any essentially more than (P1).

And why {\tt (P2)}, {\tt (P3)} are not likely to cost essentially
more than {\tt (P1)} ?

First, the {\tt (!!)} function invocates not more than 3 times,  
and this costs much less than the whole program.
Second, the first (n+1) values in {\tt primes'} needed in {\tt (P2)}
for the first component of the pair also participate in evaluation  
of the second component; the variable (value) {\tt primes'} being 
copied. Then, the interpreter re-uses these values --- this is 
``sharing''. Commonly, this happens when some program variable \  
{\tt u} \ computes as some simple expression of \ {\tt v}.  
Then the value of {\tt v}, if ready, is re-used to find \ 
{\tt u}.  If \ {\tt v} \ is not needed for the result (not
referenced from other data), then its value joins the ``garbage''.

{\tt DoCon} assumes the programming style in which the expressions like
{\tt (P2)}, {\tt (P3)} \ may often appear. 
This makes the programs more clear.
\bigskip

{\bf But there is also unneeded laziness.}
\medskip

For example, the program \ \ {\tt maximum [1..b]}, \ \ where
%
\footnotesize
\begin{verbatim}
  -- the below is taken from Standard Prelude

  maximum [] = error "maximum [] \n"
  maximum xs = foldl1 max xs

  max x y = if  x < y  then y  else x

  foldl1 f (x:xs) = foldl f x xs
  foldl1 _ []     = error "foldl1 _ [] \n"

  foldl f z []     = z
  foldl f z (x:xs) = foldl f (f z x) xs
\end{verbatim}
\normalsize
%
requires, in many implementations, the stack size proportional to \ 
{\tt b} \ to find \ {\tt maximum [1..b]}.

Because evaluating it really ``lazily'', produces the data sequence
\footnotesize
\begin{verbatim}
   foldl1 max [1..b]  =
   foldl max 1 [2..] =
   foldl max (max 1 2) [3..] =
   foldl max (max (max 1 2) 3) [4..] =
   ...
\end{verbatim}
\normalsize
That is the iteration style program may occur ``recursive'' when 
computed lazily. Here the list \ {\tt [1..b]} \ unwinds lazily 
all right, but the nested delayed \ {\tt max} \ applications are 
accumulated eagerly.

Changing the evaluation strategy, the interpreter might compute this
so that neither the list \ {\tt [1..b]} \ nor the \ {\tt max} \ 
application terms grow more than to one cell.
But it requires a compiler of infinite intellect to find such 
strategy change in generic case.

At this point, we soothe ourself with the following considerations.
%
\begin{itemize}
\setlength\itemsep{0pt}
%
\item The evaluation cost is \hspace{45mm}     $ R + C \cdot A, $
  \\
  where \ $R$ \ is the number of ``reduction steps'', \\
  $A$ \ number of cell allocations (for new data), \ \ \ 
                                                   $C$ \ a constant. \\
  And in the above example, the ratio of the lazy evaluation cost to
  the best strategy one is \ \ $ (b + C \cdot b)/b = \ 1+C $ \ \ 
  --- a constant. That is the best strategy costs near the same as the 
  purely lazy one. Only the space expenses may sometimes turn into the  
  proportional time ones. If this is not a generic law, then it would 
  be of great interest to observe any contra example.

\item In easy cases, as the aforementioned \ {\tt maximum}, it is not 
      too hard for the compiler to improve the unneeded laziness.

\item The practical average thrust of unneeded laziness does not 
      look great --- see the examples in Section~\ref{sec-pe}.
%
\end{itemize}





\newpage
\section{ Getting started }
% -------------------------
\label{sec-start}  

Here follow some simple examples of how to arrange work with {\tt DoCon}.

First, as the file  \ \ {\tt install.txt} \ \ says, `make' {\tt DoCon}
and run the test. It shows many things, and looking into the modules
\begin{center}
                   \verb# .../demotest/T_*.hs #
\end{center}
you get an impression of how to set computation. 

Nevertheless, we give

\subsection{ Starting example 1 }
% -------------------------------
\label{sec-start.1}  

{\footnotesize
\begin{verbatim}
  module Foo where                                 -- in the file  Foo.hs
  import Categs     (Factorization        )  --
  import RingModule (FactorizationRing(..))  --
  import Z ()                                --

  f :: Integer -> Factorization Integer      -- just define some function
  f    n =  factor (n + 2)  
\end{verbatim}
}
%
Here the three lines of \ {\tt `import'} \ can be replaced by a 
single one:
\begin{center}       {\tt import DExport}
\end{center}
, which means ``import all the DoCon interface''.


\subsubsection{`Making' executable and running}
\label{sec-start.1.mk}  

To use the above program create the file {\tt Main.hs}:
{\footnotesize
\begin{verbatim}
  module Main where 
  import Foo (f)
  
  main = putStr str   
         where          -- example of setting the head function
         n   = 10       -- edit this

         str = concat ["f ", shows n " = ", shows (f n) "\n"]
\end{verbatim}
}

To `make' and run this program under the \verb#GHC-6.6.1# system, 
command
{\footnotesize
\begin{verbatim}
  ghc $doconCpOpt --make Main 

  Main +RTS -M20m -RTS
\end{verbatim}
}
This prints: \ \ {\tt f 10 = [(3,1),(2,2)]}.

\verb#`+RTS -M... -RTS'# \ \  
means restricting the space size for computation.

For this example, \ and also for the whole this manual, \ 
we presume that the \ {\tt docon} \ {\it package} is installed 
following the guide \ {\tt install.txt}, \ 
and (according to this guide too) the environment variables are set:
{\footnotesize
\begin{verbatim}
  setenv doconSource  ... <path to the DoCon directory .../source>
  setenv doconCpOpt   "-fglasgow-exts -fallow-overlapping-instances          \
             -fallow-undecidable-instances -fno-warn-overlapping-patterns    \
             -fwarn-unused-binds -fwarn-unused-matches -fwarn-unused-imports"
\end{verbatim}
}
Thus, our command \ \ \verb#ghc $doconCpOpt --make Main# \ \  
uses this environment variable. Also it uses that {\tt ghc} will find
the {\tt DoCon} interface and object library according to the configuration
for the \ {\tt docon} \ package set in the file \ 
{\tt .../source/docon.cabal}.
\medskip

Note: it does not matter here in what directory the file {\tt Foo.hs} 
resides. Of course, it is better to put a user program apart from the 
{\tt DoCon} source.


\subsubsection{Interpreting the program}
\label{sec-start.1.interp}  

To run this program by the interpreter of the \verb#GHC-6.6.1# system, 
command, for example,
{\footnotesize
\begin{verbatim}
   ghci  -package docon   Foo   +RTS -M20m -RTS
   ...
   Foo> :set +s
   Foo> f 10
   [(3,1),(2,2)]
   (0.01 secs, 0 bytes)
   Foo>
\end{verbatim}
}
Here \ {\tt ghci} \ is the interpreter and interactive system of GHC, 
\medskip

Using compiled module:  
{\footnotesize
\begin{verbatim}
  ghc -c $doconCpOpt Foo.hs
  ... 
  ghci -package docon  Foo  
  ...
\end{verbatim}
}
Compiling from under {\tt ghci} is done by
{\footnotesize
\begin{center}  \verb# ...> :! ghc -c $doconCpOpt Foo.hs #
\end{center} 
}          



\newpage
\subsection{ Starting example 2 }
% -------------------------------
\label{sec-start.2}

This program gives a more definite idea of how to program in DoCon. 
It
\begin{itemize}
\setlength\itemsep{0pt}
\item builds integer matrix {\tt M} of size \ 3 x 6;

\item finds the generic solution of equation \ {\tt M*x = 0} \ 
      over the ring \ {\tt Z} \ of integers;

\item adds rows to \ {\tt M} \ to obtain the square matrix \ {\tt M'};

\item makes a rational matrix \ {\tt qM'} \ by mapping \ \verb#:/1# \ 
      to the elements of \ {\tt M'};

\item evaluates \ {\tt iM' = inverse qM'};

\item finds \ {\tt iM'*qM'} \ to test that it is unity;

\item builds the residue ring \ {\tt R = Z/(5)}, \ finds its 
      property list and evaluates {\tt 2/3} in \ {\tt R};

\item parses from the string the polynomials \ {\tt f}, {\tt g} \
      in variables \ {\tt ["x","y"]} with the coefficients from \ 
      {\tt R},

\item evaluates \ {\tt gcd f g};
 
\item prints (unparses and outputs) all these results to the file \ 
      {\tt ./result}
\end{itemize}
%
{\footnotesize
\begin{verbatim}
  import DPrelude   (Z, ctr, smParse, mapmap                 )
  import Categs     (Subring(..)                             )
  import SetGroup   (zeroS                                   )
  import RingModule (Ring(..), GCDRing(..), upField, eucIdeal)
  import Z          (dZ                                      )
  import VecMatr    (Matrix(..), scalarMt                    )
  import Fraction   (Fraction(..)                            )
  import Residue    (ResidueE(..)                            )
  import Pol        (PolLike(..), Pol(), degRevLex, cToPol   )
  import LinAlg (solveLinearTriangular, solveLinear_euc, inverseMatr_euc)
  --
  -- all the above import can be replaced with  import DExport

  type Q = Fraction Z   -- rational number field
  type R = ResidueE Z   -- for  Z/(b)
  type P = Pol R        -- for  R[x,y]
  main =
    let
      un  = 1     :: Z
      unQ = 1:/1  :: Q
      zrQ = zeroS unQ                    -- zero of domain of unQ
      dQ  = upField unQ Map.empty        -- domain term of Q
      mM  = [[1,2,3,4,5,6],
             [5,0,6,7,1,0],
             [8,9,0,1,2,3]]  :: [[Z]]

      v       = [0,0,0] :: [Z]           -- right-hand part of system
      (_,ker) = solveLinear_euc mM v
      rows'   = mM ++ [[0,2,0,4,0,2],[5,0,6,1,2,0],[0,2,0,1,2,1]]
      qM'     = mapmap (:/un) rows'             -- making rationals
      iM'     = Mt (inverseMatr_euc qM') dQ     -- \m-> Mt m <dom>  makes true matrix
      Mt mPrd _  = (Mt qM' dQ)*iM'              -- matrix product
      unM        = scalarMt qM' unQ zrQ         -- unity matrix of given size
      checkInvM' = mPrd==unM
      ----------------------------------------------------------------
      b  = 5 :: Z                        -- arithmetics in R = Z/(b)
      iI = eucIdeal "bef" b [] [] []     -- makes Ideal(b) in R
      r1 = Rse un iI dZ                  -- unity residue by ideal iI
      dR = upField r1 Map.empty          -- domain term for R = Z/(b)
      (_,rR)     = baseRing r1 dR        -- base ring to which r1 belongs
      rProps     = subringProps rR
      [r2,r3,r4] = map (ctr r1) ([2..4] :: [Z])  -- each n projects to domain of r1
      q = r2/r3              
      ----------------------------------------------------------------
      vars = ["x","y"]                           -- for polynomial over R
      ord  = (("drlex",2), degRevLex, [])        -- power product ordering term
      p1    = cToPol ord vars dR r1  :: P        -- coefficient-> polynomial
      [x,y] = varPs r1 p1                                   -- x,y as polynomials
      [f,g] = map (smParse p1) ["x*(x^5+1)", "y*(x+1)^2"]   -- parse by sample p1
      gcdFG = gcD [f,g]
    in
    writeFile "result" $ 
                 -- shows e s  prints any value  e  prepending its string to  s
      concat
      ["kernel generators over Z =\n",                shows (Mt ker dZ) "\n\n",
       "inverse(qM')    =\n",                         shows iM'         "\n\n",
       "Checking qM'*(inverse qM') == unityMatrix = ",  shows checkInvM' "\n",
       "properties of R =\n",                         shows rProps "\n\n",
       "2/3 in R        = ",                          shows q     "\n",
       "gcd(f,g)        = ",                          shows gcdFG "\n"
      ]
\end{verbatim}
}
%
This program (let it reside in the file {\tt Main.hs}) is run under the \  
\verb#ghc-6.6.1# interpreter as follows:
\begin{verbatim}
   ghci -package docon Main 
   ...
   Main> main 
\end{verbatim}

Now, we \ repeat \ the \ {\tt `let'} \ part giving more comments:

\newpage
{\footnotesize
\begin{verbatim}
  main =
    let
      un  = 1     :: Z
      unQ = 1:/1  :: Q
      zrQ = zeroS unQ               -- zero of domain of unQ,
                                    -- unQ is a sample argument
      dQ  = upField unQ Map.empty   -- domain term of Q;  unQ a sample argument
      mM  = [[1,2,3,4,5,6], [5,0,6,7,1,0], [8,9,0,1,2,3]] :: [[Z]]
      v   = [0,0,0] :: [Z]       
      (_,ker) = solveLinear_euc mM v
      rows'   = mM ++ [[0,2,0,4,0,2], [5,0,6,1,2,0], [0,2,0,1,2,1]]
      qM'     = mapmap (:/un) rows' 
      iM'     = Mt (inverseMatr_euc qM') dQ  -- \m-> Mt m <dom>  makes true matrix
                                             -- from the list of rows
      Mt mPrd _  = (Mt qM' dQ)*iM'       
      unM        = scalarMt qM' unQ zrQ  
      checkInvM' = mPrd == unM
      ----------------------------------------------------------------
      b  = 5 :: Z                                   -- arithmetics in R = Z/(b)
      iI = eucIdeal "bef" b [] [] []   -- Ideal (b) in R.  eucIdeal "bef" completes
                                       -- ideal attributes according to mode "bef"
      r1 = Rse un iI dZ                  -- unity residue by ideal iI
      dR = upField r1 Map.empty          -- the full domain description
                                         -- for the ring of r1 (R = Z/(b))
      (_,rR)     = baseRing r1 dR        -- base ring to which r1 belongs
      rProps     = subringProps rR
      [r2,r3,r4] = map (ctr r1) ([2..4] :: [Z])  -- each n projects to domain of r1,
                                                 -- r1 is a sample argument
      q = r2/r3              
      ----------------------------------------------------------------
      vars = ["x","y"]                               -- for polynomial over R
      ord  = (("drlex",2), degRevLex, [])
                                     -- Power product ordering description.
                                     -- We could put instead of degRevLex any
                                     -- admissible function for pp comparison.
      p1 = cToPol ord vars dR r1  :: P
                                -- Mapping from coefficient is the best 
                                -- way to initiate some polynomial.
                                -- Here  r1  maps to the unity of  P = R[x,y].
      [x,y] = varPs r1 p1                                -- x,y as polynomials
      [f,g] = map (smParse p1) ["x*(x^5+1)", "y*(x+1)^2"]
                              -- Parses domain elements by the sample p1.
                              -- Alternative: [f,g] = [x*(x^5+p1), y*(x+p1)^2]
      gcdFG = gcD [f,g]    -- this should be (x+1)^2 because x^5+1 = (x+1)^5  over R
    in  ...
\end{verbatim}
}




\newpage
\section{ Principles of {\tt DoCon}}
% -----------------------------
\label{sec-prp} 

\subsection{ Partial maps. m format }
\label{sec-prp.mb} 

Consider an example: in DoCon, 
\begin{center}                {\tt n/m :: Z}  \ \ \ {\tt (= divide n m)} 
\end{center}
either evaluates to \ \ {\tt q :: Z} \ \ or to the program break with the 
report like\\ 
\verb#error: "divide 6 4"#.

But {\tt DoCon} provides also \ \ \ \verb# divide_m,# \ \ \ 
where the `m' denotation stands for `maybe'. For example,
\footnotesize
\begin{verbatim}
  divide_m 4 2 -> Just 2
           4 3 -> Nothing
           4 0 -> Nothing
\end{verbatim}
\normalsize
This gives a partial map with explicitly processed fail.
Example of usage:
\footnotesize
\begin{verbatim}
  f x y = case  divide_m x y  of  Just q -> ... something   with q ...
                                  _      -> ... other thing with x,y
\end{verbatim}
\normalsize
The type  
\begin{center}  \verb# data Maybe a = Nothing | Just a # \ldots
\end{center}
its instances, auxiliary functions, like \ {\tt allMaybes}, 
{\tt catMaybes} \ldots, are taken from the {\tt Haskell} Prelude,  
DPrelude of {\tt DoCon} and the standard library \ {\tt Maybe}.

Further, the operation \ \ {\tt root n x}
\\
may yield the values 
\begin{center}       \verb# Just (Just r) | Just Nothing | Nothing #
\end{center}
of type 
\begin{center}       {\tt MMaybe a = Maybe (Maybe a)}
\end{center}
(see Section \ref{sec-dprel}). This means respectively
\begin{itemize}
\setlength\itemsep{0pt}
\item ``r  is the root of n -th degree of  x'', 
\item ``such root does not exist in the given domain'', 
\item ``could not determine whether such root exists in given domain''.
\end{itemize}
Similarly are treated the \ {\tt zero}, {\tt unity} \ operations in 
semigroup, listing of a subset, and some others.
On the other hand, the {\it property values} attribute may help in 
choosing between `m' format and simple format. Thus, \ 
{\tt (IsGroup, Yes)} \ in the property list of an additive semigroup 
{\tt H} insures that the \ {\tt neg}, {\tt sub} \ operations are 
total on {\tt H}, hence, there is no need to apply \ \verb#neg_m#, 
\verb#sub_m#. 

Additional reason for wide use of `m' format is the feature of 
parametric domains, where the true definition domain of operations 
may depend on a dynamic parameter (Section \ref{sec-prp.ske}).
 


\newpage
\subsection{ Example of {\tt DoCon} application.\\  
             Computing in cubic radical extension.
           }
% ------------------------------------------------
\label{sec-prp.ex} 

The following example serves as an introduction to the {\tt DoCon} design
principles. The function 
\begin{center}           \verb# \a b k -> cubicExt a b k #  
\end{center}
builds automatically the radical extension tower
\begin{center} 
                     {\tt   k -- k(d) -- E = k(d)(u,v,r)  }
\end{center}
for the given field \ {\tt k}, \ and coefficients \ {\tt a}, {\tt b} \
of irreducible polynomial 
$$                        {\tt f} = t^3 + {\tt a} \cdot t + {\tt b} 
$$
over \ {\tt k}, \ {\tt a} $\neq 0$, \\
{\tt d} \ \ \ \ \ stands for the square root of {\tt discriminant(f)}, \\
{\tt r} \ \ \ \ \ square root of $-3$, \ \ \ \ {\tt u}, {\tt v} \ \ 
                  Cardano cubic radicals.

So, {\tt E} \ contains the field \ {\tt K' = k(x,y,z)} \ 
generated by the roots of {\tt f}.

{\tt cubicExt} \ applies the operation \ {\tt root 2 x} \ to \ 
{\tt x} \ from \ {\tt k} \ returning \ {\tt Just (Just y)} \ with
\ {\tt y} \ from \ {\tt k} \ such that \ \ {\tt y} $^2 =$ {\tt x}, \ \ 
if there is such \ {\tt y} \ in \ {\tt k}.

From the user point of view, one has only to apply 
\begin{center}         {\tt cubicExt a b k}
\end{center}
in the user program to prepare the extension.  But  to  explain  the
{\tt DoCon} architecture, we show here how to implement this  function  in 
{\tt Haskell} using {\tt DoCon}.
This  implementation  needs  combining  in   a   certain   way   the 
constructors of Polynomial and Residue;  the latter presumes, in its
turn, the Gr\"obner basis computation. The scheme is
%
\begin{itemize}
\setlength\itemsep{0pt}
%
\item  \verb# D = discriminant(f) = - 4*a^3 - 27*b^2; # \\
       {\tt dd = minimalPolynomial(d)} \\
  here \ {\tt dd = d - squareRoot(D)}, \ if \ {\tt k} \ contains 
  {\tt squareRoot(D)}, \ \ \verb#d^2-D# \ otherwise;
              
\item build the field \ {\tt k1 = k(d) = k[d]/(dd)} \ 
      and the ring \ {\tt B = k1[u,v,r];}
 
\item set \ {\tt r}, {\tt u}, {\tt v}, {\tt uv} \ 
      to be the defining polynomials for the corresponding field 
      elements \\
      (first portion of Cardano formulas): \\
      \verb# r  : r^2  + 3,# \\  
      \verb# u  : u^3  - (3/2)*d*r + (27/2)*b,# \\  
      \verb# v  : v^3  + (3/2)*d*r + (27/2)*b,# \\   
      \verb# uv : u*v  + 3*a# ;                 

\item find \ {\tt gs = Gr\"obnerBasis [u,v,uv,r]} \ in \ {\tt B} \\
      needed to represent \ {\tt B/Ideal(u,v,uv,r);}

\item build \ {\tt E = B/I} \ for \ {\tt I = Ideal(gs)} \ in \ {\tt B}
      \\
      --- {\tt E} \ represents an extension of \ {\tt k1} \ containing 
      the roots;

\item define the roots of \ {\tt f} \ in \ {\tt E} \ by Cardano 
      formulas: \\
      \verb# x = (1/3)*(u + v),#             \\
      \verb# y = (1/6)*(r*v - r*u - u - v),# \\
      \verb# z = (1/6)*(r*u - r*v - u - v)#  \\
\end{itemize}
%
Then the programmer may set, for example, the \ {\tt main} \ 
function that applies \\
{\tt cubicExt a b k} \ \ for some particular 
field \ {\tt k}, \ and then, performs various computations in terms 
of \ \ {\tt x, y, z} \ \ in \ {\tt E}, \ such as testing the 
Viete relations, and so on. The more advanced experiment here might 
be expressing of \ {\tt y} \ as a polynomial of \ {\tt x} \ over \
{\tt k(d)}.

Remarks for a newcomer to {\tt Haskell}:

the below program contains the commentaries starting with `--'.
The script has the form  
\begin{center}          {\tt let} \ldots {\tt in} {\it Expression}
\end{center}
familiar to the Lisp programmers. We also use intensively the 
pattern matching. To understand better the script, recall also that 
%
\begin{itemize}
\setlength\itemsep{0pt}
\item identifiers of type parameters, data (functions in particular) 
      start with small letters;
\item data and the type constructor names, as \ 
      {\tt Integer, \ Z, \ Pol}, \\ 
      start with capital letters;
\item {\tt Haskell} encourages omitting the parentheses, say \ 
      {\tt f x y === ((f x) y)},
\item the indentation rule also helps this and in narrowing the 
      scope of the variables.
\end{itemize}
%
\footnotesize
\begin{verbatim}
  import Prelude hiding (minimum, maximum)
  import DPrelude
  ...
  import GBasis (algRelsPols)

  type Q    = Fraction Z       -- rational numbers
  type A  k = UPol k           -- for  A  = k[d]
  type K1 k = ResidueE (A k)   --      K1 = k[d]/(d_equation)
  type B  k = Pol (K1 k)       --      B  = K1[u,v,r]
  type E  k = ResidueI (B k)   --      E  = B/I = k1(u,v,r)

  cubicExt :: Field k => k -> k -> Domains1 k -> (Domains1 (E k), [E k], k -> E k)
                      -- a    b    dK             dE             [x,y,z] kToE
\end{verbatim}
\normalsize
%
{\tt cubicExt} \ returns the
\begin{itemize}
\setlength\itemsep{0pt}
\item domain description \ {\tt dE} \ for the field \ {\tt E},
\item elements \ {\tt [x,y,z]} \ of \ {\tt E} \ representing the 
      aforementioned roots, 
\item embedding function \ {\tt k -> E}. 
\end{itemize}

{\bf Restriction}: \ \ {\tt char(k)} $\neq 2, 3$.

Here \ \ {\tt dK :: Domains1 k} \ \ is the domain description 
(term) for a field \ {\tt k}. \ It may include the set term, additive 
group term, and so on. The simplest way to obtain such domain supplued
with all neccessary desciption terms, is to apply an appropriate 
`up' function. \\
For example, 
%
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt dZ :: Domains Z} \ \ is `up' for the domain \ 
      {\tt Z = Integer}, \\
      it saturates \ {\tt dZ} \ with all things known for \ {\tt Z};

\item \verb#dK = upField (1:/1) Map.empty# \\
      saturates \ {\tt dK} \ with set, semigroup, \ldots, ring terms, 
      and so on, using \verb#1:/1# as the domain sample element,
      \ {\tt Map.empty} \ means here the empty initial domain. \verb#1:/1# 
      is a sample argument here, and, for example, \verb#2:/3#, 
      produces an algebraically equivalent result.
\end{itemize}
Thus, 
{\footnotesize
\begin{verbatim}
   let {un = 1:/1 :: Q;  dK = upField un Map.empty} in  cubicExt un (-un) dK
\end{verbatim}
}
builds the extension \ \ \ {\tt (dE, [x,y,z], kToE)} 
\\ 
expressing \ \ $ Q \ \mbox{---} \ Q( rootsOf(t^3 - t + 1) ) = E. $

\verb#Field k =># \ \
means that the parameter domain \ {\tt k}, considered as the type
is an {\it instance} of the {\tt Field} category 
({\tt Field} data class).  For example, this implies, that the 
expression \\
{\tt x + x/y} \ is valid for \ {\tt x}, {\tt y} \ from \ {\tt k}.

Now, skip the body of this function and concentrate on how  one  can
use it for constructing the extension of the field \ 
{\tt Rational = Q} \ with the roots of  
$$                                     f = t^3 - t + 1  
$$
and for performing some computations with the corresponding \ 
{\tt x}, {\tt y}, {\tt z} \ values in \ {\tt E}.


\newpage
\footnotesize
\begin{verbatim}
  module Main where
  import ...
  ...                -- Example. Build the extension of Q = Fraction Z
  main =             --          with  f = t^3 - t + 1
    let             
      un               = 1:/1 :: Q
      (a,b)            = (-un,un)
      dK               = upField un Map.empty 
      (dE,roots,kToE)  = cubicExt a b dK
      [x,y,z]          = roots
      Just (D1Ring rE) = Map.lookup Ring dE  -- look into ring E
      propsE           = subringProps rE     -- - for curiosity

                                          -- example of calculation in E
      discr  = - (4:/1)*a^3 - (27:/1)*b^2
      n1     = fromi x 1                       -- integer -> ring of x
      fRoots = [x^3 - x + n1 | x <- roots]     -- should be [0,0,0] in E
      vieteValues = [x+y+z,x*y+x*z+y*z,x*y*z]  -- test Viete relations

      -- Now, find  y  as a quadratic polynomial in  x  over  k1.
      -- x,y  are the polynomial residues of  x',y' <- B = k1[u,v,r]
      -- modulo I.  We have to find the algebraic relations between 
      -- x',y' in B modulo I.

      [x',y'] = map resRepr [x,y]
      Just hs = idealGens (resIdeal x)
      o       = lexPPO 2                            -- set pp ordering
      rels    = algRelsPols hs ["y","x"] o [y',x']
          --
          -- generators of algebraic relations for  y',x' viewed
          -- modulo Ideal(hs) in  k1[u,v,r],  the relations to display
          -- in variables "y","x"

      relCol = transp (Mt [rels] Map.empty)   -- for nice printing of several polynomials
    in
    (discr, [roots,fRoots,vieteValues], propsE, rels, relCol)
\end{verbatim}
\normalsize
%
Now, we repeat the `main =' part supplying it with more comments.
Some of the program lines are marked with \ {\tt `n:'}.
This means ``see the commentary number n after the program''.

\newpage
\footnotesize
\begin{verbatim}
  main =  
    let   
  1:  un               = 1:/1 :: Q
      (a,b)            = (-un,un)
      dK               = upField un Map.empty
      (dE,roots,kToE)  = cubicExt a b dK
      [x,y,z]          = roots      -- the list is pattern matched to x,y,z values
  2:  Just (D1Ring rE) = Map.lookup Ring dE   -- look into ring E
      propsE           = subringProps rE      -- - for curiosity

                                              -- example of calculation in E
      discr  = - (4:/1)*a^3 - (27:/1)*b^2
      n1     = fromi x 1              -- map homomorphically integer to base ring of  x
      fRoots = [x^3 - x + n1 | x <- roots]           -- this should be [0,0,0], 0 of E
      vieteValues = [x+y+z, x*y+x*z+y*z, x*y*z]      -- testing Viete relations

      -- For these a,b, the Galois theory says E' = k1(x,y,z) = k1(x)  and
      -- E':k1 = 3.  In particular,  y  has to express as a quadratic polynomial in 
      -- x  over  k1.  Let us test this.  x, y  are the polynomial residues of
      -- x', y' <- B = k1[u,v,r]  modulo the ideal I.  So we have to find the 
      -- algebraic relations between x', y' in B modulo I.

  3:  [x',y'] = map resRepr [x,y]
  4:  Just hs = idealGens (resIdeal x)
      o       = lexPPO 2           -- set ordering for polynomial power product
      rels    = algRelsPols hs ["y","x"] o [y',x']
                                -- generators of algebraic relations for y',x' 
                                -- viewed modulo Ideal(hs) in  k1[u,v,r],  
                                -- relations to display in variables "y","x"
      relCol = transp (Mt [rels] Map.empty)   
                          -- for the nice printing we transform the polynomial 
                          -- list to the column matrix over polynomials
    in
    (discr, [root, [fRoots,vieteValues], propsE, rels, relCol)
\end{verbatim}
\normalsize
%
One could also set \ {\tt shows} \ here, after the fashion of earlier 
examples, to print, output the results.
This program, together with \ {\tt cubicExt}, \ is also presented in the file 
\\
\verb#demotest/T_cubeext.hs.# 

Printing the results, we see:
\newpage
\footnotesize
\begin{verbatim}
  discr       = -23
  roots       = [(1/3)*u + (1/3)*v, 
                 (-1/6)*u*r + (-1/6)*u + (1/6)*v*r  + (-1/6)*v,
                 (1/6)*u*r  + (-1/6)*u + (-1/6)*v*r + (-1/6)*v)    
                ]
  fRoots      = [0,0,0]
  fRoots      = [(0), (0), (0)]
  vieteValues = [(0), (((-1))), (((-1)))]
  propsE      = [(IsField,Yes), (Factorial,Yes) ...]

  relCol  (algebraic relation generators for y,x) =
  (Mt [
    [(x^3 + ((-1))*x + (1))],
    [(y + ((3/23)*d)*x^2 + ((9/46)*d + (1/2))*x + (((-2)/23)*d))]
  ] )
\end{verbatim}
\normalsize
We are mostly interested in \ {\tt relCol}, \ and observe that it 
consists of the source equation on \ {\tt x} \ and a non-trivial 
quadratic expression of \ {\tt y} \ in \ {\tt x} \ over \ 
{\tt k(d)}.

Now, the No -red commentaries to the function `main': 
\medskip

{\bf 1:}

\verb#:/# \ \ is the data constructor for the {\tt Fraction} 
functor in {\tt DoCon}. The {\tt DoCon} declaration associates 
it with the type constructor 
\begin{center}        \verb#  data Fraction a = a :/ a ... #
\end{center}
As the first approach, we assume that {\tt DoCon} represents \\ 
  an algebraic category \ \ \ \ \ \ \ \ as an {\tt Haskell} data class, \\
  operation from a category \ \         as a class method, \\
  (static) algebraic domain \ \ \       as a class instance. 

{\tt DoCon} contains the declarations that supply a type {\tt (Fraction a)} 
with the operations of \ Set, Additive group, 
Multiplicative semigroup \ldots \ Field \ categories --- provided the
parameter type \ {\tt a} \ is the instance of the {\tt GCDRing} class 
described in DoCon. And the usual arithmetic methods for 
{\tt (Fraction a)} are correct if the operations on \ {\tt a} \ 
satisfy the GCD-ring property. In our case, \ {\tt a = Z} \ 
provides such a ring, and this is why in the further script the 
expressions like \ \verb#(-4:/1)*a^3# \ make sense. 

Similarly, the {\tt DoCon} functors \ {\tt UPol}, {\tt Pol}, 
{\tt ResidueE}, {\tt ResidueI} \ are composed and make the ring 
tower up to \ {\tt E}, with the instances of the \ {\tt Field} class. 
This is why, for example, the expression \ \verb#\x-> x^3-x+1 :: E# 
\ is valid in the further program.
\medskip

{\bf 2:}
\begin{verbatim}
                 Just (D1Ring rE) = Map.lookup Ring dE
                 propsE           = subringProps rE   
\end{verbatim}
Here \ {\tt Map.lookup} \ extracts the ring term given the key \ 
{\tt Ring :: CategoryName}. 
Say \ \ {\tt Map.lookup AddGroup dE} \ \ extracts the additive group, 
and so on. 
The value \ {\tt rE} \ is an explicit description of the ring:
%
{\footnotesize
\begin{verbatim}
                Subring {subringChar  :: Maybe Z,
                         subringGens  :: Maybe [a],
                         subringProps :: Properties_Subring,
                         ...
                        }
\end{verbatim}
}
There are several specially designed functions to help  constructing
such terms from the simplest data: integer domain {\tt dZ}, 
set from list, ideal from generators, and so on.
\medskip

{\bf 3:} \ \ \ \ \ {\tt [x',y'] = map resRepr [x,y]}

{\bf 4:} \ \ \ \ \ {\tt Just hs = idealGens (resIdeal x)}
\medskip

{\tt x}, {\tt y} \ are built as the elements of a residue ring \
{\tt E = B/iI}, \ {\tt B = k1[u,v,r]}.

{\tt resRepr} \ extracts a representative from the residue element.
For these representatives {\tt x'}, {\tt y'}, the program finds the  
relations modulo ideal. 
Another way to extract {\tt x'}, is to pattern match \ 
{\tt Rsi x' \ldots = x}, \ with the constructor \ {\tt Rsi} \ of 
the residue ring data. {\tt resRepr} \ is better, because it does
not rely on the particular type constructor.

{\tt resRepr}, {\tt resIdeal} \ are the operations from the 
{\it constructor class} \ {\tt Residue}, \ that joins \ {\tt ResidueE}
--- for the Euclidean case, and \ {\tt ResidueI} --- for the generic 
case.
{\tt ResidueI} \ relates to the implementation of a residue ring 
by an ideal. The ideal term {\tt iI} is inside each residue element 
{\tt r}, and can be extracted by applying \ {\tt resIdeal r}.

Further, \ \ {\tt idealGens iI} \ \ extracts the ideal generator 
list from {\tt iI}, --- if it was set into the {\tt iI} data earlier.
For the ideal, {\tt DoCon} needs the generator list with the property 
value \ {\tt (IsGxBasis,Yes)} \ to provide the residue ring with 
the correct {\tt Ring} instance. 
So, starting from the residue elements \ {\tt x}, {\tt y}, \ we get 
the ideal, ideal generators, and so on. 

{\tt x'} \ has to be a canonical representative of a residue class.
For the polynomial ring over an Euclidean ring, {\tt DoCon} chooses as 
such representative the normal form modulo the Gr\"obner basis  
contained in {\tt iI}.


\newpage
\subsection{ Category hierarchy }
% -------------------------------
\label{sec-prp.hr}

DoCon deals with the following category graph:
%
\begin{verbatim}
                          Show    Eq
                             \   /
       OrderedSet    <- - -   Set  
                             /   \
                           /       \
  Ordered.. <- - - AddSemigroup    MulSemigroup
  ...                 /                  \
                    /                  /   \
            AddMonoid                /     MulMonoid
                 /                 /          \
               /                 /              \
          AddGroup _ _ _ _  _  /                MulGroup 
           /     \           / \ _ _ _
         /         \       /           \
   OrderedAddGroup   \   /             LeftModule
                       |                        \    
                      Ring                     LinSolvLModule
                       |              
                 CommutativeRing --> OrderedRing 
                      /  \ 
                    /      \               
               GCDRing      LinSolvRing      
                 /            \
               /                \
     FactorizationRing         EuclideanRing        
                 \            /
                   \        /
                     \    /
                     Field     - - ->  RealField      
\end{verbatim}
%
The programmer may develop this graph further.
There also exist standard {\tt Haskell} classes \\
{\tt Show, Eq, Ord, Enum, Num, Fractional}.

{\tt DoCon} includes them into this tower in order to use their operation
names. But other {\tt DoCon} operation definitions has to agree with these 
ones in a certain way --- see the comments to each category.

\newpage
  {\tt Eq}  \hspace{30mm}      is a superclass of {\tt Set},

  {\tt Ord} \hspace{55mm}                      of {\tt OrderedSet},

  {\tt Num}, {\tt Fractional}  \hspace{31mm}   of {\tt Ring}.
\medskip

Most of DoCon library is devoted to {\tt GCDRing}, 
{\tt LinSolvRing}.
Some of the category declarations are {\it empty}, only proclaim  
in a commentary some additional presumed conditions.
See, for example, \ {\tt Field}.




\newpage
\subsection{ What is {\tt DoCon}}
% --------------------------
\label{sec-prp.ske}

The following explains in brief the full idea of DoCon.
\bigskip

\underbar{{\bf (MB) Mathematical base}}

The methods, algorithms (of arithmetic nature or other) are defined 
for some constructed domain 
\begin{center}               {\it C} {\tt a b} \ldots 
\end{center}
via some generic methods for the domains \ {\tt a}, {\tt b} \ldots
--- under appropriate declared conditions. For example,
\begin{verbatim}
  instance GCDRing a => GCDRing (Pol a) where 
                                        gcD = ... <gcd for polynomials>
\end{verbatim}
expresses the polynomial GCD via arithmetics and GCD on \ {\tt a}, 
and relies on the property of \ {\tt a} \ being a gcd ring.
Developing such methods constitutes the science of computing,  
they may be taken from books, scientific papers 
(see the literature {\bf References}), sometimes are invented by the 
author.
\bigskip
  
\underbar{{\bf (CT) Category}}  

is defined by a class declaration and presumed, intended condition; 
the latter is provided as a commentary. {\bf Example:}  
\begin{verbatim}
  class Set a => AddSemigroup a where add :: a -> a -> a
    --                                ...
    -- presumed: `add' agrees with (==), is associative, commutative
\end{verbatim}
\bigskip

\underbar{{\bf (D) Domain (many-domain)}}

is defined by several algebraic instance declarations for a given
algebraic constructor \ {\it C}, \ together with the sample element 
\begin{center}
                      {\tt s =} {\it C} {\tt a b \ldots}
\end{center}
This \ {\tt s} \ defines finally the true current algebraic domain 
\ {\tt D(s)}, \ and hence, to which categories {\tt D(s)} belongs
in fact.
(Many-)domain  has also an explicit description --- a {\it bundle}
--- see {\bf (DT)}, {\bf (MD)}.
\bigskip

\underbar{{\bf (DT) Domain term}}

is an explicit expression describing partly a domain. \\
{\bf Example:} \ the base bundle for \ {\tt Z = Integer} \ contains
\begin{itemize}
\setlength\itemsep{0pt}
\item \verb#sZ :: OSet Z# \ \ 
      which describes the set Z,  \ \ it contains  \\
      {\tt membership = const True, \ cardinality = Infinity}, \ \  
      other attributes,

\item \verb#aZ :: Subgroup Z# \ \
      contains the generator list \ {\tt [1]} \ 
      for an additive group \ldots
\end{itemize}
and so on.
\bigskip


\underbar{{\bf (MD) Many-domain (bundle)}}

is a finite collection of domain terms stored each under its {\it key},
\begin{center}
         {\tt Key = CategoryName = Set | AddGroup | Ring | \ldots}
\end{center}
Example:  \ {\tt dZ} \ is the bundle for \ {\tt Z}, \ 
it contains terms for the keys from {\tt Set} up to \\
{\tt FactorizationRing}, {\tt EuclideanRing}.
\bigskip

\underbar{{\bf (E) Element (of domain)}}

is a data of kind \ {\it C} {\tt x y \ldots} \\ 
obtained by a type constructor {\it C} applied to arguments.  
Some arguments may be domains (bundles) \\
(the domains \ {\tt Char, Integer} \ are presented as constructors 
applied to empty argument sequence). \\ 
{\bf Example:} 
\begin{center}      {\tt Rse x iI aD} 
\end{center}
is an element of residue ring \ \ \verb#a/I  <--> ResidueE a# \ \ \
for Euclidean \ {\tt a}, \\
{\tt aD} \ a bundle for domain \ {\tt a}, \ \ 
{\tt iI} \ ideal description.
\bigskip

\underbar{{\bf (DS) Domain by sample element}}

Any element  
\begin{center}        {\tt s = {\it C} a b \ldots}    
\end{center}
can serve as a sample defining its many-domain.  
For each known to {\tt DoCon} constructor \ {\it C}, \ {\tt DoCon} puts
individually how the parameters \ {\tt a}, {\tt b} \ldots \ of
{\it C} \ define a domain. Partly, this is set by assumption,  
partly --- by explicit definition of several base-operations: 
{\tt baseSet}, {\tt baseAddSemigroup} \ldots \ --- see {\bf (BO)}.
\\
{\bf Example:} \ for the ideal descripions \ 
                   {\tt iI = idealOf(7 in Z), \ iJ = idealOf(8 in Z)},
\\
the data 
\begin{center} {\tt r1 = Rse 0 iI dZ, \  r2 = Rse 0 iJ dZ}  
\end{center}
are of the same type \ \ {\tt ResidueE Z} \ \ but of different domains \ \ 
                                              {\tt Z/(7), Z/(8)}.

Further,
\begin{center} 
\verb# bs1 = snd $ baseSet r1 Map.empty,  bs2 = snd $ baseSet r2 Map.empty#
\end{center}
build the set terms for \ {\tt Z/I}, \ {\tt Z/J}. \ 
One could see, for example (at the run-time), 
\begin{center} 
               {\tt osetCard bs1 = 7,  \ \ osetCard bs2 = 8.}
\end{center}
If further domain terms have been formed by \
                     {\tt upAddGroup} \ldots \ {\tt upRing} \ldots, 
\\
then other domain attributes can be tested at the run time. 
For example, \ {\tt isField(Z/I)} \ can be checked by looking into 
the {\it property list} of the ring term.
\bigskip



\underbar{{\bf (SA) Sample argument}}

Some class operations, functions in {\tt DoCon} need a sample argument to
specify the domain for the operation (function).
For example, 
\begin{center} \verb# zeroS $ Vec [2],  zeroS $ Vec [2,0] # 
\end{center}
are the zeroes of different groups --- defined by samples of 
different domains. If a function  \ {\tt f} \ is said to have a
sample argument \ {\tt s}, \ taking value in some \ {\tt Set}, \ 
then \ {\tt f} \ should not depend on the choice of \ {\tt s} \ 
inside the same domain (see {\bf (DS)}). 
\ \ {\bf Examples:}  
\begin{verbatim}
  fromi (1,1) 4   == fromi (2,1) 4    == (4,4) 
  zeroS $ Vec [2] == zeroS $ Vec [-1]  /= zeroS $ Vec [2,2],
  unity (2:/3)    == unity ((-3):/1).
\end{verbatim}
Sample arguments are sometimes commented with 
``-- SA'' or ``-- sa''. Often they are taken from surrounding program 
context, otherwise, can be easily built recursively, applying the 
constructor to the simpler samples.
\bigskip

\underbar{{\bf (CS) Cast by sample}}

Construct the initial sample \ \ \verb#s :: T# \ \ for a domain in the type \ 
{\tt T} \\ 
and apply the casting functions  
\begin{center}        {\tt ct s, \ ctr s, \ fromi s, \ smParse s}
\end{center}
to construct other elements of domain from simpler data. \\
{\bf Example 1:} \
in {\bf (DS)} example, it is better to write 
\begin{center} 
           {\tt ct r1 4}   \ \ than \ \ {\tt Rse 4  iI dZ}, \ \ \ \ \ 
           {\tt ctr r1 11} \ \ than \ \ {\tt Rse 11 iI dZ}.
\end{center}
{\tt ct s}, \ {\tt ctr s} \ \ cast to domain of \ {\tt s}. \ 
These functions are polymorphic. For example, they cast to polynomial from 
coefficient, from monomial, from monomial list.
\\
{\bf Example 2:} \ 
\verb#fromi s:  Z -> domain of s# \ \ maps homomorphically from {\tt Integer}.
\\
Thus, in {\bf (DS)}, \ \ \verb#fromi (r1,r2) : Z -> (Z/(7), Z/(8))#
\bigskip
 

\underbar{{\bf (DE) Extractors}}

It is a good style to use specially designed  operations,  functions
to extract the parts of domain element.
For this purpose there are also provided the classes  
\begin{center} 
  {\tt Dom (sample, dom), \ \ Residue (resRepr, resPIdeal \ldots), \ \
                                                    \ \ PolLike \ldots 
  }
\end{center}

{\bf Example 1:} \  
in example of {\bf (DS)}, \ \ {\tt resRepr r1, \ dom r1, \ resPIdeal r1}
\\
extract the representative from the element of residue ring {\tt Z/I},
argument domain {\tt dZ}, \\
ideal term for {\tt I}.  This is more invariant than matching against \ 
{\tt Rse x iI d}.

{\bf Example 2:} \ 
for a polynomial \ {\tt f} \ from \ $R[x], \ R[x_1,\ldots,x_n]$, 
\\
which can be represented in various ways,
\begin{center}   
                  {\tt sample f, \ dom f, \ pVars f, \ lc f}
\end{center}
yield respectively the \ coefficient sample, \ term of $R$, \ 
variable list, \ leading coefficient.
\bigskip


\underbar{{\bf (BO) Base-operations}}
%
\begin{center} 
  {\tt baseSet, \ baseAddSemigroup, \ \ldots \ baseRing, \ baseEucRing}
\end{center}
and some other, build the corresponding domain terms from a sample \
{\tt s} \ and a given current {\it bundle} \ {\tt dD}.  
%
\begin{itemize}
\setlength\itemsep{0pt}
\item Example 1: \ \verb# baseSet s dD --> (dD',bs) : #
  \\
  if the Set term {\tt bs} is in {\tt dD}, then {\tt dD} remains 
  and {\tt bs} extracts, \\     
  otherwise, {\tt bs} is constructed via \ {\tt s, dD} \ 
  and put into {\tt dD} too. \\
  Other base-operations act similarly.

\item Example 2: \ for the example from {\bf (DS)}, \ \ 
                               \verb# bS = snd $ baseSet r1 Map.empty# 
  \\
  builds the subset term for {\tt Z/I}. \ As \ \verb#r1 = Rse _ iI dZ#,\\
  {\tt bS} is defined via the bundle 
  for \ {\tt Z} \ and the ideal \ {\tt iI}. 
\end{itemize}
\bigskip

  
\underbar{{\bf (UP) Up-functions}}

A {\it base bundle} can be built from {\it initial} one 
(maybe, from empty) by the {\tt DoCon} functions
\begin{center} 
             {\tt upAddSemigroup, upGroup, upRing}, \ and so on.
\end{center}
Up-function is a composition of several {\it base-operations}. 
\\
{\bf Example:} \ \ in {\tt (DS)} example, the program 
\begin{center} 
              {\tt let  bd = upRing r1 Map.empty  in  upEucRing r1 bd'}
\end{center}
adds the terms, up to the description of Euclidean ring, to the
bundle obtained from {\tt upRing}.
\bigskip


\underbar{{\bf (BSE) Base set. Equality.}}

{\tt (==)} \ has to be an equivalence relation on a {\it base set}
BS. 

BS is understood as the set of canonical representatives by 
{\tt (==)}.
This is always a {\tt DoCon} assumption for a base domain of given sample.
In easy cases the subset BS in a type is defined completely by  the
the membership function contained in the  subset  term made via \ \  
\verb#baseSet s _#.  \ \ And often, the subset is presumed.

All the further base domains for {\tt s} are considered as having  
the {\it support} BS.
\\
{\bf Example:} \\ 
{\tt r1, r2} \ from example of {\tt (DS)} \ 
define the finite subsets BS1, BS2 \ in \ {\tt ResidueE Z}, \ \
with empty intersection of BS1, BS2.  
\\
{\tt Rse 6 iI dZ} \ belongs to BS1.  \ \ 
{\tt r3 Rse 7 iI dZ} \ \ does not --- the representative being not 
reduced canonically by {\tt I}. \ {\tt r3/r3} \ will pass through 
compilation, but may evaluate wrongly, because {\tt DoCon} presumes {\tt r3} 
to belong to BS1.
\bigskip


\underbar{{\bf (IN) Meaning of a category instance declaration}}
\medskip

Here we formulate how the programmer should view the class instances
when applying the advanced part of DoCon. This concerns a parameterized 
domain {\tt D(p)} inside a type \\ 
{\tt (C a)}. \ For example, \ \verb#D(m) = Integer/(m)# \ inside \ 
{\tt ResidueE Integer}.

The following semantics is proposed for the category (algebraic class)
instance with respect to the parametric domain {\tt D(p)} given by a
sample \ \verb#s :: C a.# \ 
This instance meaning differs in its last point from traditional 
Haskell.
%
\begin{itemize}
\setlength\itemsep{0pt}
\item{(1)}  For a non-parametric domain the meaning remains.
            Examples: \\
      {\tt Integer}, \ {\tt (Fraction Integer, UPol (UPol Integer))}.

\item{(2)}  For a parametric domain {\tt D(p)}  related to type
            {\tt (C a)}  the meaning of {\it absence} of instance
            declaration
            \verb# (...) => # {\it Category} {\tt (C a)} \ \ \ 
  remains: no domains {\tt D(p)} are considered as belonging to
  {\it Category}. \  
  In the cases (1),(2), categories for {\tt D} are detected at compilation 
  time.

\item{(3)}  For a parametric domain {\tt D(p)} related to a type
            {\tt (C a)}  the presence of declaration
  \\
  \verb#                 #
  {\tt instance} {\it Context} {\tt a} \verb# => # {\it Category}
                                                   {\tt (C a)}  \\
  means that
  \begin{enumerate}
  \setlength\itemsep{0pt}
  \item  (as usual) for {\tt D(p)} to be of {\it Category},
         the instances {\mbox ({\it Context} {\tt a})} should match
         the type \ {\tt a} \ (this is detected at compilation time)  AND

  \item  {\tt s} \ should contain a parameter value \ {\tt p}
    satisfying the so-called `detect' condition.
    This condition check is optional and often performs at the run-time. 
    \\
    The programmer may apply explicitly appropriate detecting 
    function to {\tt s}.
  \end{enumerate}
\end{itemize}
%
The mentioned detecting function can always be presented as a composition
of base-functions and access to the domain attributes produced by 
base-functions.
\\ 
{\bf Example:} \\ 
{\tt DoCon} contains a declaration
\begin{verbatim}
   instance EuclideanRing a => Field (ResidueE a)
                                            -- (resPIdeal r) should be prime 
\end{verbatim}
According to the general rule, this means: a residue data \  
\verb#r = Rse x iI aD  :: ResidueE a#
\\
belongs to a ring \ {\tt R = a/I} \ of residues of a ring \ {\tt a}. \ 
And {\tt R} is a field when the ideal {\tt iI} is prime. 
The latter condition can be checked by applying
\begin{center}
   {\tt isPrimeIdeal iI} \ \ or \ \ \verb#isPrimeIdeal $ resPIdeal r#
\end{center}
or \ \ {\tt isField rR}, \ \ with a base ring term {\tt rR} for \ {\tt r} \ 
formed earlier by \ {\tt (baseRing r \ldots)}. \ And again, {\tt baseRing} 
would analyze {\tt iI}, {\tt aD} \ when forming {\tt rR}.

Note the role of compiler here: it checks the static 
{\it class instance} \ {\tt EuclideanRing a}\\
for the type \ {\tt a} \ but does not check further the primality of 
{\tt iI}, \ nor the condition \ {\tt isField (a/I)}. 
\bigskip


\underbar{{\bf (CC) Correctness condition for method}}

A polymorphic method defined under the  instance  context,  has  the
correctness  condition  that  depends  not  only  on   the   context 
declaration but also on the sample (true domain) attributes.
This is a consequence of {\bf (IN)}, {\bf (DS)}. 
\\
{\bf Example:} \ 
let the user put  
\begin{verbatim}
  det_Gauss :: Field a => [[a]] -> a
  det_Gauss mM = ... <determinant via Gauss method>
\end{verbatim}
and apply it to  \ {\tt a = ResidueE Z}. \ Then this will compile all right, 
and at the run-time, the correctness depends on which residues are put in 
the matrix. With \verb#(Rse _ ideal(3) _)#, \ \ \verb#det_Gauss# \ 
performs correct, \ with \ \verb#(Rse _ ideal(4) _)#, \ may perform wrongly. 

{\tt DoCon} usually checks  such  conditions before starting to really 
evaluate expensive enough methods: \ determinant, gcd, \ and such.
Similarly, the user program decides each time, what to check.
\bigskip


\underbar{{\bf (BF) Bundle field in constructor}}

Bundle field in a domain constructor provides a reliable control on the 
cost of base-fuctions and domain attribute access. 
\\
{\bf Example:} \ 
a residue element for an Euclidean ring is 
\begin{center}
        {\tt r = Rse x iI aD \ \ $\in$ \ a/iI = R = base ring of \ r}
\end{center}
If in some loop the attributes of {\tt R} are processed many times, 
they form dependently on {\tt iI}, {\tt aD}, \ {\tt aD} the bundle for 
\ {\tt a}. \ But {\tt iI}, {\tt aD} \ are ready, their values shared by 
the elements of {\tt R}.

If, say for this example, there appears further the ring {\tt R[x]}, 
then the constructor {\tt UPol} requires a bundle {\tt dR} for {\tt R}, 
{\tt dR} is formed after {\tt iI}, {\tt aD}, and then, the ready 
value for {\tt dR} is shared among elements of {\tt R[x]}.  
And so on, up the constructors applied.

This looks like a situation when each student of university keeps 
this university in one's pocket. 
This is all right for functional programming, due to most natural 
features of any reasonable implementattion, such as 
data sharing, references and `lazy' copying.




\subsection{ Further explanations on principles }
% -----------------------------------------------
\label{sec-prp.skco} 


\subsubsection{ Presumed condition for category }
\label{sec-prp.skco.ct} 

Still, the ``presumed condition'' --- see 
(Section~\ref{sec-prp.ske} (CT)) 
--- is sometimes provided automatically, due to the constructor 
properties. Thus, the {\tt DoCon} declaration
\begin{verbatim}
   instance (AddSemigroup a, AddSemigroup b) => AddSemigroup (a,b)
     where
     add (x,y) (x1,y1) = (add x x1, add y y1)
        ...
\end{verbatim}
automatically guarantees that the semigroup law holds for the domain 
{\tt (a,b)} if it holds for \ {\tt a} \ and \ {\tt b}.



\subsubsection{ Sample element }
\label{sec-prp.skco.se} 

This approach is taken partly because in {\tt Haskell} one cannot 
relate a constant to a domain in a simplest way. For example, declaring
\begin{center}
               \verb# class WithCard a where cardinality :: Z #
\end{center}
would not do any good. Because seeing, say \ \verb#2*cardinality# \ 
in a program, the compiler cannot solve, who's cardinality is taken.
But it appears, the sample element also helps to identify the 
presumed dynamic domain and to map between domains.
For each constructor \ {\it C}, \ {\tt DoCon} documentation declares 
individually how the subset is defined in the type \\ 
{\tt ({\it C} a b \ldots)} \ (Section~\ref{sec-prp.ske} DS).
\\
{\bf Example:} \ {\tt DoCon} specifies the following assumptions:
\begin{itemize}
\setlength\itemsep{0pt}
\item \verb#s :: Z# \ \ defines in the base set Integer --- 
                                          it coincides with the type.

\item \verb#s = k:/l  :: F a = GCDRing a => Fraction a#
      \\
      defines the subset of {\tt (F a)} of all the expressions \
      \verb#n:/d#, \ {\tt d /= zero, \ n, d} \ cancelled canonically 
      via gcd \ (Section~\ref{sec-fr}).

\item \verb#s = Vec xs  :: Vector a# 
      \\ 
      defines the subset \ 
           \verb#V = {Vec ys :: Vector a | length ys == length xs}#
      \\
      of vectors over \ {\tt a} \ with the given number of components.
\end{itemize}



\subsubsection{ Base set. Equality }
\label{sec-prp.skco.bs}

{\tt Haskell} wisely treats the relation {\tt (==)} not as syntactic
but as ``algebraic'' one. So that the programmer can define equality
according to one's undesrtanding of a given algebraic domain.
For example, the polynomial data
\begin{center}
            {\tt  f = UPol [] 1 "x" dZ, \ \ g = UPol [] 2 "x" dZ  }
\end{center}
in {\tt Z[x]} are syntactically different, but \ \ {\tt f==g = True} \ \  
in DoCon. \\
Because in \ \ \verb#(UPol _ c _ _)# \ \ {\tt c} \ 
is treated as a sample element.



\subsubsection{ Cast by sample }
\label{sec-prp.skco.cs}

For the data \ \verb#s :: T#, 
\\
\verb#fromi s   : Z      -> T# \ \ maps homomorphically from Integer,
\\
\verb#smParse s : String -> T# \ \ parses a string after a sample,
\\
\verb#ctr s     : a      -> T# \ \ 
                               casts from domain \ {\tt a} \ after a sample.

Example: \ 
        {\tt s = Pol monomials coefSample ppOrd variables coefDomain}
\\
is a format for a multivariate polynomial.
But the programmer is not supposed to write things like \ 
{\tt (Pol ms c o vs dD)}. \\
Rather one sets \ \ \verb#ctr s <coefficient>#, \ \  
\verb#ctr s <monomial>#, \\
\verb#ctr s <monomialList># \ \ (Section~\ref{sec-prp.ske} (CS)).

Apply similar technique to other constructors: 
{\tt RPol}, {\tt ResidueE}, {\tt ResidueI}, \ldots

See in this manual the programs with these operations, their 
instances declared here for the constructors, 
examples in the files ...\verb#demotest/T_*.hs# 



\subsubsection{ Static and dynamic domain }
\label{sec-prp.skco.sd} 

As we see from Section~\ref{sec-prp.ske}, 
\\
the static notion of a domain is given by the class {\tt instances},
\\
a dynamic domain is a bundle of domain terms.

A bundle is used mostly for operating with the domain attributes:
cardinality, properties, and such.
The {\tt instances} are needed to use the category operations: \
\verb#+, *#, {\tt gcD} \ldots

Base-operations (Section~\ref{sec-prp.ske} BO) present an important 
relation between a static domain and a bundle.


\subsubsection{ Base-operations }
\label{sec-prp.skco.bo}

The needed domain term can be obtained from a sample element \ 
{\tt s} \ and a current bundle \ {\tt dm} \ either by
\begin{center}
              \verb#Map.lookup <key> dm# \ \ ({\tt s} not needed) \ \ \
              or by \ \ \verb#base<Category> s dm#
\end{center}
Consider, for example, \ {\tt (Map.lookup Set dm)} \ and \ 
{\tt (baseSet s dm)}.
\\
The latter is more generic: if it does not find the needed term in 
{\tt dm}, it starts forming it from \ {\tt s, dm}.

{\bf Example 1:} \\
for the domain {\tt Char}, {\tt DoCon} declares something like
\footnotesize
\begin{verbatim}
  instance Set Char where 
    ...
    baseSet _ dm = case  Map.lookup Set dm
                   of
                   Just (D1Set o) -> (dm, o)
                   _              -> (Map.insert Set (D1Set o) dm, o)
                       where
                       o = OSet {osetSample  = 'a', membership = (\_ _->True), ...}
\end{verbatim}
\normalsize
For {\tt Char}, the function {\tt baseSet} ignores the sample 
argument. Similar is {\tt Z}.
\medskip

{\bf Example 2:} \\ 
The {\tt Fraction} constructor uses the sample as follows.
\footnotesize
\begin{verbatim}
  instance GCDRing a => Set (Fraction a)  where
    ...
    baseSet (n:/_) dm = case  (Map.lookup Set dm, upGCDRing n Map.empty)  of

                  (Just (D1Set sbs), _   ) -> (dm, sbs)
                  (_               , aDom) -> (Map.insert Set (D1Set sbs) dm, sbs)
                                     where
                                     sbs = ... build a base set for  Fraction A
                                     from the bundle  aDom  of A
\end{verbatim}
\normalsize
Here the bundle {\tt aDom} is built for the numerator of the 
sample, --- for the domain \ {\tt a}, \\
then {\tt aDom} is used to build the destination term.


\subsubsection{ Bundle, domain }
\label{sec-prp.skco.bd} 

Sometimes we mean by `domain' a bundle: several algebraic structures
related to the {\it set}. In other case, `domain' means one of these 
structures.

A type, instances related to it, and a bundle define completely what 
a domain is. If, for example, the call \ 
{\tt Map.lookup Ring dD} \ returns \ {\tt Just s}, \ this means that 
{\tt DoCon} is ready to deal with {\tt dD} as with a true ring, 
it may look into the property list, and so on. 
Otherwise, {\tt dD} is not known as a true ring.
For example,
\begin{center}   \verb# dZ :: Domains1 Z # 
\end{center}
is the fullest known bundle for \ {\tt Integer}, \ and
\footnotesize
\begin{verbatim}  
  (Map.lookup AddGroup dZ, lookupFM MulGroup dZ, lookupFM EuclideanRing dZ) 
  --> 
  (Just (D1Group sG), Nothing, Just (D1EucR rE))
\end{verbatim}
\normalsize
extracts the descriptions of {\tt Z} as of additive group, and as 
an Euclidean ring. The same request for the multiplicative group 
returns {\tt Nothing} --- because {\tt dZ} does not put such term 
there, for obvious reason.


\subsubsection{ Up-functions }
\label{sec-prp.skco.up}

(Section~\ref{sec-prp.ske}, UP). 
\\
The {\it domain descriptions do not include into each other}.
\\
For example, a {\tt Subring} \ {\tt rR} \ is also an  
additive {\tt Subgroup}, and the corresponding term for this 
subgroup is extracted not from {\tt rR} but from the bundle.
\\
{\bf Example.}
\\
To create a bundle ``up to {\tt Ring}'' from the empty bundle {\tt Map.empty},
one needs to create {\tt OSet}, put it to bundle under the key {\tt Set}, 
create {\tt Semigroup} and put it to bundle under the name 
{\tt AddSemigroup}, create another {\tt Semigroup} and put it to 
bundle under the name {\tt MulSemigroup}, create {\tt Subring} and put 
it to bundle under the name {\tt Ring}. \\
The call \ \ {\tt upRing s dom} \ \ performs all this. 
Naturally, it applies {\tt upAddGroup} and some other `ups'.  
According to the category hierarchy, one up-functions apply some others.
And they are the compositions of base-functions.
\footnotesize
\begin{verbatim}
  type ADomDom a = a -> Domains1 a -> Domains1 a

                        -- up<category> :: <category> a => ADomDom a

  upAddSemigroup :: AddSemigroup a => ADomDom a 
  upAddGroup     :: AddGroup     a => ADomDom a  
  ...
  upFactrLinSolvRing :: (FactorizationRing a, LinSolvRing a) => ADomDom a

  upAddSemigroup a = fst . baseAddSemigroup a . fst . baseSet a
  upAddGroup     a = fst . baseAddGroup     a . upAddSemigroup a
  ...
  upRing a = fst . baseRing a . fst . baseMulSemigroup a . upAddGroup a
  ...
  upField = upEucFactrRing   -- here the matter is not in bundle
                             -- but in presumed conditions
\end{verbatim}
\normalsize
It is also important that creating some domain term to add to a
bundle {\tt dD} the program may use the ready terms in {\tt dD}.
For example, the property value \ {\tt v} \ in \ 
\verb#(IsPrimeGroup, v)# \ for the group term may somtimes be 
derived as 
\begin{center}  {\tt let v = Fin n = osetCard sS in isPrime n}
\end{center}
for the subset term {\tt sS} from {\tt dD}.

Which domain terms \ {\tt t} \ have to be placed in a bundle for the
domain defined by a given sample \ {\tt s} ?

{\tt t} \ is placed there when \ {\tt s} \ is of the type that 
matches the corresponding class {\it C} \ {\it and} \ the domain 
{\it D} of {\tt s} may, --- for some parameter values, --- occur of 
the category {\it C}. 
\\
{\bf Example:} 
\\ 
let \ \verb#t = GCDRingTerm {..}#, \ \ 
  {\tt  s1 = (1,2) $\in$ (Z,Z), \ \ s2 = (UPol..) $\in$ (Z/(m))[x]. }\\
Then
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt t} \ is not placed in the bundle of {\tt s1} \ 
      (of {\tt (Z,Z)}), \\
      because the type of {\tt (Z,Z)} is not an 
      instance of {\tt GCDRing} class.

\item {\tt t} \ goes to the bundle of {\tt s2} \ 
   and it has to contain \ {\tt (IsGCDRing, v)} in the property list,
   where \ {\tt v = Yes} \ for a prime \ {\tt m}, \ \ {\tt No} --- for 
   composed {\tt m}, \ \ and when this property is hard to detect, put 
   {\tt v = Unknown}.
   And the GCD category memership is defined finally by this property 
   value. See Section~\ref{sec-prp.skco.in}.
\end{itemize}



\subsubsection{ Domain by sample }
\label{sec-prp.skco.ds}

(Section~\ref{sec-prp.ske} DS). \\
Most commonly, a base domain appears as in the below example. 
It shows also an approach to residue ring in Euclidean case.

{\footnotesize
\begin{verbatim}
  instance EuclideanRing a => Set (ResidueE a)  where
    ...
    baseSet (Rse x iI aDom) rDom = case  Map.lookup Set rDom  of

      Just (D1Set o) -> (rDom, o)
      _              -> (Map.insert Set (D1Set o) rDom, o)
                     where
                     o = let  b = pirCIBase iI
                         in ... build OSet for the residue ring a/I, the bundle
                            for `a' given by  aDom,  b the generator of ideal I
\end{verbatim}
}
This is important: each residue element of domain \ {\tt a/I} \ 
contains the domain description {\tt aDom} for domain \ {\tt a} \ 
and the ideal description {\tt iI}.

So, {\tt baseSet} does not need to build the bundles for the argument
domain by new. Rather it has to combine the ready terms {\tt aDom} 
and {\tt iI}. So, in this example, \ \verb#x::a# \ is a 
representative of residue, and it can be used in \ {\tt o} \ via \ 
{\tt (baseSet x aDom)} \ to obtain a set term for \ {\tt a}.  
But this would share the ready value from {\tt aDom}.
Because the base-operations are designed so that they  proceed  to
construct the term according to the sample only if the given bundle 
does not contain this term.

But what if {\tt aDom} from \verb#(Rse..)# does not contain the set 
term?

When the programmer deals with the residue domain, one has first to 
create the descriptions \ {\tt aDom, iI} \ as shown above;
then, to copy these {\it variables} to the expressions destined to 
this particular domain \ {\tt a/iI}. The best way to do this is as 
follows:
\footnotesize
\begin{verbatim}
  let  u    = cToUPol (1:/1) "x" dQ            -- sample for Q[x],  Q = Fraction Z
       aDom = upEuclideanRing u Map.empty            -- represents Q[x]
       f    = smParse u "x^3 + ... "           -- ideal generator
       iI   = eucIdeal "be" f [] [] [(f,1)]    -- create ideal
       r    = Rse u iI aDom                    -- initial sample for residue
  in   (ctr r f1, ctr r f2, fromi r 9, smParse r "(x^2+1)*x") ...
\end{verbatim}
\normalsize
This operates with the residues in \ {\tt R = Q[x]/I, \ I = (f)}. \\
{\tt aDom} is created from {\tt Map.empty} --- this is done once.
The initial element {\tt r} for {\tt R} is set explicitly.
Other expressions for the values in {\tt R} are made after the sample
{\tt r} \\
(Section~\ref{sec-prp.ske} CS).
Also this example shows the three ways to map values to the domain\\  
{\tt R = a/I} \ of \ {\tt r} \ from other domains --- 
{\tt Z}, \ {\tt String}, \ {\tt a}.
\\
{\tt ctr r g} \ 
  extracts {\tt iI} from {\tt r}, reduces canonically {\tt g} by 
{\tt iI} to {\tt g'}, ``wraps'' {\tt g'} into the residue after 
the sample {\tt r}. 
\\
{\tt ct} \ does the same, only without reduction of {\tt g}.
     
And what if the programmer forms the residues in another style, or
maybe, forgets to feed {\tt aDom} with domains: skips the above 
{\tt upEuclideanRing} \ldots \ ?

Then, either \ \verb#(baseSet r _)# \ reports at the run-time
\begin{center}
      {\tt error "... such and such thing not found in \ aD \ for \ 
                 Rse aI aD ..."
      }
\end{center}
or it constructs the needed part of {\tt aDom} by new, according
to the representation sample {\tt x} contained in {\tt r}. 
The latter spends some computation cost.

This style, with \\
{\it sample}, up-functions, copying variables of domain terms, 
cast by sample, 
\\
supported by DoCon, is so natural that we hardly ever can imagine
avoiding it.



\newpage
\subsubsection{ Domain field in constructor. Cost of bundles }
\label{sec-prp.skco.df}

As an element often contains a domain bundle in it, creating the
sample needs up-function to build a bundle, some functions imply
searching in such bundle, maybe, inside a program loop,
--- may this ruin the performance?

No. Because
\begin{itemize}
\setlength\itemsep{0pt}
\item a sample is created once for a domain, and then, its attributes are 
   {\it shared} (Section~\ref{sec-prp.ske} (BF)),

\item bundle is built ``lazily'',

\item {\tt Map.lookup, Map.insert} \ cost \ $O(\log N)$, \ for a bundle, 
   \\ 
   $N < length(CategoryName-list)$, \ so, in DoCon, \ 
   this cost is not more than \ $\log_2 20$ \ key comparisons,

\item all the important domain constructors {\it C} have a data
      field for an argument domain bundle 
      (Section~\ref{sec-prp.ske} (BF)).
\end{itemize}
We would only add that the bundle processing is 
{\it less desirable in the inner loops}.
\\
{\bf Example:} \ consider the program of kind
\begin{center}
{\tt let rs = [$r_1$..$r_{1000}$] :: [T] in (sum rs, foldl1 gcD rs)}
\end{center}
For {\tt T = Z}, bundles never appear here, only \ 
{\tt (+)}, {\tt gcd} \ run in the loop.

For \ \verb#T = UPol (ResidueE Z) <-> (Z/(p))[x]#, \ --- 
polynomial over residue, --- {\tt gcD} of {\tt DoCon} gets each time into 
the sample, into the sample of coefficient, finds the ideal generator
{\tt p}, checks the property value {\tt isField} for the sample for 
{\tt Z/(p)}. But even here, this does not increase the cost any 
essentially. Because the {\tt isField} value is shared, and 
{\tt (+)}, {\tt gcD} for a polynomial over {\tt Z/(p)} cost much 
more on average than this {\tt isField} test. Besides, {\tt (+)} in  
{\tt Z/(p)} needs the reduction by {\tt p} in any case, {\tt gcD}
needs in any case the inversion for several coefficients in 
{\tt Z/(p)} --- this costs much more that the ideal generator 
extraction.
  
So, we have an idea of the relative cost of bundles.



\subsubsection{ Meaning of instance declaration }
\label{sec-prp.skco.in}

Certain small {\it property value list} supported by DoCon,
may help to define which of the category instances are  correct 
for the sample. The cost of such check is usually small --- see 
Section~\ref{sec-prp.skco.df}.
\\
{\bf Example 1.} 
\\
For the Euclidean residue constructor \ {\tt Rse}, \ {\tt DoCon} defines 
the addition (of AddSemigroup) in \ {\tt a/I} \ as
\footnotesize
\begin{verbatim}
  instance EuclideanRing a => AddSemigroup (ResidueE a) where
    ...
    add r1 r2 = ifCEuc r1 "A" (("add r1 r2,"++) . showsWithDom r1 "r1" "") $
                       ctr r1 $ add (resRepr r1) (resRepr r2)
\end{verbatim}
\normalsize
The last line \ \ {\tt add \ldots} \ \ forms the true result: sums
the residue class representatives and casts to the residue ring by 
the sample {\tt r1}. This casting is done by taking of the Euclidean 
remainder \ \ {\tt x -> remEuc 'r' x b} \ \ by the ideal base {\tt b}
contained in {\tt r1}.

The \ \ {\tt ifCEuc \ldots} \ \ line tests whether the ring is 
c-Euclidean: extracts the Euclidean ring term from {\tt r1} and 
looks there into the properly value list.
What happens if we skip the \ \ {\tt ifCEuc \ldots} \ \ part?

Then, it might look like
\begin{center}
        \verb# careless_add r =  ctr r . add (resRepr r) . resRepr #
\end{center}
Then, for example, for \ {\tt a = P = P(2) = (Z/(m))[x], \ \ m = 2,}
\\
\verb#careless_add# \ causes \ \ {\tt remEuc 'r' (f+g) b} \ \   
--- the remainder division of polynomials. The result is correct.

For \ {\tt m = 4}, \ {\tt P} still has formally the instance of 
{\tt EuclideanRing} class. And here \\ 
{\tt remEuc 'r' (f+g) b} \ \
may yield an incorrect result\\ 
(why apply Euclidean residue to {\tt P(4)} if {\tt P(4)} is not 
Euclidean?).

And for more safety, {\tt DoCon} tests this correctness condition in \ 
{\tt add} \ and in some other operations for {\tt a/I}.

Each time {\tt x+y} applies in {\tt a/I}, the property value is 
searched in certain list extracted from {\tt x}. 
Can this ruin the performance?

It cannot. Because
\begin{itemize}
\setlength\itemsep{0pt}
\item of `sharing' of a property value in a domain term \ 
      (Section~\ref{sec-prp.ske} (BF)),

\item the property list is small,

\item for a polynomial ring \ {\tt a}, \ the remainder division 
      costs not less than the search in the property list, and 
      usually, costs much more.

\item for \ {\tt a = Z}, \ even this fast test is not necessary: \ 
      {\tt DoCon} declares special category instances for \ 
      {\tt ResidueE Z}, \ there the \ {\tt add} \ definition skips \ 
      {\tt ifCEuc}.
\end{itemize}

{\bf Example 2:} \ \ {\tt DoCon} contains the declaration
\begin{center}
               \verb# instance EuclideanRing a => Field (ResidueE a) #
\end{center}
It means that for the residue ring \ {\tt R = a/iI} \ of an Euclidean ring 
defined by a sample \\ 
\verb#r = Rse x iI aD :: ResidueE a#, \ \
it depends on the primality of {\tt iI}, whether {\tt R} is a 
{\it field}. This primality can be checked fast by looking into 
the part of {\tt iI} presenting the generator factorization.

Further, if the above declaration included the definition for some 
specific {\tt Field} operation, for example, {\tt dimensionOverPrimeField},
then the aforementioned attribute in {\tt iI} would be actually a 
{\it correctness condition} for an algorithm put for the
{\tt dimensionOverPrimeField} definition.


{\bf A drawback:}
\\
in DoCon, a category declaration has more complex meaning, puts
less static restrictions, than it is in the purely static approach 
to domain.
In particular, it is often on the programmer, not to mix wrongly the 
data from different domains inside the same type. 

Still  {\tt DoCon} keeps  on  with  the   half-dynamic,  sample-dependent 
domains.
Because with the purely static  model,  there  are  impossible,  for 
example, nice programs for the Chinese remainder method,  and  other
useful algorithms.
The above method needs constructing of many residue rings {\tt a/(p)}, 
and sometimes one cannot even predict, how many different {\tt a/(p)}
would suffice.
With DoCon, the user program has  only  to  form  dynamically  the 
samples \ \verb#r(p) = Rse _ iI(p) aD# \ \ for the residues.

More example: \\
the dynamic change of the {\it power product ordering} 
(Section~\ref{sec-pol.rp}) solves some tasks for the multivariate 
polynomials, or may help to reduce the computation cost.
And in DoCon, this ordering is a part of a {\it polynomial sample}.  
Changing it means changing to another isomorphic copy of a given 
polynomial ring.



\subsubsection{ Static domain alternative }
\label{sec-prp.skco.st}

Suppose we add the constructor classes \ {\tt SIdeal, MaximalIdeal} \ 
for the `static' ideals {\tt I} in an Euclidean ring \ {\tt a},
\\
SIdeal  \ \ \ \ \ \ \ \ \ \ --- with, say the ideal base operation, 
\\
MaximalIdeal \    --- with, say inversion operation modulo {\tt I}.
\\
Then, for the constructor \ {\tt i}, \ the \ {\tt Ring, Field} \ 
instances for  
\begin{center} \verb# R = StaticResidue i a   <-->  a/I #
\end{center}
can be defined depending on the existence of the static instances \ 
{\tt SIdeal, MaximalIdeal}\\
for {\tt i}.

With this approach, quite natural for {\tt Haskell}, the correctness  
of the \ {\tt Field a} \ instance is solved statically.
And the meaning of the category declaration becomes straight.

Still DoCon remains only with the dynamic ideals.

Besides the reasons for this explained in previous subsection, 
recall that an ideal in the above domain \ {\tt a} \ is defined 
usually by the base \ {\tt b}.
After {\tt b} is defined in the program as, say \ \ {\tt b = f x}, \ \
declaring     
\begin{center}  {\tt instance Maximaldeal I1 a}
\end{center}
for the ideal \ {\tt I1 = (b)} \ in \ {\tt a} \ presumes that \ 
{\tt b} \ is prime. Such declaration makes sense only when it is  
known statically that \ {\tt b} \ is prime. And often this is not 
the case.

In other words, the static representation of an ideal  fits  better
the {\tt Haskell} language nature,  
but does not reflect the dynamic nature of correspondence between the  
ideals and ideal generators.



\subsubsection{ Treating properties }
\label{sec-prp.skco.pr}

{\tt DoCon} operates with certain small set of algebraic domain properties.
The property values, such as \ {\tt IsGroup = Yes | No | Unknown}, \    
are set in the domain terms. \\
These property lists are introduced because \\
(a) such property evaluation is itself an important function of system, 
\\
(b) domains are often parametric, usually, a property list helps to
determine the true computation domain.

Many of the property requirements only accompany the program texts 
as comments --- to prevent the programmer from applying functions 
to mathematically incorrect data.
But often {\tt DoCon} derives these property values automatically, 
following the construction of the domain, properties of the argument 
domains, and using certain restricted set of rules. These rules  
are simple and follow classic algebra. They are like this:
\begin{verbatim}
  IsField      ==> Euclidean,        Euclidean ==> not HasZeroDivisor, 
  IsMaxIdeal I <==> IsField (R/I),
  Factorial R  <==> Factorial (R[x1,...,xn]),   and so on.
\end{verbatim}





\subsection{ Subdomain }
% ----------------------
\label{sec-prp.sub} 

How does one compute in (over) a subdomain, for example, subgroup of 
even integers?  Or maybe, factor a polynomial over some subfield of 
a field $K$?

Commonly --- by introducing a constructor and defining new domain, new
instances --- see ``New sub-domain'' below.

{\bf Induced subdomain} \ 
is viewed as a subdomain bundle together with the category operations 
induced from the base domain.  It is implicit. 
\\
{\bf Examples:} \\
\verb#sPI :: Subsemigroup Z# \ \ may describe the 
{\it Positive Integer} subsemigroup in {\tt Z}.   
The restriction of \ {\tt add} \ from {\tt Z} is correctly
described by {\tt sPI}, but the restriction of \ \verb#neg_m# \ 
does not fit {\tt sPI}.
With this, factoring polynomial over a sub-domain is impossible.

{\bf New subdomain} \ 
is simply another base domain, with its new constructor and related 
instances. \\
{\bf Example:} \ \ 
{\tt DoCon} has not a natural number monoid. The user may introduce it:
\begin{verbatim}
  newtype Natural = N Z  deriving (Eq, Ord)  -- in  N n,  n >= 0 presumed
  instance Set Natural where 
                       baseSet _ _ =  ... membership = (>= 0) ...
\end{verbatim}
Operation \ \verb#neg_m# \ has to be defined here differently than in 
{\tt Z}, and so on.



\subsection{ Advancing with category declarations }
% -------------------------------------------------
\label{sec-prp.ctad} 

The category hierarchy is expressed naturally by declarations like
the following.
\footnotesize
\begin{verbatim}
class (Eq a, Show a) => Set a                          -- partially ordered set
  where
  compare_m  :: a -> a -> Maybe CompValue                   -- partial ordering
  showsDomOf :: a -> String -> String                       -- for messages
               --sa 
  fromExpr   :: a -> Expression String -> ([a], String)             -- parse
               --sa  e                          messg

  baseSet    :: a -> Domains1 a -> (Domains1 a, OSet a)   -- description of set
\end{verbatim}
\normalsize
This means that any instance of the Equality and Printable standard 
{\tt Haskell} classes can be made an algorithmic Set instance by 
implementing the operations \ {\tt fromExpr}, \ 
\verb#compare_m#, \ {\tt baseSet}. Here
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt showsDomOf smp} \ \
  prints to String a short description of domain defined by the 
  sample {\tt smp}. It is used in error messages.

\item {\tt fromExpr}, \ \ together with Haskell's \ {\tt shows},\\
      serve to parse and print between a domain element and a string. 

\item {\tt baseSet} \ \ is explained in 
      (Section~\ref{sec-prp.ske} (BO),(BSE)) and in further sections.
\end{itemize}

Further,
\footnotesize
\begin{verbatim}
  class Set a => AddSemigroup a  
    where
                        -- REQUIRED: `add' associative, commutative, agreed with (==)
    add     :: a -> a -> a
    zero_m  :: a -> Maybe a   -- sa
    neg_m   :: a -> Maybe a
    sub_m   :: a -> a -> Maybe a
    times_m :: a -> Z -> Maybe a
    baseAddSemigroup :: a -> Domains1 a -> (Domains1 a, Subsemigroup a) 
                     -- sa
\end{verbatim}
\normalsize
So {\tt AddSemigroup} inherits by default the operations from {\tt Set}, 
(and of supercategories {\tt Show, Eq} of {\tt Set}) 
and exports the operations of its own. 
It proclaims that a {\tt Set} instance can be made an additive  
semigroup instance by adding the above operations. Zero (\verb#zero_m#)
and opposite element \verb#neg_m# are presented as partial maps. \
\verb#zero_m s# \ has a sample argument \ {\tt s} \ 
(Section~\ref{sec-prp.ske} SA).

In this manner, {\tt DoCon} adds \ {\tt AddGroup}, {\tt MulSemigroup} \
categories. Then, it declares
\begin{verbatim}
  class (AddGroup a, MulSemigroup a, Num a, Fractional a) => Ring a
    where
    ...
\end{verbatim}
which puts that the operations \ 
\verb#(+) = add,  (*) = mul,  0 = zeroS _,  1 = unity _#
\\
form a {\tt Ring} --- under certain presumed conditions on these 
operations.
And so on, down to the leaves of the category tree shown on the 
picture in Section~\ref{sec-prp.hr}.

Some of the category declarations show no operations. For example,
\begin{center}
    \verb# class (EuclideanRing a, FactorizationRing a) => Field a #
\end{center}
only asserts in its accompanying commentary that \ \verb#inv_m# \ 
of \ {\tt MulSemigroup a} \ has to satisfy certain property.



\subsection{ Algebraic data and functors }
% ----------------------------------------
\label{sec-prp.fu}

{\bf Example 1.}
\\  
{\tt (1,'b')} \ is an element of the direct product of domains  
{\tt Z}, \ {\tt Char}. \\ 
{\tt (,)} \ is the data constructor from {\tt Haskell}.
{\tt DoCon} relates to it a finite set of instance declarations
\footnotesize
\begin{verbatim}
  instance (Set a, Set b) => Set (a,b) where ...

  instance (AddSemigroup a, AddSemigroup b) => AddSemigroup (a,b) 
    where 
    add (x,y) (x',y') = (add x x', add y+y')
    ...
\end{verbatim}
\normalsize
--- up to \ {\tt Ring} \ldots \ {\tt LinSolvRing}.
Here \ {\tt add x x'}, \ {\tt add y y'} \ apply the \ {\tt add} \ 
operation from \ {\tt AddSemigroup} instance of \ {\tt a} \ and 
\ {\tt b} \ respectively.

This relates to the data constructor \ {\tt (,)} \ the functor of 
direct product of sets, functor of direct product of additive 
semigroups, and so on. But the instances  
\begin{center}
              \verb# ... => EuclideanRing (a,b), ... Field (a,b) #
\end{center}
are {\it not} declared. For, evidently, the direct product of rings
cannot be an Euclidean ring. So, {\tt DoCon} adds several {\tt DoCon} instances 
to the standard {\tt Haskell} instances for {\tt (,)}.
The effect of these declarations is that setting in the program the
expressions like
\begin{center}    \verb# let p = (a1,b1) in  p + (c,d)*(c,d) #
\end{center}
with \ \verb#a1, c :: Ring a => a,  b1, d :: Ring b => b#,
\\
causes the operations \ \verb#+, *# \ to be resolved in the sense 
of the aforementioned instances for {\tt (a,b)}.


\newpage
{\bf Example 2.} \ \  
{\tt DoCon} introduces an univariate polynomial as
\begin{center}   
               {\tt  data UPol a = UPol [UMon a]} \ldots
\end{center}
--- a name \ {\tt UPol} \ serves both as a type and data constructor.
The declaration
\footnotesize
\begin{verbatim}
  instance CommutativeRing a => AddSemigroup (UPol a) 
    where
    add (UPol mons ...) (UPol mons' ...) = UPol (addpol mons mons') where ...
\end{verbatim}
\normalsize
defines for any commutative ring \ {\tt a} \ an additive semigroup 
instance on {\tt a[x]}. The addition is expressed by the 
implementation part \ {\tt addpol} which applies \ \verb#zero_m#, \
{\tt add} \ of coefficient domain \ {\tt a} \ to sum the 
coefficients. And so on, up to 
\begin{center}   
       \verb# instance Field a => EuclideanRing (UPol a) ..., #            
\end{center}
and some other instances.
This brings the usual mathematical meaning to expressions like \ 
{\tt f/(gcD f g)} \ with \ \verb#f, g :: Field a => UPol a#.

More example: \ for \ \verb#f, g :: UPol (Z, Fraction Z)#, \\
\verb#f - f*g# \ \ also has usual algebraic meaning, it evaluates 
via the operations in the ring \\
{\tt (Z $\oplus$ Q)[x]} \ --- 
coefficients are from the direct sum of the integer and rational 
number rings. This is due to the instances that {\tt DoCon} declares for \ 
{\tt Z}, \ {\tt Fraction}, \ {\tt (,)}, \ {\tt UPol} \\  
domain constructors.



\subsection{ User program design }
% --------------------------------
\label{sec-prp.usr} 
    
With DoCon, it consists mostly of adding the data types, categories,
implementing for these data the category instances (new or of DoCon, 
or the standard {\tt Haskell} ones), adding instances to the data 
constructors of DoCon, or {\tt Haskell}.  Naturally, the  user  items 
(data, functions, instances \ldots) may refer to the {\tt DoCon} ones.
For example, {\tt DoCon} does not provide the trigonometric expressions.
The user design for this might be
\footnotesize
\begin{verbatim}
  data TrigExpr a = TrigGround a | Sin (Trig a) | Cos (Trig a) ...

  instance RealField a => Eq (TrigExpr a) 
    where 
    (TrigGround x) == (TrigGround y) =  x==y
    (Sin e1      ) == (Sin e2      ) =  ... implement some reasonable (partial)
                                            equality on the type TrigExpr a
  ...
  instance RealField a => Set (TrigExpr a)  where ...
  instance RealField a => AddSemigroup (TrigExpr a)  
    where 
    add (TrigGround x) (TrigGround y) = (TrigGround (x+y))
    add (Sin ...)      ...            = ...
\end{verbatim}
\normalsize
--- and so on



\subsection{ df and ndf domain constructors }
% -------------------------------------------
\label{sec-prp.df}

The \ ndf \ {\tt DoCon} constructors (``no domain field'') are 
\begin{center}
       {\tt Char, Z, \ \ Permutation, \ [], (,), \ \ Vector, Fraction}
\end{center}
They do not provide a data field for an argument domain.

All the rest {\tt DoCon} constructors are \ df \ --- ``with domain field''.

The difference is in the cost control of the bundle builders. 
For ndf, they build the domains mostly by new, and recursively. 
For df --- mostly, by taking the domains from the parameter fields of
constructors.

{\tt DoCon} could avoid ndf at all. For example, treat a direct product as
\begin{center}   
            {\tt  data Pair a b = Pr a b (Domains1 a) (Domains1 b) }
\end{center}
But we think, it is better to remain with the mentioned above \ ndf.
The reasons for this are that this \\
(a) simplifies denotations, \\
(b) is unlikely to cause much additional computation.
\medskip

The latter is explained as follows.
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Char, \ Z, \ Permutation} \ \ 
      do not need a domain parameter at all.

\item {\tt [,]} \ \ makes only a \ {\tt Set}, \ 
                        {\tt DoCon} does not need any more instances for it.

\item {\tt Fraction} \ \ cannot apply twice for different arguments 
      in any tower of ndf constructors. Because \\
      {\tt Fraction [a], \ Fraction (a,b)} \ \ \ are senseless, \\
      {\tt Fraction (Fraction a) === Fraction a} \ \ 
      (why apply it twice?).

\item {\tt (,), \ Vector} \ \ often produce the final domain, 
                             not subjected to further constructors.
\end{itemize}




\newpage
\subsection{ Algorithms for constructors }
% ----------------------------------------
\label{sec-prp.alm}

The underlaying mathematics for the constructor implementation is
classical. \\
Let us sketch it. 
\bigskip

\underbar{{\bf Fraction}}
\medskip

As usual, a fraction can be cancelled correctly over the (factorial)
GCD-ring {\tt R}.\\
In particular, {\tt R} has the operation \ {\tt gcd}, \
and has \ {\tt canInv} \ for the canonical invertible element
\cite{BL,Da}. This gives rise to the arithmetic of the fraction 
field \ {\tt Fraction R}.
\bigskip

\underbar{{\bf Pol}}
\bigskip

For the \ {\tt CommutativeRing R} \ and the polynomial ring 
$$
                   P = R[vars] = R[x_1,\ldots,x_n]
$$
defined by the sample element  
\begin{center}
  \verb# Pol <monomials> r ord vars dR,   r :: R, vars :: [PolVar], # 
\end{center}
the {\tt Set} instance (and all the extensions) depends on the  
indeterminate list \ {\tt vars} \ and the power product ordering \ 
{\tt ord}.
The arithmetic \ \verb#(+), (-), (*), (^), (/)# \ is evident. \\
The gcd operation is given, say by the subresultant algorithm --- 
provided {\tt R} is a gcd-ring --- see Section~\ref{sec-pol.a.g}. 
Factorization in \ $R[x], R[x,y]$ \ is provided for some $R$ --- 
see Section~\ref{sec-pol.a.f}.

{\tt UPol, \ RPol} \ \ are similar. {\tt UPol} \ also has 
\begin{center}
           \verb# instance Field k => EuclideanRing (UPol k) ... #
\end{center}
\medskip


\underbar{{\bf Residue ring}}
\medskip

For 
\begin{itemize}
\setlength\itemsep{0pt}
\item a ring \ {\tt R} \ of category \ {\tt LinSolvRing} \\
      possessing the attribute \ {\tt (IsGxRing, Yes)} \ 
      (Section~\ref{sec-linr}),

\item and ideal \ {\tt I} \ in {\tt R} supplied with generators \ 
      {\tt rs} \ and possessing \ (IsGxBasis, Yes) \ in its property list,
\end{itemize}
any sample element \ \ \ \ \ \ \ \ \ \ \ \ \ \ \verb#Rsi x di dR,  x :: R#
\\
defines the ring of residues. 
\\
{\tt di} \ \ contains the ideal term {\tt iI}.\\
{\tt x} \ \  has to be a canonical representative modulo {\tt iI}. 
Such representative can be found by reducing by the generators contained 
in {\tt iI}, under the condition of {\tt (IsGxBasis, Yes)}.
Here follow the particular cases, when {\tt DoCon} can compute such 
generators for {\tt iI}.

For the so-called c-Euclidean ring (Section\ref{sec-euc}), any \
{\tt rs = [r]} \ with non-zero \ {\tt r} \ is a GxBasis, and 
reduction is represented by Euclidean remainder \ {\tt remEuc 'c'}.

For  \ $P = R[x_1,\ldots,x_n]$, \ $R$ \ a c-Euclidean ring,
a gx-basis is a weak reduced Gr\"obner basis.

Further, for the direct sum \ $R \oplus U$, \ the gx-bases are 
defined via the generator lists that have the gx-bases as their 
projections. In all these cases, the canonical form for a residue 
element is evident, as well as the algorithms for the operations  \ 
\verb#+, -, *, ^# \  --- see Section~\ref{sec-gx}.

A partial operation \ \verb#(divide_m b a)# \ 
is generally treated as solution of linear equation \\
$a*x = b$. \ \ 
It has to find {\it any} solution or return \ {\tt Nothing}. 
Together with {\tt syzygyGens}, this yields the generic solution.
For a c-Euclidean ring $R$, such division in \ $R/(d)$ \ 
can be done via the extended gcd algorithm:
\begin{verbatim}
                 u*d + v*b = g = gcd(a,b);           q = a/g;
                 quotient = canonicRemainder(q*u, b)
\end{verbatim}
For a gx-ring, say polynomials over a field, we use similarly 
{\tt gxBasis}, which can be considered as the generalization for
the mentioned above extended gcd method. See Sections \ref{sec-linr}, 
\ref{sec-gx}.

And so on, for other constructors.



\subsection{ No limitations. Generality }
% ---------------------------------------
\label{prp.lim} 

{\tt DoCon} is very generic.
Thus, \\
{\bf (1)} integer, rational number, list or vector size, 
   power product and its entity --- may be arbitrary large,
\\
{\bf (2)} polynomials are considered under any indeterminate list 
  and arbitrary comparison function for the power products,
\\
{\bf (1)} sorting takes in the argument any comparison function and 
  returns also the permutation sign, 
\\
and so on.




\newpage
\subsection{ Parsing, unparsing }
% -------------------------------
\label{sec-prp.pars}

\underbar{{\bf Unparsing}}
\medskip

is writing to {\tt String}. {\tt DoCon} does it via the {\tt Haskell} \ {\tt Show} 
class, with its operations \ \ {\tt shows}, {\tt show}.
\\
{\bf Example:} 
\footnotesize
\begin{verbatim}
  instance MulSemigroup a => Show (Fraction a)
    where
    showsPrec _ (n:/d) = if d==(unity d) then  shows n
                         else              ('(':) . shows n . ('/':) . shows d . (')':)
\end{verbatim}
\normalsize
This enables to ``print'' things like this:
\begin{verbatim}
                   show (1:/2 :: Fraction Z) --> "(1/2)"
                   show (2:/1 :: Fraction Z) --> "2"
\end{verbatim}
\medskip


\underbar{{\bf Parsing}}
\\
is reading from {\tt String}. This is more complex. 
{\tt DoCon} uses for this the operation
\begin{verbatim}
                fromExpr ::   a -> Expression String -> ([a], String)
                           -- sa        
\end{verbatim}
of the class \ {\tt Set}. But before this, the \ {\tt Set, Show} \ 
instances should be declared.

The generic {\it parsing by sample} 
\begin{center}                      {\tt smParse} 
\end{center}
is the composition of the functions \ \ 
                             {\tt lexLots, \ infixParse, \ fromExpr}.
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt lexLots} \ \ splits a string to lexemes.

\item {\tt infixParse} \ \   
  takes a lexeme list and produces a syntactic tree, --- 
  {\tt Expression}, --- with the lexemes in the leaves.
  At this stage, the infix operations, as \verb#+, *#, and others, 
  have no more sense beyond their signature and precedence.

\item {\tt fromExpr} \ \ gives an interpretation to the 
      {\tt Expression} \ according to the sample element of domain.
      It should be programmed for each domain.
\end{itemize}
%
{\tt smParse} \ is defined as follows: 
\footnotesize
\begin{verbatim}
  smParse :: Set a => a  ->  String -> a
  smParse             sample s      = 
    case  
        infixParse parenTable opTable $ lexLots s
    of
      ([e], "" ) -> case  fromExpr sample e  of
                                   ([x],"" ) -> x
                                   (_  ,msg) -> error (..."bad string for sample"...)
      (_  , msg) -> error (..."infixParse:  "++msg++"\n")
\end{verbatim}
\normalsize
%
{\bf Example.} \ \ For \verb#  str =  " (1+2, 1 ) ",  #
\begin{verbatim}
  smParse ((1,1) :: (Z,Z)) str              --(infix . lexLots)-->

  (E "," (E "+" "1" "2") "1") =  e   :: Expression String      -->

  fromExpr ((1,1)::(Z,Z)) e                                    -->  (3,1)
\end{verbatim}
Further, \ \ 
        \verb#smParse ((1:/1, 1) :: (Fraction Z, Z)) str  -->  (3:/1, 1)#
\\
--- changing the sample changes the parser for the domain.
This is because the \ {\tt fromExpr} \ instance changes.
Very naturally, {\tt fromExpr} is defined recursively, following the type 
\\
(or domain) construction.

{\bf More example:} \ \ 
for a polynomial, a sample element contains  also  the  list  of
indeterminates (variables) which are recognized in the {\tt Expression} 
by \ {\tt fromExpr} \ function.
Also \ {\tt smParse}  uses these indeterminates to display the polynomial.
See  \ {\tt Set}, \ \ Section~\ref{sec-pars}, \\ 
and the files \ {\tt source/parse/princip.txt}, \ \verb#Iparse_.hs#.

Why do we need this intermediate {\tt fromExpr} and conversion to
{\tt Expression} ?  \\
Is not it simpler to parse straight from {\tt String}, exploiting \ 
{\tt lex} ?
For example, to parse \ \verb#(n:/m) :: Fraction a# \ \ from \ 
{\tt str},
\\
parse the element of \ {\tt a} \ from {\tt str} (recursion); then  \
{\tt lex} \ gets \ \verb#:/#, \ then parse element of \ {\tt a} 
--- ?

We tried this, but met the difficulty with parsing the elements of
domains like \\ 
$((R[x])[y])[z].$  \ \
It is hard to define for the strings like \ \ \verb#" y*2*x + z "#,
\\
where the ``coefficient'' or ``monomial'' ends with \verb#"y"#, \ 
or maybe, with \verb#"z"# \ respectively.

Instead, {\tt infixParse} \ sets the parentheses systematically, 
and then, {\tt fromExpr} is simple to define.



\newpage
\section{ Usage of Haskell Prelude }
% ----------------------------------
\label{sec-prel}


{\tt DoCon} exploits the {\tt Haskell} Prelude items and the Standard
libraries.
But for some of operations it adds its own counterparts.
It coexists peacefully with the {\tt Haskell} Prelude and 
Standard libraries, and never changes the Prelude operation
meaning for the Prelude domains or constructors.

Here follow some points concerning the interaction with Prelude.
\bigskip

\underbar{{\bf No Int :}} \ \ \ \
{\tt DoCon} uses only \ \ {\tt type Z = Integer} \ \ for the ring of integers.
\bigskip

\underbar{ {\bf No} \ {\tt\bf fromInteger :} }
\medskip

{\tt DoCon} relies instead on operation \ \ {\tt fromi s} \ \
--- map from {\tt Integer} by sample.
\\
{\bf Examples:}
\begin{verbatim}
  (2, 3) + 4 :: (Z, Z) --> error "... Undefined member: fromInteger",
        
  let  p         = (2, 3) :: (Z, Z)
       (p1:p2:_) = map (fromi p) [1 ..] 
  in   p + p2*p2                         --> (6, 7)
\end{verbatim}
\medskip

\underbar{{\bf List processors}} \ \ {\tt minimum, maximum, sort, sortBy}.
\medskip

are re-implemented.
In particular, to import the {\tt DoCon} definitions for them, the program has 
to specify the import like this: 
\begin{verbatim}
                import List hiding (minimum ...)
                import DPrelude    (minimum ...)
\end{verbatim}
This is the choice of DoCon's taste. For example, {\tt DoCon} prefers ``merge''
algorithm for sorting, and some {\tt Haskell} implementations prefer 
``quickSort'' (faster on average, and \ $O(N^2)$ \ in the worst case).
But the situation may change. Besides, this issue is not so important.
The user is free to import the variant one likes.
\bigskip


\underbar{{\bf sum1, product1 \ instead of \ sum, product}}
\medskip

For \ {\tt Z}, \ there is no difference.
But for other lists \ \ \verb#xs :: Ring a => [a],#
\\
apply \ {\tt sum1 xs}, \ {\tt product1 xs}. \ 
They are for non-empty lists.

If \ {\tt xs} \ may occur empty, then apply  
\begin{center} 
  {\tt sum1 ((zeroS s):xs)} \ \ or \ \ {\tt product1 ((unity s):xs)}
\end{center}
respectively --- with any sample element \ {\tt s} \ for the 
needed domain. This is because the {\tt Haskell} Prelude initiates \  
{\tt sum}, {\tt product} \ with \ \ 
{\tt fromInteger 0}, \ {\tt fromInteger 1}, \ \ 
while {\tt DoCon} has \ \verb#fromi <sample># \ \ instead of \ 
{\tt fromInteger}.
\\
{\bf Example:}
\footnotesize  
\begin{verbatim}
  sum  [(1,2),(3,4)]  :: (Z,Z)  --> "error: Undefined member: fromInteger"
  sum1 [(1,2),(3,4)]  :: (Z,Z)  --> (4,6)
\end{verbatim}
\normalsize  
\medskip

\underbar{{\bf Classes \ Prelude.Eq, Prelude.Show :}} 
\medskip

{\tt DoCon} relies on them. See (Section~\ref{sec-prp.ske} (BSE)) on {\tt Eq}.
\bigskip

\underbar{{\bf Read :}}  
\\
instead it, {\tt DoCon} applies \ {\tt smParse, fromExpr} \ --- 
see Section~\ref{sec-prp.pars}.
\bigskip

\underbar{{\bf Prelude.Ord}}
\medskip

includes into the {\tt DoCon} hierarchy with the condition of \ 
\verb#compare_m# \ to agree with \ {\tt compare}:
\footnotesize
\begin{verbatim}
  class (Ord a, Set a) => OrderedSet a
    -- Presumed:
    -- on the base set BS,  compare_m  possesses (OrderIsTotal, Yes),
    -- and agrees with `compare': (compare_m x y)==(Just $ compare x y)
\end{verbatim}
\normalsize
For other domains, of {\tt Set}, but not of {\tt Ord},  \ 
\verb#compare_m# \ may differ, for example, may be defined as \ 
{\tt compareTrivially}.
Note also that the {\it property list} of the base set contains certain
information on \ \verb#compare_m#. 
\bigskip

\underbar{{\bf On unlucky Num, Fractional}}
\medskip

We think (see the paper in \cite{Me2}) that the {\tt Haskell-98} 
standard categories \\ {\tt Num}, {\tt Fractional}, {\tt Integral} \ \
are not reasonably organized from mathematical point of view.

But {\tt Haskell} relates to them the names \verb#+, -, *, ^, / ...#,
\\ 
And {\tt DoCon} likes to use these names. So, it includes these classes into 
its categories in a following way. 
Any domain with the {\tt Ring} instance has the operations
\begin{center} 
                {\tt add, \ neg, \ sub, \ mul, \ power, \ divide},
\end{center}
some of them --- with their \ \verb#_m# \ counterparts. 
\\
{\tt DoCon} puts \ \ {\tt Num}, \ {\tt Fractional} \ \ 
to be the superclasses for {\tt Ring}:
%
\begin{verbatim}
  class (AddGroup a, MulSemigroup a, Num a, Fractional a) => Ring a
    where
    ...
    -- presumed:
    -- ... (+) = add, (*) = mul  obey the ring laws,  (/) = divide
\end{verbatim}
%
Concerning {\tt Haskell}'s \ \ 
                      {\tt abs}, \ {\tt signum}, \ {\tt fromInteger}: 
\\
{\tt DoCon} uses them, for example, for {\tt Z}, but in general case, it 
relies on
\begin{verbatim}
          absValue :: AddGroup a => a -> a
          absValue x = if less_m x $ zeroS x  then  neg x  else  x
\end{verbatim}
and on \ \ \verb#times(_m)# \ of {\tt AddSemigroup}, \ \ 
                                        {\tt fromi} \ of {\tt Ring}.


\newpage
\underbar{{\bf Unlucky Prelude.Integral}:}
\medskip

{\tt Haskell-98} Prelude provides this class, probably, as the merely
a holder for {\tt Integer} and {\tt Int}.

{\tt DoCon} applies sometimes the operations from {\tt Integral}, say \
{\tt quotRem} --- but {\it only} for {\tt Integer}. \ 
For the general purpose (for {\tt Integer} too), it has the 
\ {\tt EuclideanRing} \ category with its operations \ \ 
{\tt divRem}, {\tt eucNorm}.
\medskip

{\bf Caution:} \ 
the {\tt Haskell} class {\tt Integral} does not express what is 
called `integral domain' in classic algebra. Rather it intends the 
meaning `isomorphic to Integer'.

For example, {\tt Haskell}'s \ \ \verb#Integral a => Ratio a# \ \ 
applies \ {\tt divMod, sign, (<)} \ to cancel fractions --- which is 
not so appropriate for the polynomials over a field.

Instead, {\tt DoCon} defines the categories \ 
{\tt GCDRing}, {\tt EuclideanRing}, \ and so on --- 
which allow the generic {\tt Fraction} constructor.
Concerning \ {\tt divRem}, \ the main difference is that it does 
not rely on the ordering (sign of remainder and such attributes).
And \ {\tt divRem} \ extends naturally to a polynomial domain \ 
$k[x]$ \ for a field \ $k$, \ some quadratic integer rings, and 
so on.
\bigskip

\underbar{{\bf No Ratio :}}
\medskip

instead, {\tt DoCon} introduces the \ {\tt Fraction} \ constructor, with 
its operations \ \verb#:/#, \ {\tt canFr}.

{\tt DoCon} uses slightly different algorithms for the fraction sum,
product, and such. 
Also {\tt Fraction} is related to the {\tt GCDRing} category of 
{\tt DoCon} and the property values as {\tt IsGCDRing}, and so on. 
See Section~\ref{sec-fr}.
\bigskip


\underline{{\bf Sorry for `floating point' numbers:}}   
\medskip

{\tt DoCon} does not provide any instances for them \\
(for the types {\tt Float}, {\tt Double}, {\tt Complex} \ldots), 
just never got around.

{\bf Caution:} \ \  
these types of {\tt Haskell-98} have the operations \ \verb#+, *, 0, 1# \
of class {\tt Num}, but their definition does not satisfy the  
{\tt AddSemigroup} law, or {\tt MulSemigroup}, and such.
So, it hardly makes sense to declare such instances for them.
Probably, they need some other treating.

Generally, the paper \cite{Me2} suggests the Prelude algebra 
improvement for future {\tt Haskell}.




\newpage
\subsection{ Avoiding name clashes with Haskell }
% -----------------------------------------------
\label{sec-prel.nmc} 

\underbar{{\tt zero}} \ \ 
  is certain pre-defined {\it monad} from {\tt Haskell}.

  {\tt DoCon} uses \ \verb#zero_m#, \ {\tt zeroS} \ \ to form zero element.
\medskip

\underbar{{\tt partition}} \ \ 
  of {\tt Haskell} library breaks a list by a predicate.

  {\tt DoCon} uses \ {\tt partitionN} \ for the repeated {\tt partition}. 
  \\
  And the \ {\tt type Partition} \ refers to Young diagrams.
\medskip

\underbar{{\tt gcD, lcM}} \ \
  are of {\tt DoCon} \ {\tt GCDRing} category, they take a list of elements
  in argument. \\
  And \ {\tt gcd, lcm} \ are of {\tt Haskell} Prelude.
\medskip

The most clash-dangerous global names from {\tt DoCon} are
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt L, E} \ \ data constructors for \ {\tt Expression},
\item \verb#char :: Ring a => a -> Maybe Z# \ \ 
                                  for characteristic of a {\tt Ring},
\item {\tt add, sub, neg, mul, inv, ct, ctr} 
\end{itemize}        
\medskip


\underbar{{\bf Qualified names}}
\\
(of kind \verb# <moduleName>.<itemName>#).
They help to avoid name clashes. For example,
\footnotesize
\begin{verbatim}
  import qualified AlgSymmF ( to_e                            )
  import AlgSymmF           ( <all needed items, except to_e> )

  f    =  ... AlgSymmF.to_e ...
  to_e =  <another to_e>
\end{verbatim}
\normalsize




\newpage
\section{ What is not used from Haskell }
% ---------------------------------------
\label{sec-notu}  

In the {\tt Haskell-2-pre} language, {\tt DoCon} ignores the following 
features.
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Ratio} \ --- see Section \ref{sec-prel}.

\item {\bf arrays} \ 
       --- {\tt DoCon} prefers more explicit \ {\tt Map.Map} \ data 
       (exploiting a binary tree).

\item {\bf existential types} \\
  --- it is not clear, so far, how they work and whether {\tt DoCon} needs them.

\item {\bf monadic programming style} \\  
                   --- we do not see so far, how monads may help DoCon.

\item {\bf input-output} \\
      --- except \ {\tt putStr, writeFile} \ 
      in the end of some example programs, \ {\tt getChar} \
      in the Test program.\\
      Small exception: sometimes it may be used the 
      {\tt SymmDecMessageMode} for intermediate messages.
\end{itemize}        

          

\subsection{ About strictness annotations }
% -----------------------------------------
\label{sec-notu.strict}  

{\tt DoCon-2.11} has only one place where it applies the strictness 
annotation --- \ {\tt seq}.

Generally, we think that they may occur useful in some places. 






\section{ Demonstration, test, benchmark}
% ---------------------------------------
\label{sec-demot}  


The source directory \ \ \verb#<D>/docon/source/demotest/T_*#
\\
contains the automatic test function \ \verb#T_.test# \
for all the important {\tt DoCon} facilities.
The functions from \ \verb#T_*# \ can run as a demonstration and 
as a benchmark --- it depends on which part of their result are  
taken by the user function. See \ {\tt install.txt}, \ \verb#T_.hs#.
\bigskip

Let us proceed now with the systematic description of {\tt DoCon} parts.





\newpage
\section{ Program modules of {\tt DoCon}}
% ----------------------------------
\label{sec-pmod} 
       

{\tt DoCon} keeps one module in one \ .hs \ file.
{\tt DoCon} has a small number of the ``open'' modules --- 
the ones that are expected to be imported by the user program.
They reside in \ \verb#<D>/docon/source/# :
%
\begin{verbatim}
  AlgSymmF.hs    Fraction.hs    Pol.hs       Z.hs   
  Categs.hs      GBasis.hs      Residue.hs   DExport.hs 
  LinAlg.hs      RingModule.hs  DPair.hs     Partition.hs  
  SetGroup.hs    DPrelude.hs    Permut.hs    VecMatr.hs     
\end{verbatim}
%
Here \ {\tt DExport} \ only reexports all the other open modules, 
and many items from GHC library too.

The rest of {\tt DoCon} modules are `hidden' --- not expected to be imported
by the user program.
The hidden modules contain the most part of implementation.
Their names end with `\verb#_#', say \ \verb#auxil/Pol__.hs#, \ 
and such. They reside in 
%
\begin{verbatim}
  <D>/docon/source/auxil/  demotest/    lin/   parse/  pol/  residue/
                           pol/factor/  pol/symmfunc/
\end{verbatim}
\bigskip

\underbar{{\bf DPrelude}} 
\ \ 
contains generic items for the whole DoCon, such as
\begin{verbatim}
  class Cast, 
  data PropValue, data InfUnn(..)
  types  Z, Natural, MMaybe, CompValue, Comparison,
  functions   tuple31, tuple32 ... alteredSum, sortBy ...
  instance Set Char,  instance ... => Set [a] ...
\end{verbatim}
\medskip
 
\underbar{{\bf Categs}} 
\ \
contains the data structures for domain term, bundle:
\begin{verbatim}
  class Dom, 
  data CategoryName(..), Domain1, Domain2,  OSet, Subsemigroup ...
  Submodule ...
  types  Domains1,Domains2 ...
\end{verbatim}
\medskip

\underbar{{\bf SetGroup}}
\ \
contains the category declarations for
\begin{center}
 \verb#Set, AddSemigroup, MulSemigroup, AddMonoid, AddGroup, MulGroup# 
 \ldots,
\end{center}
polymorphic functions  
\begin{verbatim}
  zeroS, times, unity, power, divide, compareTrivially, isFiniteSet,
  listToSubset, isoOSet, upAddGroup, upMulSemigroup, upMulGroup ...
\end{verbatim}
\medskip


\underbar{{\bf RingModule}}
\ \
contains the categories 
\begin{center} {\tt Ring \ldots \ GCDRing \ldots \ Field, LeftModule(..)},
\end{center} 
some functions for \ {\tt Submodule}, some instances of 
{\tt LeftModule}, \\ 
`Chinese' ideal data \ {\tt PIRChinIdeal(..)}, \ 
many auxiliary functions for \ {\tt Ring}, {\tt GCDRing}, 
{\tt EuclideanRing} \ldots :
\begin{center} 
 {\tt quotEuc, remEuc, eucGCDE, multiplicity, isPowerOfNonInv, isoRing}
 \ldots
\end{center} 
\medskip

\underbar{{\bf Z}} 
\\  
declares category instances for \ {\tt Z = Integer} \ --- 
in addition to the {\tt Haskell} Prelude ones: 
\begin{center} 
{\tt Set \ldots \ AddGroup \ldots \ EuclideanRing \ldots \ FactorizationRing},
\end{center} 
defines a domain bundle \ {\tt dZ} \ for {\tt Integer}.
\bigskip

\underbar{{\bf DPair}}
\\
declares instances for the constructor \ {\tt (,)} \ of the direct 
product --- in addition to the {\tt Haskell} Prelude ones. 
\medskip

\underbar{{\bf Permut}} \ 
defines some instances and functions for \ {\tt Permutation} \ constructor.
\medskip

\underbar{{\bf Fraction}}
\\
contains various items for the construction \ {\tt Fraction a}, \ 
{\tt a} \ a gcd-Ring: \ some generic functions: \ 
{\tt num}, {\tt denom}, {\tt canFr}, \ \ instances \ \ 
{\tt Set} \ldots \ {\tt OrderedField}.
\bigskip

\underbar{{\bf VecMatr}}
\\
declares items for \ {\tt Vector a, Matrix a, SquareMatrix a}:
\\
category instances \ {\tt Set \ldots \  AddGroup} \ for all the three,
instances, 

  {\tt Ring} \ldots \  for {\tt Vector a}, \ \ \ 
                             {\tt Ring} \ for \ {\tt SquareMatrix a}, \\
several generic functions:
\begin{verbatim}
              vecSize, vecHead, vecTail, constVec, scalProduct,
              isLowTriangMt, vandermondeMt, resultantMt 
\end{verbatim}
\medskip


\underbar{{\bf Pol}}
\ \
declares items for the polynomial constructors 
\begin{center} 
               {\tt UPol, Pol, EPol, RPol, VecPol},
\end{center} 
declares \ \ {\tt type PowerProduct}, \ \ 
with its related functions \ {\tt lexComp, degLex \ldots}, 
\\
classes \ {\tt PolLike, Dom}, \ their instances for \ 
{\tt UPol}, {\tt Pol}, {\tt EPol}, {\tt RPol},
\\
instances for \ {\tt UPol}: \ \ldots \  
                            {\tt EuclideanRing}, {\tt FactorizationRing},
\\
instances for {\tt Pol}: \ \ldots \  
                            {\tt LinSolvRing}, {\tt FactorizationRing},
\\
instances for {\tt RPol}: \ \ldots {\tt GCDRing},
\\
instances 
\begin{verbatim}
                ... => LinSolvLModule (Pol  a) (EPol a),
                       LinSolvLModule (Pol  a) (Vector (Pol  a)), 
\end{verbatim}
and such, \\
numerous functions for these kinds of polynomial, 
various conversions between them, and so on.
\bigskip


\underbar{{\bf Residue}}
\ \
declares the \ {\tt Residue} \ class and the items for  
%
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt ResidueG a} \ --- 
                    residue by the subgroup of a commutative group,
\item {\tt ResidueE a} \ --- 
                    residue by an ideal     of an Euclidean ring,
\item {\tt ResidueI a} \ --- 
                   {\tt a/I}, residue by an ideal {\tt I} of a 
                   {\tt LinSolvRing}, \ {\tt I} given by gx-basis.
\end{itemize}
For \ {\tt ResidueG}, \ it contains the instances \ 
{\tt Set} \ldots \  {\tt AddGroup}, \\
for others --- {\tt Set \ldots \  Field}.

It also declares some items related to \ {\tt Ideal, PIRChinIdeal}.
\bigskip

\underbar{{\bf LinAlg}}
\\
defines several functions for the \ staircase form of matrix 
(Gauss method), \ diagonal form, \ determinant, \ 
linear system solution \ldots
\medskip


\underbar{{\bf GBasis}}
\\
defines the functions of the \ Gr\"obner reduction to normal form, \  
Gr\"obner basis, \ syzygy generator list, \ 
algebraic relation generator list \\
--- for the vector domain over \ $a[x_1,\ldots,x_n]$, \ 
$a$ \ an Euclidean ring.
\bigskip

\underbar{{\bf Partition}}
\\
defines operations with the \ partitions (Young diagrams), \ shapes, \ 
skew hooks,\\
horizontal bands: 
\begin{verbatim}
  partition conjugation, union, ..., subtracting h-bands, s-hooks,
  previous partition, hook, band, ... , 
\end{verbatim}
Kostka number, \ character matrix for $S(n)$, \ and some others.
\bigskip

\underbar{{\bf AlgSymmF }}
\\
defines arithmetic for \ symmetric functions --- sym-polynomials,
\\
transformations between various bases of the symmetric function
algebra \cite{Ma}: \\
{\tt m, s, p, h, e}.
\bigskip

\bigskip

Now, proceed with the description of {\tt DoCon} components.




\newpage
\section{ {\tt DoCon} prelude }
% -----------------------
\label{sec-dprel} 

It consists of a number of the general purpose items exported from
the module
\begin{center}             DPrelude.hs
\end{center}
--- see the export list of this module in Section~\ref{sec-dme}. 
\\
Some of these items are implemented in auxiliary modules 
\begin{center} 
     \verb#Prelude_,  Common_,  Char_,  List_,  Iparse_# \ldots
\end{center}
{\tt DPrelude} also exports the {\tt Set} instances for the 
domains \ {\tt Char}, {\tt List}:
\begin{verbatim}
                 instance Set Char         where ...
                 instance Set a => Set [a] where ...
\end{verbatim}
--- to add to the {\tt Haskell} Prelude instances for \ 
{\tt Char}, {\tt []}.

Describing here the {\tt DoCon} Prelude, and further, describing other 
parts of  DoCon,  we partly repeat  the  contents  of  the  relevant 
modules. But many implementation details are skipped.
And the Section~\ref{sec-dme} is specially devoted to listing of each 
module export.
%
\footnotesize
\begin{verbatim}
  module DPrelude ...

  type Z = Integer                -- IGNORE Int !
  toZ :: (Integral a) => a -> Z
  toZ =  toInteger
  fromZ :: Num a => Z -> a 
  fromZ =  fromInteger

  type Natural = Integer              -- use it for values >= 0

  tuple31 (x,_,_) = x 
  tuple32 (_,x,_) = x 
  tuple33 (_,_,x) = x 
                                 --- and other  tuple<i><j>,  i,j <- [3,4,5]
    -- There comes a language extension where these  tuple  things  are
    -- done in a nicer way.

  sublists :: [a] -> [[a]]
  sublists []     =  [[]]
  sublists (x:xs) =  (map (x:) ls)++ls  where  ls = sublists xs

  listsOverList :: Z -> [a] -> [[a]] 
                         -- list of all lists of length  n  with the elements from  xs. 
                         -- It does Not take notice of repetitions in  xs.       

  partitionN :: (a -> a -> Bool) -> [a] -> [[a]]
                              -- break list into groups by the Equivalence relation  p
  partitionN _ []     = []
  partitionN p (x:xs) = (x:ys):(partitionN p zs) where (ys,zs) = partition (p x) xs  
                 --
                 -- but for the case of equivalent items being *neighbours* use groupBy

  -- BEGIN   suggestion for Haskell standard library? ************* 

  mapmap :: (a -> b) -> [[a]] -> [[b]]
  mapmap    f        =  map (map f)

  fmapmap :: Functor c => (a -> b) -> c [a] -> c [b]
  fmapmap                 f        =  fmap (map f)

  mapfmap :: Functor c => (a -> b) -> [c a] -> [c b]
  mapfmap                 f        =  map (fmap f)

  fmapfmap :: (Functor c, Functor d) => (a -> b) -> c (d a) -> c (d b)
  fmapfmap                              f        =  fmap (fmap f)

                                       -- rewritten from  Maybes  of `data'  to
                                       -- avoid mentioning non-standard Maybes
  allMaybes :: [Maybe a] -> Maybe [a]
  allMaybes []           = Just []
  allMaybes (Nothing:_ ) = Nothing
  allMaybes (Just x :ms) = case allMaybes ms of  Nothing -> Nothing
                                                 Just xs -> Just (x:xs)

  takeAsMuch, dropAsMuch  :: [a] -> [b] -> [b]   
  -- 
  -- the following two implementations are nicer (and, probably, faster) 
  -- than combining `length' with `take' and `drop'.
  --
  takeAsMuch (_: xs) (y: ys) =  y: (takeAsMuch xs ys)
  takeAsMuch _       _       =  []

  dropAsMuch xs ys =  case (xs, ys) of
                                  ([],     _     ) -> ys
                                  (_,      []    ) -> []
                                  (_: xs', _: ys') -> dropAsMuch xs' ys'


  eqListsAsSets :: Eq a => [a] -> [a] -> Bool
  eqListsAsSets xs ys = all (`elem` xs) ys  &&  all (`elem` ys) xs

  zipRem :: [a] -> [b] -> ([(a,b)], [a], [b])
                      -- zip preserving remainders. Example:
                      -- for  xs = [1,2]  zipRem xs (xs++[3]) = ([(1,1),(2,2)], [], [3])

  zipRem []     ys     = ([], [], ys)
  zipRem xs     []     = ([], xs, [])
  zipRem (x:xs) (y:ys) = ((x,y):ps, xs', ys') where (ps,xs',ys') = zipRem xs ys

  delBy :: (a -> Bool) -> [a] -> [a]  
  delBy _ []     = []        
  delBy p (x:xs) = if  p x  then  xs  else  x:(delBy p xs)

  separate :: Eq a => a -> [a] -> [[a]]
                           -- break list to lists separated by given separator
                           -- Example:  ';' -> "ab;cd;;e f " -> ["ab", "cd", "", "e f "]
  separate _ [] = []
  separate a xs = case span (/= a) xs of (ys, []  ) -> [ys]
                                         (ys, _:zs) -> ys:(separate a zs)
  pairNeighbours :: [a] -> [(a,a)]
  pairNeighbours (x:y:xs) = (x,y):(pairNeighbours xs)
  pairNeighbours _        = []

  removeFromAssocList :: (Eq a) => [(a,b)] -> a -> [(a,b)]
  removeFromAssocList []              _  = []
  removeFromAssocList ((x',y):pairs)  x  =  
                          if x==x' then pairs  else (x',y):(removeFromAssocList pairs x)

  addToAssocList_C :: Eq a => (b -> b -> b) -> [(a,b)] -> a -> b -> [(a,b)]
                      -- c
                                    -- combines with the previous binding: when a key is
                                    -- in the list, it binds with  (c oldValue newValue)
  addToAssocList_C c pairs key value = add pairs 
    where
    add []         = [(key,value)] 
    add ((k,v):ps) = if k /= key then (k,v):(add ps) else (k, c v value):ps  

  addListToAssocList_C :: Eq a => (b -> b -> b) -> [(a,b)] -> [(a,b)] -> [(a,b)]
  addListToAssocList_C c ps binds = foldl addOne ps binds
                                             where
                                             addOne ps (k,v) = addToAssocList_C c ps k v
  -- END *************************************************************

  compBy :: Ord b => (a -> b) -> Comparison a
  compBy f x y = compare (f x) (f y)
    --
    -- Usable tool to define comparison. Examples:
    -- compBy snd          compares pairs by second component,
    -- compBy (abs . snd)  -              by absolute value of second component
 
  mulSign :: Char -> Char -> Char 
  mulSign    x       y    =  if  x==y  then '+'  else '-'

  invSign '+'  = '-'
  invSign '-'  = '+'

  evenL :: [a] -> Char  -- '+' ('-') means the list has even (odd) length
  evenL []     = '+'
  evenL (_:xs) = invSign (evenL xs)

  cubeList_lex :: (Show a, Ord a, Enum a) => [(a,a)] -> [[a]]
                                             --bounds
    -- Lists in the lex-increasing order all the vectors  [a(1)..a(n)]
    -- over `a' in the cube   a(i) <- [l(i) .. h(i)],  1 <= i <= n,
    -- defined by  bounds = [(l(1),h(1))..(l(n),h(n))],  l(i) <= h(i)
    -- Example: [(0,2),(0,3)] ->
    --                      [ [0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],
    --                        [2,0],[2,1],[2,2],[2,3] ]

  factorial :: Z -> Z
  factorial 0 = 1
  factorial n = if n < 0 then error $ ("factorial "++)$ shows n ":  negative argument\n"
                else          product [1..n]
\end{verbatim}
\normalsize
\bigskip

\begin{center} \verb#sum1, product1, alteredSum ::  Num a => [a] -> a#
\end{center}
%
{\tt alteredSum} [$x_1..x_n$] = $x_1 - x_2 + x_3 - x_4$ \ldots
\\
These functions are for {\it non-empty} list. \\
For non-integer, apply \ {\tt sum1} \ instead of \ {\tt sum}, \ \ 
{\tt product1} \ instead of \ {\tt product}. \\
If {\tt xs} may occur empty, then apply \ \ {\tt sum1 ((zeroS s):xs)}
\\
or \ \ {\tt product1 ((unity s):xs)} \ \ respectively --- with any 
sample element {\tt s} for the domain \ {\tt a} \ --- see \ {\tt sum1} \ 
in Section~\ref{sec-prel}.


\footnotesize
\begin{verbatim} 
  binomCoefs :: Z -> [Z]  -- binomial coefficients [C(n,k)..C(n,0)], k <= n/2+1
              --n        

  data InfUnn a = Fin a | Infinity | UnknownV  deriving(Eq, Show, Read)

  --- to represent domain `a' extended with the Infinity and Unknown 
  values.
  Examples: Fin n  :: InfUnn Z   means a `finite' integer,

            let  {(_,sChar)= baseSet 'a' Map.empty;  (_,sZ) = baseSet 0 dZ}
            in
            (osetCard sChar, osetCard sZ)    --> (Fin 256, Infinity) 

  instance Functor InfUnn  where  fmap f (Fin a)  = Fin (f a)
                                  fmap _ Infinity = Infinity
                                  fmap _ UnknownV = UnknownV
  type MMaybe a = Maybe (Maybe a)
    --
    Example of usage:
    subsmgUnity sS -> Just (Just u)  means here the unity  u  is found in sS,
                      Just Nothing   - sS does not contain unity,
                      Nothing        - cannot determine whether such  u  exists

  type CompValue = Ordering                -- `Ordering' is from Haskell-98
                                           -- and it does not sound well
  type Comparison a = a -> a -> CompValue
  data PropValue = Yes | No| Unknown  deriving (Eq, Ord, Enum, Show, Read)

  not3 :: PropValue -> PropValue
  not3    Yes       =  No
  not3    No        =  Yes
  not3    _         =  Unknown

  and3, or3 :: PropValue -> PropValue -> PropValue

  and3  Yes  Yes = Yes
  and3  No   _   = No
  and3  _    No  = No
  and3  _    _   = Unknown

  or3 ...

  boolToPropV :: Bool -> PropValue
  boolToPropV    b    =  if  b  then Yes  else No

  propVToBool :: PropValue -> Bool 
  propVToBool    Yes       =  True
  propVToBool    _         =  False

  compBy :: Ord b => (a -> b) -> Comparison a
  compBy f x y = compare (f x) (f y)
                          -- Usable tool to define comparison. Examples:
                          -- compBy snd          compares pairs by second component,
                          -- compBy (abs . snd)  - by absolute value of second component
 
  antiComp :: CompValue -> CompValue
  antiComp    LT        =  GT
  antiComp    GT        =  LT
  antiComp    _         =  EQ
           -- It holds: (flip compare) x y == flip compare x y == antiComp $ compare x y
           -- Use  `flip'.  Though,  antiComp  occurs sometimes useful too.

  less_m, lessEq_m, greater_m, greaterEq_m, incomparable :: Set a => a -> a -> Bool

  less_m       x y = case  compare_m x y  of  Just LT -> True
                                              _       -> False
  greater_m    x y = case  compare_m x y  of  Just GT -> True
                                              _       -> False 
  incomparable x = not . isJust . compare_m x

  lessEq_m    x y = x==y || less_m    x y
  greaterEq_m x y = x==y || greater_m x y

  lexListComp :: (a -> b -> CompValue) -> [a] -> [b] -> CompValue
                       -- Compare lists lexicographically according to the given 
                       -- element comparison cp. The lists may differ in type and length
  lexListComp cp = lcp where  
                       lcp []     []     = EQ
                       lcp []     _      = LT
                       lcp _      []     = GT
                       lcp (x:xs) (y:ys) = case  cp x y  of  EQ -> lcp xs ys
                                                             v  -> v

  minBy, maxBy :: Comparison a -> [a] -> a  --minimum, maximum by the given comparison
                                           -- Example: minBy compare        [2,1,3,1] = 1
                                           --         minBy (flip compare) [2,1,3,1] = 3

  minPartial, maxPartial :: Eq a => (a -> a -> Maybe CompValue) -> [a] -> Maybe a
    -- Minimum (maximum) by Partial ordering.
    -- The result maybe 
    --            Just m   - for  m <- xs & m <= x  for all  x  from xs,
    --            Nothing  - if there is no such  x  in  xs.  

  isOrderedBy :: Comparison a -> [a] -> Bool
                               -- Examples:  isOrderedBy compare        [1,2,2] -> True,
                               --            isOrderedBy (flip compare) [1,2,2] -> False

  minAhead, maxAhead :: Comparison a -> [a] -> [a]
                                      -- put ahead the minimum (maximum)  
                                      -- without changing the order of the rest

  mergeBy :: Comparison a -> [a] -> [a] -> [a]    -- merge lists ordered by cp
  mergeBy _  []     ys     = ys                 
  mergeBy _  xs     []     = xs
  mergeBy cp (x:xs) (y:ys) = case cp x y of GT -> y:(mergeBy cp (x:xs) ys)
                                            _  -> x:(mergeBy cp xs (y:ys))

  mergeE :: Comparison a -> [a] -> [a] -> ([a],Char)
                       -- extended merge: permutation sign '+' | '-' is also accumulated 

  sortE :: Comparison a -> [a] -> ([a],Char)
                       -- Extended sort: permutation sign '+' | '-' is also accumulated.
                       -- The cost is still  O( n*log(n) ).

  propVOverList :: Eq a => [(a,PropValue)] -> a -> PropValue -> [(a,PropValue)]
  propVOverList ps _  Unknown = ps                              -- update property value
  propVOverList ps nm v       = pov ps
    where
    pov []            = [(nm,v)]
    pov ((nm1,v1):ps) = if  nm1/=nm  then  (nm1,v1):(pov ps)
                        else               (nm ,v ):ps

  updateProps :: Eq a => [(a,PropValue)] -> [(a,PropValue)] -> [(a,PropValue)]
  updateProps ps ps' = foldl update ps ps'
                                         where  update ps (nm,v) = propVOverList ps nm v

  mbPropV :: Maybe PropValue -> PropValue
  mbPropV    (Just v)        =  v
  mbPropV    _               =  Unknown

  lookupProp :: Eq a => a -> [(a,PropValue)] -> PropValue
  lookupProp            a =  mbPropV . lookup a

  addUnknowns :: Eq a => [(a,PropValue)] -> [a] -> [(a,PropValue)]
  addUnknowns props = foldl addOne props
    where
    addOne  []               nm = [(nm,Unknown)]
    addOne  ps@((nm',v):ps') nm = if nm==nm' then  ps  else  (nm',v):(addOne ps' nm)
\end{verbatim}
\normalsize
\bigskip

\begin{center}  \verb# smParse :: Set a => a -> String -> a #
\end{center}
Generic parsing by sample. Applies \ \ {\tt infixParse, fromExpr}. \\
See Section~\ref{sec-prp.pars}, \ function \ {\tt Iparse.infixParse}, \\  
operation \ {\tt fromExpr} \ of \ {\tt Set} \ category.


\footnotesize
\begin{verbatim}
  smParse sample s = case infixParse parenTable opTable$ lexLots s  of

    ([e], "" ) -> (case  fromExpr sample e
                   of
                     ([x],"" ) -> x
                     (_  ,msg) -> error $ ("fromExpr sample str:  bad string.\n"++) $
                                          showsWithDom sample "sample" ""
                                          ('\n':(msg++"\n"))
                  )
    (_  , msg) -> error ("infixParse:  "++msg++"\n")
  --------------------------------------------------------------------
  -- for the following 3 operations with the association lists, we 
  -- could not find a good replacement in the Haskell libraries

  removeFromAssocList :: Eq a => [(a,b)] -> a -> [(a,b)]
  addToAssocList_C    :: Eq a => (b -> b -> b) -> [(a,b)] -> a -> b -> [(a,b)]
                                 -- c
                                    -- combines with the previous binding: when a key is
                                    -- in the list, it binds with  (c oldValue newValue)
  
  addListToAssocList_C :: Eq a => (b->b->b) -> [(a,b)] -> [(a,b)] -> [(a,b)]
  addListToAssocList_C c ps binds = foldl addOne ps binds where
                                             addOne ps (k,v) = addToAssocList_C c ps k v
\end{verbatim}
\normalsize
\bigskip

\begin{center} \verb# class Cast a b where  cast :: Char -> a -> b -> a #
\end{center}
%
{\tt cast mode a b} \ means to cast \ {\tt b} \ to domain of \ {\tt a}. \\
{\tt a} \ is used as a {\it sample} for the destination domain. \\
{\tt mode = 'r'} \ \ \ \ means the additional correction to perform, \\

   other value \ \ means to cast ``as it is''. 

{\bf Example 1.} \\
map coefficient \ {\tt c} $\in R$ \ to domain \ $R[x_1,\ldots,x_n]$: 
\\
{\tt cast mode pol c}, \ \ {\tt mode = 'r'} \ means the check \ \
{\tt c == zero} \ is needed, other mode is usually set when \ {\tt c} \
is known as non-zero.

{\bf Example 2.} \\
Projection \ $R \rightarrow R/I$ \ to residue ring, \\
say \ 
$R = Z, \ I = Ideal(g), \ g > 0$, \ {\tt res $\in R/I$, \ n} $\in R,$ \ 
and \ \ {\tt cast mode res n} \ \ projects {\tt n} to $R/I$. \\
Here {\tt mode = 'r'} \ takes first the remainder by \ $g$ \ 
($g$ contained in {\tt res} data); \ 
other mode has sense when it is known that \ {\tt $0 \leq$ n $< g$}.
\medskip

\footnotesize
\begin{verbatim}
  ct, ctr :: Cast a b => a -> b -> a
  ct  = cast '_'
  ctr = cast 'r'
\end{verbatim}
\normalsize
These functions are explained in Sections (\ref{sec-prp.ske} (CS)), 
\ref{sec-prp.skco.cs}.



\newpage
\section{ Domain descriptions }
% -----------------------------
\label{sec-dd}  

Their general meaning is explained in 
(Section~\ref{sec-prp.ske} (D), (DT) ...). \\
Their data types are mostly exported from the module \ {\tt Categs}.
%
\footnotesize
\begin{verbatim}
  module Categs   
  ...
  -- some prelude

  data AddOrMul = Add | Mul deriving (Eq,Show,Ord,Enum)  -- additive | multiplicative
                                                         -- subsemigroup
  type {-Ring a=>-}  Factorization a = [(a,Z)]

    -- example: 8*49*3 = 2^3*7^2*3   expresses as  [(2,3),(7,2),(3,1)]:: Factorization Z

  newtype Vector a = Vec [a] deriving (Eq)    -- Presumed: NON-empty list under Vec
  vecRepr (Vec l) = l                

  type PowerProduct = Vector Z
  type PPComp       = Comparison PowerProduct       -- power product comparison
\end{verbatim}
\normalsize


\subsection{ Bundle }
% -------------------
\label{sec-dd.b} 

\footnotesize
\begin{verbatim}
  data CategoryName =
       Set | AddSemigroup | AddGroup | MulSemigroup | MulGroup | Ring
       | LinSolvRing | GCDRing  | FactorizationRing | EuclideanRing | 
       IdealKey | LeftModule | LinSolvLModule
       -- may extend ...
       deriving (Eq, Ord, Enum, Show)
\end{verbatim}
\normalsize
\bigskip

\begin{center} {\tt type Domains1 a = Map.Map CategoryName (Domain1 a)}
\end{center}
Represents a domain or a bundle --- see 
(Section~\ref{sec-prp.ske} (D), (DT), (MD)) \\
--- with one parameter \ {\tt a}.

\footnotesize
\begin{verbatim}
  type Domains2 a b = Map.Map CategoryName (Domain2 a b)

  data Domain1 a =  
       D1Set      (OSet a)            | D1Smg    (Subsemigroup a)  |
       D1Group    (Subgroup a)        | D1Ring   (Subring a)       | 
       D1GCDR     (GCDRingTerm a)     | D1FactrR (FactrRingTerm a) | 
       D1LinSolvR (LinSolvRingTerm a) | D1EucR   (EucRingTerm a)   |   
       D1Ideal    (Ideal a)  
       -- ...
\end{verbatim}
\normalsize
--- see (Section~\ref{sec-prp.ske} (DT)).
\bigskip

\footnotesize
\begin{verbatim}
  data Domain2 a b = D2Module (Submodule a b) | D2LinSolvM (LinSolvModuleTerm a b)}
  -- may extend ...
\end{verbatim}
\normalsize


\subsection{ Dom class } 
% ----------------------
\label{sec-dd.dm} 

\footnotesize
\begin{verbatim}
class Dom c where  
            dom    :: c a -> Domains1 a  -- extracts the description of domain 
                                         -- over which the constructor c acts  
                                         -- - description of argument domain of c
            sample :: c a -> a   -- extracts sample element for argument domain
\end{verbatim}
\normalsize
{\bf Examples:} 
\\  
for \ \verb#f = UPol _ 0 _ dZ# \ --- univariate polynomial over {\tt Z} ---
\\
{\tt dom f = dZ, \ sample f = 0};

for \ {\tt r = Rse 2 iI dZ} \ --- residue modulo {\tt I} of {\tt Z} ---
\\
{\tt dom r = dZ, \ sample f = 2}. \ \ 
See (Section~\ref{sec-prp.ske} (CS), (DE)).



\subsection{ Domain terms}
% ------------------------
\label{sec-dd.dt} 

See first (Section~\ref{sec-prp} (DT)).
\\
The rest of the module {\tt Categs} describes the domain term data: 
\\
{\tt OSet, Subsemigroup, \ldots, GCDRingTerm, \ldots, Submodule, \ldots}
\\
We describe them separately, in the sections devoted to each
particular category --- {\tt Set}, {\tt AddSemigroup}, and so on.
\bigskip

Now, proceed with these categories.




\newpage
\section{ Set }
% -------------
\label{sec-set}


\subsection{ Set category }
% -------------------------
\label{sec-set.ct} 

See the module \ {\tt SetGroup}, \ 
{\tt OSet} data declaration in the module {\tt Categs}.
%
\footnotesize
\begin{verbatim}

  class (Eq a, Show a) => Set a                       -- partially ordered set
    where
    compare_m  :: a -> a -> Maybe CompValue           -- partial ordering
    showsDomOf :: a -> String -> String               -- for messages
                --sa
    fromExpr   :: a -> Expression String -> ([a], String)      -- for parsing
                --sa   e                          messg

    baseSet    :: a -> Domains1 a -> (Domains1 a, OSet a)
                --sa                              description of set
\end{verbatim}
\normalsize
\bigskip

\underbar{{\tt baseSet}}
\\
provides the main information on set.
It returns the description of the base subset related to  the  given 
sample element.  See (Section~\ref{sec-prp.ske} (DS), (SA), (BO)).
\begin{center}
                 {\tt baseSet x dom --> (dom', o)}
\end{center}
{\tt dom' = Map.insert Set (\ldots \ o) dom}. 
\\
{\tt o} \ is either found in {\tt dom} or built according to the 
          construction of {\tt x} and {\tt dom} contents.
\bigskip

\underbar{{\tt compare}} \verb#_m#
\\
Any {\tt Set} is considered as partially ordered by \ \verb#compare_m#.
\\
At least, the trivial ordering \ \ \verb#compare_m = compareTrivially#\\
can be specified: 
\begin{center}  
          {\tt compareTrivially x y = if x==y then Just EQ else Nothing}    
\end{center}
All the subsets of the base set are considered relatively to 
\ \verb#compare_m#.
\\
\verb#compare_m# \ should define a transitive and anti-symmetric 
relation. It takes the values in
\begin{center}
               {\tt  Just LT | Just GT | Just EQ | Nothing }
\end{center}
--- the latter value means the incomparability of elements. \\
Further information on this ordering is contained in the base subset
description {\tt bS} --- for example, \ \  
\verb#bS = snd $ baseSet <sample> Map.empty#.

Recall also of \ {\tt compare} \ of {\tt Haskell} Prelude.
In principle, for some domains of {\tt Set} and {\tt Ord}
instances, \ {\tt compare} \ and \ \verb#compare_m# \ may disagree.
But starting from {\tt OrderedSet}, they have to agree.
\bigskip


\underbar{{\tt showsDomOf x str --> str'}}
\\
prints to String the short description of domain defined by sample \
{\tt x}.\\ 
It is used in error messages: see Section~\ref{sec-set.dpr}.
\bigskip

\underbar{{\tt fromExpr}}  
\\
is reading from expression by sample --- see Section~\ref{sec-prp.pars}, 
function {\tt DPredude.smParse}, \ the files \  
\verb#parse/princip.txt, Iparse_.hs#.

If {\tt fromExpr} succeeds, the result is \ \verb#([elementOf_a], "")#, 
\\ 
otherwise, it is \ \ \verb#(_, message)#, \ \
where \ {\tt message} \ contains some explanation of why the 
expression  \ {\tt e} \ does not fit to represent an element of domain  
(defined by sample).



\subsection{ Subset } 
% -------------------
\label{sec-set.o} 

\footnotesize
\begin{verbatim}
  data OSet a =
       OSet {osetSample  :: a,                    -- sample data for type
             membership  :: Char -> a -> Bool,
             osetCard    :: InfUnn Z,             -- cardinality
             osetPointed :: MMaybe a,             -- pointed element of set
             osetList    :: Maybe [a],
             osetBounds  :: (MMaybe a, MMaybe a, MMaybe a, MMaybe a),
             osetProps   :: Properties_OSet,
             osetConstrs :: [Construction_OSet a],
             osetOpers   :: Operations_OSet a
            }
  type Properties_OSet = [(Property_OSet,PropValue)]
  data Property_OSet   =
       Finite | FullType | IsBaseSet | OrderIsTrivial | OrderIsTotal | 
       OrderIsNoether | OrderIsArtin  -- more?
       deriving(Eq, Ord, Enum, Show)                

  data Construction_OSet a = Interval (Maybe a) Bool (Maybe a) Bool
                             --
                             -- Union [OSet a], Intersection [OSet a] ...?
  type Operations_OSet a = ...   -- DUMMY, so far
\end{verbatim}
\normalsize
\medskip

\underbar{{\bf Base set and subset}}
\\
A value \ \ \verb#o :: OSet a# \ \ describes a subset \ S = S(o) \ \  
of the base set BS inside a type \ {\tt a}.

For this section, we keep on with the denotations \ S, BS.

BS \ is defined, for example, by the sample element \ 
                                   \verb#<sample> = osetSample o  :: a#.
\\
And S is a subset of \ 
S' = S'(o) = \verb#{x <- a | membership o 'r' x == True}#.

According to the type constructors involved in \verb#<sample>#, 
{\tt DoCon} puts individually, what BS is precisely presumed.
See Sections (\ref{sec-prp.ske} (DS), (SA), (BSE)), 
\ref{sec-prp.skco.se}.

For some constructors, S = S', and \ {\tt membership o 'r'}  \ \
is really an algorithm solving the membership to S.
For others, it is not, this is the matter of a given constructor:
{\tt Integer}, {\tt Vector}, {\tt Pol}, {\tt ResidueI}, or other.

All the further possible base domains for \verb#<sample>#  
(additive group, ring, \ldots) are considered as having the 
{\it support} BS.
For example, for the base additive group, \ {\tt (+), neg} \ 
are considered as restricted to the set BS.
\bigskip

{\tt osetProps o} \ \ contains \ {\tt (IsBaseSet, v)}, \\ 
{\tt v} \ may be \ {\tt Yes} \ (means S = BS), \ \ \
{\tt No} \ (S $\neq$ BS), \ \ \ {\tt Unknown}.
\medskip 

The letter {\tt 'O'} in {\tt OSet} stands for ``ordered partially''.
\bigskip

\underbar{{\tt membership :: Char -> a -> Bool}}
\medskip 

is the above predicate for S'(o). 
In the function \ {\tt belongs = membership o}, \\ 
in \ {\tt belongs mode x},
\\
{\tt mode = 'r'} \ \ means to test the membership recursively, 
                     down all the constructors in \ {\tt x}.

Example:  for the {\tt Set (a,b)} instance, {\tt DoCon} puts
\begin{verbatim}
                 belongs 'r' (x,y) = bel1 'r' x  &&  bel2 'r' y
                 belongs _   _     = True,
\end{verbatim}
where \ {\tt bel1, bel2} \ are the corresponding predicates for \
{\tt a}, {\tt b}.
\bigskip 


\underbar{{\tt osetCard :: InfUnn Z}}  
\medskip

{\tt osetCard o} \ is \ cardinality(S(o)) = \ 
                         {\tt Infinity | UnknownV | Fin n}, 

    {\tt n} \ a non-negative integer.
\bigskip


\underbar{{\tt osetPointed :: MMaybe a}} 
\medskip

is any chosen element in S. It may be 
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Just (Just x)} \   --- ``this {\tt x} belongs to S'',
\item {\tt Just Nothing} \ \  --- ``S is empty'',
\item {\tt Nothing} \ \ \ \ \ \ \ \ \ \ --- ``could not find any element in S.
\end{itemize}
\bigskip


\underbar{{\tt osetList :: Maybe [a]}} \ \ may be
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Just xs} \ \ \ \ \ --- {\tt xs} is a finite list of all the 
                                  elements of S, \ free of repetition,
\item {\tt Nothing} \ --- ``could not provide such list''.
\end{itemize}
\bigskip


\underbar{{\tt osetBounds}} 
                    {\tt :: (MMaybe a, MMaybe a, MMaybe a, MMaybe a)}
\medskip

  {\tt = (lower, upper, infinum, supremum)}
 
These are the attributes of the partial ordering \ \verb#compare_m# \ 
restricted to S. \ {\tt infinum} \ and the membership predicate 
of S may give the minimum of S.  Similar is maximum.

It holds \ \ \ \ \ \ {\tt lower <= infinum, \ upper >= supremum} \\ 
--- when these data have definite values.
\\
{\tt lower =}

  {\tt Just (Just l)} \ 
               --- means {\tt l} $\in$ S \ is the lower bound for S,

  {\tt Just Nothing} \ \            --- such bound does not exist in S,

  {\tt Nothing} \ \ \ \ \ \ \ \ \ \ --- could not find such bound in S.     
\medskip

Similar are \ {\tt upper, infinum, supremum}.
\bigskip


\underbar{{\tt osetProps}} \verb#:: Properties_OSet#
\medskip

is an {\it association list} with the \ \verb#Property_OSet# \ key. \\
The pairs (or keys) in this list may be:
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt (IsBaseSet, Yes)} \ \ means S = BS  --- a base set.
\item {\tt FullType} \ \     --- S = full set of the {\it type}.
\item {\tt OrderIsTrivial} \ \ --- 
           \verb#(compare_m x y)==Nothing# \ for all {\tt x /= y} in S.
\item {\tt OrderIsTotal} \ \ --- 
           \verb#(compare_m x y) /= Nothing# \ for all {\tt x, y} in S.

\item {\tt OrderIsNoether} \ \ --- S has not any infinite increasing by  
                                 \verb#compare_m# sequence \\
                                 $x_1 < x_2 < $ \ldots

\item {\tt OrderIsArtin} \ \ --- S has not any infinite decreasing by  
                                        \verb#compare_m# sequence.
\end{itemize}
\bigskip

\underbar{{\tt osetConstrs}} \verb#:: [Construction_OSet a]#
\medskip

is the list of algebraic constructions known to produce S. \\
This feature is \ reserved, \ not really used, so far.

Possible construction: \ \verb#Interval l l_closed r r_closed#
\\
expresses \ S = interval (l,r) \ in a partially ordered set. \\
This is for the case {\tt (OrderIsTotal, Yes)}.
\\
{\tt l = Just l'} \ \ \ \ \ \ \ means {\tt l'} is a \ lower bound for S,
\\
{\tt r = Just r'} \ \ \ \ \ \ \ --- {\tt r'} is an \ upper bound, 
\\
{\tt l (r) = Nothing} \         --- there is no lower (upper) bound.
\\
\verb#l_closed (r_closed) = True# \ \    
         means that the lower (upper) bound belongs to the interval.
\bigskip


\underbar{{\tt osetOpers}} \verb#:: Operations_OSet a# 
\medskip 

Generally, \ \ \verb#<dom>Opers# \ \
contains several additional operation descriptions for a domain 
--- set, group, \ldots \ 
Such operation can be extracted by applying the \ {\tt lookup} \ 
function.\\
For example, 
\begin{center}  \verb#lookup DimOverPrimeField $ subringOpers rR#
\end{center}
may yield \ {\tt DimOverPrimeField' (\ldots)} \ or \ {\tt Nothing}.
\bigskip

\underbar{On {\tt Constructions, Operations}} parts of domain description: 

in DoCon, they are DUMMY, \ except  

  {\tt Interval} construction for {\tt OSet},

  {\tt DimOverPrimeField} operation for \verb#Operation_Subring#,   

  {\tt GenFactorizations} \ for \ \verb#Construction_Ideal#,

  {\tt IdealRank} \ for \ \verb#Operation_ideal# 




\newpage
\underbar{{\bf Example 1:}} \ \ {\tt DoCon} declares for the domain {\tt Char}
\footnotesize
\begin{verbatim}
instance Set Char  
  where   
  showsDomOf _ = ("Char"++)

  fromExpr _ (E (L "'") [] [L [c]]) = ([c], "")
  fromExpr _ e                      =  
                          ( [], "(fromExpr <Char> e):  wrong e = " ++ (showsExpr e "") )
  compare_m x = Just . compare x 

  baseSet _ dm = case  Map.lookup Set dm  of

    Just (D1Set o) -> (dm, o)
    _              -> (Map.insert Set (D1Set o) dm, o)
     where
     o = OSet {osetSample  = 'a',
               membership  = (\_ _-> True),
               osetCard    = Fin (n2-n1+1),
               osetPointed = Just (Just 'a'),
               osetList    = Just list,
               osetBounds  = (Just (Just minC), Just (Just maxC),
                              Just (Just minC), Just (Just maxC)  
                             ),       
               osetProps   = props,
               osetConstrs = [(Interval (Just minC) True (Just maxC) True)],
               osetOpers   = []
              }             
     (minC, maxC) = (minBound, maxBound) :: (Char, Char)
     [n1  , n2  ] = map (toZ . fromEnum) [minC, maxC]
     list         = [minC .. maxC]
     props        = [(Finite,Yes),(FullType,Yes),(IsBaseSet,Yes),(OrderIsTrivial,No),
                     (OrderIsTotal,Yes),(OrderIsNoether,Yes),(OrderIsArtin,Yes)]
\end{verbatim}
\normalsize

\underbar{{\bf Example 2:}} \ \ zero ideal in polynomial ring.
\medskip

For the ring  \ {\tt P = Z[x]}, \ \ ideal \ {\tt I} \ in \ {\tt P}, \ 
any residue element in \ {\tt P/I} is represented as \ \ 
\verb#Rsi f (_, iD) dP#, 
\\ 
where {\tt iD} the bundle for the domain {\tt I}. 
In particular, {\tt iD} contains the subset term {\tt sI}.

Suppose now that {\tt I} = \{0\}. Then, {\tt sI} has to describe 
the set \{0\}:
\begin{verbatim}
 sI = OSet {osetSample = f :: P,           membership = (\_ g-> isZero g)...
            osetList   = Just [zeroS f],   ...
           }
\end{verbatim}
Here the base set \ BS(f) = {\tt P} \ --- the whole polynomial ring.
This is put by {\tt DoCon} for the constructor {\tt UPol} in  \ 
\verb#f = UPol _ _ "x" dZ#.

And  S  inside BS is defined by \ \ 
                         {\tt (membership sI): \ sI = \{(zeroS f)\}}.

A good way to form the {\tt (iI,iD)} terms for the ideal description 
is to apply the {\tt DoCon} function \\
{\tt gensToIdeal} \ 
which starts with the ideal generator list and ring bundle {\tt dP}
and produces automatically {\tt sI} and other parts of {\tt iD},
{\tt iI}. As in our case {\tt I = \{0\}, \ gensToIdeal} \ 
may apply in its turn \ {\tt listToSubset} \ to build the subset 
term \ {\tt sI}.

Commonly, the domain descriptions are constructed  by  the  standard
{\tt DoCon} functions rather than ``by hand''.



\subsection{ Examples of using domain properties }
% ------------------------------------------------
\label{sec-set.pr} 

\footnotesize
\begin{verbatim}
  f subset = let  ps = osetProps subset
             in
             (case  lookup Finite ps  of  Just Yes -> g 
                                          Just _   -> h
                                          _        -> error (..."property skipped"...)
             )
             where  g = ...    h = ...
\end{verbatim}
\normalsize
Also this can be scripted more shortly as
\footnotesize
\begin{verbatim}
  f subset = let ps  = osetProps subset
                 fin = fromMaybe (error (.."property skipped"..) $ lookup Finite ps
             in  if fin==Yes then ... else ...
\end{verbatim}
\normalsize
And often we program it like this:
\begin{verbatim}
                 f subset = let  ps  = osetProps subset   
                                 fin = lookupProp Finite props
                            in   if  fin==Yes  then ... else ...
\end{verbatim}
--- see \ DPrelude.lookupProp. \ Consider also
\begin{verbatim}
          f1 :: Set a => a -> a
          f1 x = let {(_, xS) = baseSet x Map.empty;   ps = osetProps xS}
                 in  ... like above in  f.
\end{verbatim}
Here the sample {\tt x} defines a base set, and {\tt f1} analyses 
the attributes of this set.
For several most usable properties {\tt DoCon} provides shorter access.  
Say
\begin{center}  \verb# isFiniteSet :: OSet a -> PropValue #
\end{center}
Such functions are defined simply by composing the functions \ 
{\tt osetProps} \ and \ {\tt lookup}, \ 
and the programmer can arrange the same for the properties that one
consideres as the most usable.

Semigroup, Group, and other categories, treat the properties similarly.  
Only the set of the property names is different. 



\newpage
\subsection{ Usable functions for subset }
% ----------------------------------------
\label{sec-set.fn} 

\footnotesize
\begin{verbatim}
  isBaseSet, isFiniteSet :: OSet a -> PropValue

  isBaseSet   = fromMaybe Unknown . lookup IsBaseSet . osetProps
  isFiniteSet = ...
  intervalFromSet :: OSet a -> Maybe (Construction_OSet a)
                                                  -- extract first interval construction
  card :: Set a => a -> InfUnn Z  -- make set from sample and extract cardinality
  card a = osetCard s  where  (_, s) = baseSet a Map.empty 

                       -- example:  card 'a' == card '0' == Fin 256,  card 2 == Infinity

  ofFiniteSet :: Set a => a -> PropValue
  ofFiniteSet             a =  isFiniteSet s  where (_, s) = baseSet a Map.empty
                                              
  isoOSet :: (a -> b) -> (b -> a) -> OSet a -> OSet b
             -- f        f_inv       
     -- For given oset S on type `a', the maps  f: a -> b and its inverse f_inv
     -- produce an isomorphic copy of S on `b'.  f  should be injective.

  listToSubset :: Set a =>  [a] -> [Construction_OSet a] -> OSet a -> OSet a
                          -- xs    conss
    -- Make a Listed Proper subset in the base set.
    -- Only those elements of  xs  remain which belong to the Base.
    -- conss  overwrites the construction list (is often put []).
    -- See implementation in  Set_.hs
\end{verbatim}
\normalsize



\newpage
\subsection{ Printing domains }
% -----------------------------
\label{sec-set.dpr} 

This section is on the \ {\tt showsDomOf} \ operation 
(see Section~\ref{sec-set.ct}).
\bigskip

\underbar{{\bf Example}}
\medskip

The inversion \ {\tt inv} \ in a semigroup applies \verb#inv_m# 
and either extracts the result from it or breaks the program with
the error message:
\footnotesize
\begin{verbatim}
  ------------------------------------------------------------------ BAD design
  invBAD :: MulSemigroup a => a -> a
  invBAD                      x = fromMaybe (error $ ("inv "++) $ show x) $ inv_m x
 
  -- Here the error message provides too few information.  For example,  

    invBAD (2::Z)      -> "Fail:  (inv x)  failed ... inv 2"
    invBAD (fromi r 2) -> "...                        inv 2"
    invBAD (fromi f 2) -> "...                        inv 2"
                                      where
                                      r = ... describes the ring Z/(4)
                                      f = ...                    Z[x]
  ------------------------------------------------------------------
\end{verbatim}
\normalsize
%
The second and the third lines try to inverse the image of 2 in
the rings \ {\tt Z/(4), Z[x,y]} \ respectively 
(we omit the program details). The element  2  of these rings 
represents internally as \ \ \verb#Rse 2 <..> dZ# \ \ and \ \ 
\verb#Pol [(2,..)] _ _ _ dZ# \ \ respectively.
But in the output string the \ {\tt shows} \ operation shows it still
as "2".  {\tt DoCon} defines {\tt shows} so for the same reason as why the 
mathematicians prefer to write \ \verb#(2, x*y + 1)# \ rather than \ 
\verb#(2*x^0*y^0, x*y + 1)#.

But then, the output has to print the short domain description ---  in 
order to give the user a more definite idea of where the computation
was taking place:
\footnotesize
\begin{verbatim}
  inv :: MulSemigroup a => a -> a                           -- Real program
  inv x = fromMaybe (error msg) $ inv_m x  
                       where
                       msg = ("inv x  failed,"++) $ showsWithDom x "x" "" "\n"
\end{verbatim}
\normalsize
Here  \ {\tt showsWithDom} \ prints {\tt x} and applies \ 
{\tt (showsDomOf x)} too. 
\medskip

{\bf Examples.}

For \ {\tt r <- Z/(4)}, \ the program \ {\tt inv (fromi r 2)}
\\
(map 2 into {\tt Z/(4)} and find there the inverse) reports \\

\verb#" Fail: inv x  failed,    x = 2  <-  (Z/<4>) "#

Here \ \verb#" <- (Z/<4>)"# \ means ``belongs to domain {\tt Z/Ideal(4)}''.
\medskip

For the residue ring \ \verb#R = (Z/(3))[x,y] / (x-y, y^2, x^3, x*y)#,
\\
{\tt inv (0 <- R)} \ would report something like
\begin{verbatim}
                 Fail: inv x  failed,
                 x = (0)
                 <-  ((Z/<3>)["x","y"] / I<(x-y)... a_3>)
\end{verbatim}
Now, it is clear, what is {\tt showsDomOf},  how to define it for 
various constructors, and how to apply \ {\tt showsWithDom}.



\subsubsection{ Domain output syntax }
\label{sec-set.dpr.s}

Its denotations follow the mathematical tradition and often differ 
from the corresponding data constructor names.
\medskip

It uses the additional \ \verb#`<'# \ and \ `\{' \ parentheses ---  
to help visual parsing of complex domains.
\bigskip

\underbar{{\tt List}}  \ is used instead of \ {\tt [,]},
\medskip

`{\tt [\ldots]}' \ is used for the polynomial variable listing.
\medskip

\verb#<...># \ \ denotes the ideal in an Euclidean ring represented by 
               the \ {\tt Rse} \ constructor.
\medskip

\verb#I<...># \ denotes the generic ideal ({\tt Rsi} constructor).
\bigskip


\underbar{{\tt (A x B)}} \ --- direct product (constructor {\tt (,)}).
\medskip

Example: it may occur \ \verb#(3, (2,2*y))# \ $\in$ \ 
                     \verb#"(Z x (Z x Z[y]))"#
\bigskip



\underbar{{\tt (List D)}} 

  --- domain of lists over domain described by a string {\tt D} \ 
  (constructor {\tt [,]}). 
  
  Examples: \ \verb#"(List Z)",  "(List (Z/<2>))"#
\bigskip


\underbar{{\tt \{Vec n D\}}} 

  --- vector domain {\tt D} -- {\tt n}-times (constructor {\tt Vec}).

  Examples: \ 1. \ \verb#(Vec [1,4,0] :: Vector Z) <-  "{Vec 3 Z}"# ;
 
  2. \ \verb#"{Vec 4 Z[x1,x2]}"# \  
              shows the fourth direct product power of {\tt Z[x1,x2]}.
\bigskip


\underbar{{\tt (L n D)}} \ --- 
                  matrix {\tt n} $\times$ {\tt n} domain over {\tt D} 
                  (constructor {\tt SqMt})
\bigskip


\underbar{{\tt (L n m D)}} \ ---
     matrix {\tt n} x {\tt m} domain over {\tt D} (constructor {\tt Mt}).

  Examples:

  \verb#(Mt   [[1,2],[3,4]] dZ  :: Matrix Z)       <- "(L 2 2 Z)"#,

  \verb#(SqMt [[1,2],[3,4]] dZ  :: SquareMatrix Z) <- "(L 2 Z)"#
\bigskip

              
\underbar{{\tt (Fr D)}} \ --- fraction domain (constructor \verb#:/#).

   Example: 

   \verb#(t:/3 :: Fraction (UPol Z))  <- "(Fr Z[t])"#
\bigskip



\underbar{{\tt (D/}}\verb#<b>#)

  --- residue ring of Euclidean ring {\tt D} by Ideal({\tt b})  
      (constructor {\tt Rse}).

  Examples:
  \verb#(Rse 0 iI dZ  :: ResidueE Z) <-  "(Z/<4>)"#, \ \ 
                                              if \verb#iI = <4>#.

  \verb#(Rse x^2 iI dQ  :: ResidueE (UPol (Fraction Z)))  <-#

  \verb#                      " ((Fr Z)[x] / < -3*x^3 +2*x^2 - 1 >) "#,

   where 

   {\tt dQ} describes \ {\tt Fraction Z}, \ \ 
                    {\tt iI} describes \ \verb#Ideal(-3*x^3 +2*x^2 -1)#.
\bigskip


\underbar{{\tt (D/I}}\verb#<gs>#)

  --- (generic) residue ring of {\tt D} by \verb#I = Ideal<gs># \
  (constructor {\tt Rsi}) 

  --- see Section~\ref{sec-rsi}.

  If a finite generator list \ {\tt gs =} $[a_1, \ldots, a_n]$ \ 
  is {\it not} detected for {\tt I}, then {\tt gs} prints as \ 
  \verb#"?"#, 

  Otherwise, it prints as \ \ $a_1$-{\it expression Tail},

  where \ {\it Tail} {\tt = ""} \ \ for {\tt n = 1}, \
  \verb#"... a_n"# \ \ otherwise.

  Examples:

  \verb#Z[x,y]/(x^2 -y  )# \ \ \ \ prints as \ 
                                       \verb#"(Z[x,y]/I<x^2 - y>)"#

  \verb#Z[x,y]/(x^2, x^3-y, x*y-1)# \ \ prints as \ 
                                  \verb#"(Z[x,y]/I<x^2, ..., a_3>)"#
\bigskip



\underbar{{\tt \{D/Subgroup}}\verb#<gs>}#
  
  --- residue group of {\tt D} by a normal subgroup {\tt H} \
  (constructor {\tt Rsg})  --- see Section~\ref{sec-rsg}.
  
It prints similar as \ \verb#D/I<gs>#, \ only \\
(a) it is embraced with \{ \},  \ \ 
(b) {\tt Subgroup} replaces {\tt `I'}, \\
(c) {\tt gs} \ are the subgroup generators.

{\bf Examples:} \\ 
the quotient group {\tt Z/(2)} prints as \ \verb#"{Z/Subgroup<2>}"#,
\\
the quotient additive group \ \verb#(Fraction Z)/<1:/2,1:/3># \ 
may be printed as  \\ 
\verb#"{(Fr Z)/Subgroup<1:/2, ..., a_2>}"#
\bigskip


\underbar{{\tt S(n)}}

  --- permutation group on {\tt n} elements (constructor {\tt Pm}).

  Example:  {\tt (Pm [-2,6,4] :: Permutation)} \ $\in$ \ \verb#"S(3)"#
\bigskip


\underbar{{\tt D[variables]}}

  --- polynomial domain over {\tt D} 
  (constructors {\tt UPol, Pol, RPol, RPol'}). 
\\
For the univariate polynomial domain ({\tt UPol})
and for the `usual' multivariate polynomial  ({\tt Pol}), \ 
{\tt variables} \ is the list as usual. For example,
\\
\verb#"Z[x]", "Z[y2]"# \ may mean {\tt (UPol Z)} or {\tt (Pol Z)} 
representation, \\
\verb#"Z[t12,r31]"# \ means only {\tt (Pol Z)} data.

For the r-polynomial domain (recursively represented polynomial),
\begin{center}
                     {\tt variables = prefix ranges}
\end{center}
describes the set of variables. See Sections \ref{sec-rpol.e}, 
\ref{sec-rpol.d}.

For example, \ {\tt " Z[vv [(1,3),(0,2)]] " } \ 
denotes the r-polynomial domain {\tt P} over {\tt Z} with the 
variable set \ \verb#{vv_i_j | 1 <= i <= 3, 0 <= j <= 2}#,
\\
{\tt D[]} \ denotes the {\tt RPol'}-polynomial domain --- 
see Section~\ref{sec-rpol.d}.
\bigskip



\underbar{{\tt \{EPol variables D\}}}

--- E-polynomial domain over \ {\tt D[variables]} \ (constructor {\tt EPol}).

This is certain representation for the vectors over polynomials  
--- see Section~\ref{sec-polv.i.e}.

{\tt Example:} \ \ \verb#"{EPol [x,y] Z}"# \ denotes a free module \  
$P \oplus P \oplus$ \ldots \ \ over \ \ $P = Z[x,y]$, \\
the vectors represented as e-pols.
\bigskip



\underbar{{\tt \{VecPol variables D\}}}

--- {\tt VecPol} representation for the module \ 
$P \oplus P \oplus$ \ldots \ over \ $P =$ {\tt D[variables]} 
\\ 
(constructor {\tt VecPol}) --- see Section~\ref{sec-polv.i.vp}.

{\bf Example:} \ \ 
\verb#"{VecPol [x,y] Z}"# \ \ denotes the module \ 
$P \oplus P \oplus$ \ldots \ \ over \ \ $P = Z[x,y]$.
\bigskip


 
\underbar{{\tt \{SymPol D\}}}    

--- symmetric function domain over {\tt D} (constructor {\tt SymPol}) 
--- see Section~\ref{sec-symmf.sp}.

{\bf Example:} 
$$               2 m_{[3]} = \ 2 \cdot \sum_{i = 1}^{\infty} x_i^3  
$$
(in its appropriate {\tt SymPol} representation) belongs to \ 
\verb#"SymPol Z"#



\newpage
\section{ OrderedSet }
% --------------------
\label{sec-ord}  

\footnotesize
\begin{verbatim}
  class (Ord a, Set a) => OrderedSet a
    -- Presumed:
    -- on the  base set,  compare_m 
    -- possesses  (OrderIsTotal, Yes)  and agrees with `compare':
    --                                 (compare_m x y) == (Just (compare x y))
\end{verbatim}
\normalsize
Example: 
\begin{verbatim}
  f :: OrderedSet a => [a] -> a
  f (x:y:xs) = if  x < y  then  x  
               else             if  fromJust $ compare_m y x ...
\end{verbatim}
uses both {\tt (<)} (defined via \ {\tt compare}) and \ \verb#compare_m# \
and applies {\tt fromJust} --- knowing that \verb#compare_m# yields 
here only \ \verb#(Just _)#.  

\verb#`OrderedSet a =>'# \ says here that {\tt f} deals with the 
elements of the base set --- on which \verb#compare_m# is a total 
ordering.
  




\newpage
\section{ Semigroup }
% -------------------
\label{sec-smg}  


See first Secrtions \ref{sec-set.ct}, \ref{sec-set.o}. \\
See the module {\tt SetGroup} and {\tt Subsemigroup} data in the 
module {\tt Categs}.



\subsection{ Subsemigroup term }
% ------------------------------
\label{sec-smg.sub} 

\footnotesize
\begin{verbatim}
  data Subsemigroup a =
       Subsemigroup {subsmgType    :: AddOrMul,       -- operation name
                     subsmgUnity   :: MMaybe a,
                     subsmgGens    :: Maybe [a],
                     subsmgProps   :: Properties_Subsemigroup,
                     subsmgConstrs :: [Construction_Subsemigroup a],
                     subsmgOpers   :: Operations_Subsemigroup a
                    }
  data AddOrMul = Add | Mul  deriving (Eq, Show, Ord, Enum)

  type Properties_Subsemigroup = [(Property_Subsemigroup, PropValue)]
  data Property_Subsemigroup   =
       Commutative | IsCyclicSemigroup | IsGroup | IsMaxSubsemigroup
       | IsOrderedSubsemigroup  deriving (Eq, Ord, Enum, Show)

  data Construction_Subsemigroup a = ... DUMMY 
  type Operations_Subsemigroup   a = ... DUMMY 
  data OpName_Subsemigroup         = ... DUMMY 
  data Operation_Subsemigroup a    = ... DUMMY
\end{verbatim}
\normalsize
%
A subsemigroup H is considered relatively to a base semigroup G. \\
See below the semigroup categories.
So, to make a true {\tt Subsemigroup}, we should have first 
\begin{itemize}
\setlength\itemsep{0pt}
\item an instance of the {\tt Set} category, with its base set BS,
\item an instance of the {\tt Add(Mul)Semigroup} category, with its 
      base semigroup BH,
\item a subset S of BS closed under the operation {\tt add} ({\tt mul}).
\end{itemize}
Together with the above instances, a bundle dH containing the
terms  sS, sH  for above S, H respectively, is a complete 
representation of a {\tt Subsemigroup}.
  
Similar construction principle applies to {\tt Subgroup}, {\tt Subring}, 
{\tt Ideal}, and so on.
In particular,  the attributes usually related to  subsemigroup  may 
sometimes be accessible in other parts of the bundle  dH.
For example, the sample element and cardinality reside in the subset
term in dH.
\bigskip

\underbar{ {\tt subsmgType :: AddOrMul} } \ {\tt =}
\medskip

{\tt Add} \ means a semigroup by operation called \ {\tt add (+)},

{\tt Mul} \ \ldots \ by \ \verb#mul (*)#.

{\tt Add} \ is for the commutative case only.
\medskip


\underbar{ {\tt subsmgUnity :: MMaybe a} } \ {\tt =}
\medskip

{\tt Just (Just z)} \ means {\tt z} is an unity for H, both left and right,

{\tt Just Nothing} \ --- no such unity exist in H, 

{\tt Nothing} \      --- could not find unity in H. 

For the additive case, `unity' means zero.
\bigskip


\underbar{ {\tt subsmgGens :: Maybe [a]} } \ {\tt =}
\medskip

{\tt Just gs} \ means {\tt gs} is a finite generator list for H, 

{\tt Nothing} \ --- could not provide such list.
\bigskip


\underbar{{\tt subsmgProps :: Properties}}\verb#_Subsemigroup#
\medskip

is the association list for the properties of H. \\
The meaning of the properties listed in  \ \verb#Property_Subsemigroup# \
are evident.

For example, {\tt (IsGroup, Yes)} means {\tt add} restricted to H 
satisfies the Group laws.

{\tt IsOrderedSubsemigroup} \ means that 
\\
(1) H is commutative, \\
(2) \verb#compare_m# \ (of {\tt Set}) is a total ordering on 
  set(H) agreed with {\tt add (mul)}, \ \verb#zero_m# (\verb#unity_m#).




\subsection{ AddSemigroup category }
% ----------------------------------
\label{sec-smg.a} 

\footnotesize
\begin{verbatim}
  class Set a => AddSemigroup a  
    where  
    baseAddSemigroup :: a -> Domains1 a -> (Domains1 a, Subsemigroup a)

    add     :: a -> a -> a
    zero_m  :: a -> Maybe a      -- sa
    neg_m   :: a -> Maybe a
    sub_m   :: a -> a -> Maybe a
    times_m :: a -> Z -> Maybe a

    zero_m x = let  sH = snd $ baseAddSemigroup x Map.empty 
               in
               case  subsmgUnity sH  of  Just (Just z) -> Just z
                                         _             -> Nothing
    sub_m x = maybe Nothing (Just . add x) . neg_m
    times_m = timesbin                     -- default definition via `add'
\end{verbatim}
\normalsize

{\bf Presumed:}
\\ 
{\tt add} \ is associative, commutative, agreed with \ {\tt (==)}, \ 
\verb#zero_m#, \ \verb#neg_m#.

For example:  if for some {\tt x} \ \ \verb#zero_m# {\tt x = Just z}, 
\\  
then for all {\tt y} \ either \ \ \verb#neg_m# {\tt y = Nothing} \ \ or 
\\ 
\verb#neg_m# {\tt y == Just y'} \ and \ {\tt add y y' == z}.

The semigroup class operations relate to the domain of the 
{\it base semigroup} bH in the type {\tt `a'}.




\underbar{ {\tt Group} and {\tt Semigroup} categories }
\medskip

{\tt AddGroup} category declares only  {\tt baseAddGroup}  operation.
\\
The mathematicians usually relate to {\tt AddGroup} the operations 
{\tt 0}, {\tt neg(ate)}.
But {\tt DoCon} leaves them to {\tt AddSemigroup} --- in the form of \ 
\verb#zero_m#, \ \verb#neg_m#. 
They are partial: may return  {\tt Nothing},  if H is not a group.

Similar approach is applied to {\tt Ring} and other categories.

There are also ``polymorphic'' operations (not from the class).
Thus, 
\begin{verbatim}
  neg x = case  neg_m x  of  Just x -> x 
                             _      -> error (... "neg  failed" ...)
\end{verbatim}
never cause a break for H, if H occurs a {\tt Group}, but otherwise,  
may cause it.
\bigskip

\footnotesize
\begin{verbatim}
  class (OrderedSet a, AddSemigroup a) => OrderedAddSemigroup a

     -- Presumed:  base AddSemigroup  contains  (IsOrderedSubsemigroup, Yes)
     --            - see Subsemigroup constructor.
\end{verbatim}
\normalsize




\subsection{ Several usable functions for semigroup }
% ---------------------------------------------------
\label{sec-smg.fn} 

\footnotesize
\begin{verbatim}
  zeroS :: AddSemigroup a => a -> a         -- zero of a semigroup
                        --   sa       

  zeroS x = fromMaybe (error msg) $ zero_m x
              where
              msg = ("(zero x)  failed,"++) $ showsWithDom x "x" "" ""

  isZero :: AddSemigroup a => a -> Bool  
  isZero                      a =  case zero_m a of  Just z -> a==z
                                                     _      -> False
  neg :: AddSemigroup a => a -> a
  neg                      x =  fromMaybe (error ...) $ neg_m x

  sub :: AddSemigroup a => a -> a -> a
  sub                      x    y =  fromMaybe (error ...) $ sub_m x y

  times :: AddSemigroup a => a -> Z -> a
  times                      x    n =  fromMaybe (error ...) $ times_m x n
\end{verbatim}
\normalsize
The above functions yield Break + message when fail to find zero
or the opposite element in a semigroup.


\footnotesize
\begin{verbatim}
  isGroup, isCommutativeSmg :: Subsemigroup a -> PropValue

  isGroup          = lookupProp IsGroup     . subsmgProps
  isCommutativeSmg = lookupProp Commutative . subsmgProps

  isoSemigroup :: (a->b) -> (b->a) -> Subsemigroup a -> Subsemigroup b

    -- given a  Subsemigroup H with the base set X on a type `a',
    --   a map  f: a -> b  injective on X,  f_inv  inverse to  f  on X,
    -- produce  Subsemigroup H'  on the base set f(X),  such that
    -- f_restrictedTo_X  is isomorphism between H and H'

  trivialSubsemigroup :: Subsemigroup a -> Subsemigroup a
    --
    -- a trivial subsemigroup ({0} or {1}) inside a non-trivial base monoid)
\end{verbatim}
\normalsize



\subsection{ Multiplicative semigroup }
% -------------------------------------
\label{sec-smg.m} 


It is similar to  {\tt AddSemigroup}, only it may be non-commutative.
%
\footnotesize{
\begin{verbatim}
  class Set a => MulSemigroup a          
    where        
    baseMulSemigroup :: a -> Domains1 a -> (Domains1 a, Subsemigroup a)

    mul       :: a -> a -> a           -- multiplication
    unity_m   :: a -> Maybe a          -- sa     
    inv_m     :: a -> Maybe a          -- inversion
    divide_m  :: a -> a -> Maybe a
    divide_m2 :: a -> a -> (Maybe a, Maybe a, Maybe (a,a))
    power_m   :: a -> Z -> Maybe a
    root      :: Z -> a -> MMaybe a    -- root of n-th degree

    unity_m x = -- sa
                case  subsmgUnity $ snd $ baseMulSemigroup x Map.empty  of  Just u -> u
                                                                      _      -> Nothing
    inv_m  x = maybe Nothing (\un -> divide_m un x) $ unity_m x
    power_m  = powerbin                            -- binary method to power via `mul'
\end{verbatim}
}


{\bf Presumed:} \ {\tt mul} is associative, agreed with {\tt (==)}, 
\verb#unity_m#, \verb#inv_m#.
So it makes a base multiplicative semigroup BH.

\verb#divide (_m)# 
\\
is for the left-side quotient: for solving for {\tt x} of the
equation \ \verb#x*a = b# \ in a semigroup.
The solution may occur not unique. Returned is some {\tt x}, not
necessarily the `best' one.
For a {\tt Ring}, we can only rely (in the general case) on that \ 
{\tt x-y} \ is a {\emph zero divisor} for any solutions {\tt x}, {\tt y}. 
Thus, {\tt x} is unique if a ring has not zero divisors.

Similar is \ \verb#inv(_m).#
\medskip

\verb#divide (_m2)# 
\\
generalizes \verb#divide_m#. It yields left, right, and bi-sided
maybe-quotient.

Example: \ in \ {\tt FreeMonoid[a,b,c]}
\footnotesize{
\begin{verbatim}
          divide_m2 abccb cb =  (Just abc, Nothing, Just (abc, []))
          divide_m2 abccb cc =  (Nothing,  Nothing, Just (ab,b)   )
\end{verbatim}
}
\medskip


{\tt root n x} \ may yield \ {\tt Just (Just r) | Just Nothing | Nothing}.
\\
This means respectively \\
``this \ {\tt r} \ from BH is the root of n-th degree of {\tt x}'', \\
``such a root does not exist in BH'', \\
``could not find such a root in BH''.

Some functions related to {\tt MulSemigroup}: 
%
\footnotesize{
\begin{verbatim}
  unity :: MulSemigroup a => a -> a    -- sa
  unity                      x =  fromMaybe (error msg) $ unity_m x
                   where
                   msg = ("unity x   failed,"++) $ showsWithDom x "x" "" "\n"

  inv :: MulSemigroup a => a -> a
  inv                      x =  fromMaybe (error ...) $ inv_m x

  divide :: MulSemigroup a => a -> a -> a
  divide                      x    y =  fromMaybe (error ...) $ divide_m x y

  invertible :: MulSemigroup a => a -> Bool
  invertible = isJust . inv_m

  divides :: MulSemigroup a => a -> a -> Bool
  divides                      x    y =  isJust $ divide_m y x

  power :: MulSemigroup a => a -> Z -> a
  power                      x    n =  fromMaybe (error ...) $ power_m x n
\end{verbatim}
}
\medskip

{\bf Use \ \verb#power (_m)# \ rather than `\verb#^#':}
\\
the former is more generic, the latter is of the Haskell library.




\section{ Monoid }
% ----------------
\label{sec-mnd} 

\footnotesize
\begin{verbatim}
  class AddSemigroup a => AddMonoid a

  class (OrderedAddSemigroup a, AddMonoid a) => OrderedAddMonoid a

  class MulSemigroup a => MulMonoid a
  class MulSemigroup a => OrderedMulSemigroup a

  class (OrderedMulSemigroup a, MulMonoid a) => OrderedMulMonoid a
\end{verbatim}
\normalsize

For a dynamic parametric domain {\it D(p)} inside a type \ {\tt a}, 
declaring 
\begin{center}    {\tt instance \ldots \  => AddMonoid D(p)}
\end{center} 
means that for \ {\tt x :: a} \ containing appropriate value of {\tt p}
a base semigroup of {\tt x} has zero.
And in such case \ {\tt zeroS x} \ gives this zero element, and
\verb#zero_m# becomes unnecessary.






\section{ Group }
% ---------------
\label{sec-grp}  


This category is implemented in the module {\tt SetGroup.hs}. \\
The {\tt Subgroup} expression is defined in the modle {\tt Categs.hs}.



\subsection{ AddGroup, MulGroup categories }
% ------------------------------------------
\label{sec-grp.ct} 


\footnotesize
\begin{verbatim}
  class AddMonoid a => AddGroup a  
    where
    baseAddGroup :: a -> Domains1 a -> (Domains1 a, Subgroup a)  

    -- Presumed:  zeroS, add, neg  of base semigroup BH satisfy the group axioms.
    -- This condition corresponds to  (IsGroup, Yes)  contained in the 
    -- property list of BH.

  class (AddGroup a, OrderedAddMonoid a) => OrderedAddGroup a
                 -- 
                 -- base AddGroup  contains  (IsOrderedSubgroup, Yes)
                 -- - see the Subgroup constructor.

  class (MulMonoid a) => MulGroup a
    where
    baseMulGroup :: a -> Domains1 a -> (Domains1 a, Subgroup a)

  class (OrderedMulMonoid a, MulGroup a) => OrderedMulGroup a
\end{verbatim}
\normalsize



\subsection{ Subgroup term }
% --------------------------
\label{sec-grp.sb} 

\footnotesize
\begin{verbatim}
  data  {-Add(Mul)Group a=>-}  Subgroup a =

       Subgroup {subgrType    :: AddOrMul,
                 subgrGens    :: Maybe [a],
                 subgrCanonic :: Maybe (a -> a),
                 subgrProps   :: Properties_Subgroup,
                 subgrConstrs :: [Construction_Subgroup a],
                 subgrOpers   :: Operations_Subgroup a
                }
  type Properties_Subgroup = [(Property_Subgroup, PropValue)]
  data Property_Subgroup   = IsCyclicGroup | IsPrimeGroup | IsNormalSubgroup
                             | IsMaxSubgroup | IsOrderedSubgroup
                             deriving (Eq, Ord, Enum, Show)
data Construction_Subgroup a = ... DUMMY
type Operations_Subgroup a   = ... DUMMY
data OpName_Subgroup         = ... DUMMY
data Operation_Subgroup a    = ... DUMMY
\end{verbatim}
\normalsize

This expresses a {\tt Subgroup} H in a base group {\tt G}.
Unity, zero \ are obtained by applying of \ \ 
{\tt unity x}, {\tt zeroS x} \ \ respectively.
\bigskip

\underbar{{\tt subgrType :: AddOrMul}}    

--- additive | multiplicative  \ is like in {\tt Subsemigroup}.
\bigskip


\underbar{{\tt subgrGens :: Maybe [a]}}
\medskip

  {\tt Just gs} \ means {\tt gs} is a finite list of the group 
                  generators for H.

  {\tt Nothing} \ means fail to provide such a list.
\bigskip


\underbar{{\tt subgrCanonic :: Maybe (a -> a)}} \ {\tt =}
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Just cn} \ means \ {\tt cn: G -> G} \ 
      is a canonical map for the congruence classes \verb#x*H:#
      \\
  {\tt cn(x)-x $\in$ H \ \ And \ \ x-y $\in$ H $\Leftrightarrow$ \
       cn(x) = cn(y) \\ 
       And \ \ cn(zero+H) = zero
  } \\
  --- similar \verb#*-# denotations are for the {\tt Mul} case.

\item {\tt Nothing} \ means fail to provide such a map.
\end{itemize}
\medskip


\underbar{{\tt subgrProps :: Properties}}\verb#_Subgroup#
\medskip

The property names in this list have the usual algebraic meaning. \\
And \ {\tt (IsOrderedSubgroup, Yes)} \ means that 
\\
(1) {\tt Subsemigroup} for H has \ {\tt (IsOrderedSubsemigroup, Yes)},\\
(2) \verb#compare_m# \ agrees with \ {\tt neg} --- in {\tt Add} case, \
    with \ {\tt mul} --- in {\tt Mul} case.




\subsection{ Several usable functions for subgroup }
% --------------------------------------------------
\label{sec-grp.fn} 


\footnotesize
\begin{verbatim}
  absValue :: AddGroup a => a -> a     -- this is correct for (IsOrderedGroup, Yes)
  absValue                  x =  if  less_m x (zeroS x)  then  neg x  else  x

  trivialSubgroup :: a -> Subgroup a -> Subgroup a
                                  -- make trivial subgroup in non-trivial base group
  trivialSubgroup zeroOrUnity gG = 
    Subgroup 
       {subgrType    = subgrType gG,  subgrGens  = Just [zeroOrUnity],
        subgrCanonic = Just id,       subgrProps = props,
        subgrConstrs = [],            subgrOpers = []
       }
      where    
      props = [(IsCyclicGroup, Yes), (IsPrimeGroup, No), (IsNormalSubgroup, Yes),       
               (IsMaxSubgroup, No), (IsOrderedSubgroup, isOrderedGroup gG)
              ]
  
  isoGroup:: (a -> b) -> (b -> a) -> Subgroup a -> Subgroup b

    -- Given a   Subgroup G with the base set X on a type `a',
    --    a map  f: a -> b  injective on X,  f_inv  inverse to  f  on X,
    -- produce the  Subgroup G' on the base set f(X),  such that  
    -- f_restrictedTo_X  is an isomorphism between G and G'.
\end{verbatim}
\normalsize




\section{ Ring }
% --------------
\label{sec-rg}  


This category is exported from the module {\tt RingModule}, \\ 
implemented in the \ \verb#Ring*# modules, \ {\tt Subring} --- in 
the module {\tt Categs}.


\subsection{ Ring category }
% --------------------------
\label{sec-rg.ct} 

\footnotesize
\begin{verbatim}
  class (AddGroup a, MulSemigroup a, Num a, Fractional a) => Ring a  
    where
    baseRing :: a -> Domains1 a -> (Domains1 a, Subring a)

    fromi_m  :: a -> Z -> Maybe a   -- standard homomorphism from integer
              --sa                  

    fromi_m x n = maybe Nothing (\u-> times_m u n) $ unity_m x
\end{verbatim}
\normalsize
{\bf Presumed:} 

(1) non-zero {\tt baseAddSemigroup} A and {\tt baseMulSemigroup} H \ 
    have the same base set BS,

(2) {\tt add, mul} \ obey the ring laws on BS, 

(3) {\tt add, mul, divide} \ \ agree with the {\tt Haskell} intances 
    of \ {\tt Num, Fractional}: \\

    \verb#(+) = add, (*) = mul, (/) = divide#.




\subsection{ Subring term }
% -------------------------
\label{sec-rg.sub} 

\footnotesize
\begin{verbatim}
  data Subring a = Subring {subringChar    :: Maybe Z,
                            subringGens    :: Maybe [a],
                            subringProps   :: Properties_Subring,
                            subringConstrs :: [Construction_Subring a],
                            subringOpers   :: Operations_Subring a
                           } 
  type Properties_Subring     = [(Property_Subring, PropValue)]
  data Construction_Subring a = ... DUMMY 
  type Operations_Subring a   = [(OpName_Subring, Operation_Subring a)]
  data OpName_Subring         = WithPrimeField -- | ...
                                          deriving(Eq, Ord, Enum, Show)
\end{verbatim}
\normalsize
%
This describes a subring R of a base ring bR.
\bigskip 


\underbar{{\tt subringChar :: Maybe Z}}

  is the characteristic of a ring. It may be

  {\tt Just n} \ --- which means characteristic {\tt n} $\geq 0$,

  {\tt Nothing} \ --- unknown characteristic.
\bigskip 


\underbar{{\tt subringGens :: Maybe [a]}} \ {\tt =}

  {\tt Just gs} \ --- 
                means {\tt gs} is a finite ring generator list for R,
 
  {\tt Nothing} \ --- means {\tt DoCon} could not provide such generators.        

{\bf Example:} \\ 
for a bundle {\tt dP} of domain {\tt Z[x]}, \ {\tt subringGens dP} 
may be \ {\tt Just [1,x]}, \\ 
and for  {\tt Rational[x]}, \ it has to be {\tt Nothing}. Because, for 
example, {\tt 1/2} cannot be generated from \ {\tt 1} and {\tt x}.
\bigskip 


\underbar{{\tt subringOpers :: Operations}}\verb#_Subring a#
\begin{center}   
\verb#data OpName_Subring = WithPrimeField  deriving(Eq, Ord, Enum, Show)#
\end{center}
--- so far, it has one member.

Example of application: \\
DoCon  uses it in factorization programs for the polynomials 
over arbitrary finite field, when finds a primitive generator for 
a field extension, and so on.

\footnotesize
\begin{verbatim}
  data Operation_Subring a =
       WithPrimeField' {frobenius            :: (a -> a, a -> MMaybe a),
                        dimOverPrime         :: InfUnn Z,
                        primeFieldToZ        :: a -> Z,
                        primeFieldToRational :: a -> Fraction Z,
                        primitiveOverPrime   :: ([a], [UMon a], a-> [UMon a])
                       }
       -- | ...
\end{verbatim}
\normalsize
It has sense in the subring term for \ R \ only when the {\tt Integer}
ring image 
\begin{center}  {\tt Z' = F(Z)}, \ where {\tt F(n) = times unity n}, 
\end{center}
extends to the field inside R.  
This field is called a \ prime field \ PF.

Thus, for a field R of char(R) = 0, \ PF \ is a copy of the field
{\tt Rational}.  The case \\
 char = p $> 0$ \ makes \ PF = GaloisField(p). \ 
In both cases  R  is a vector space over  PF.
\bigskip 


\underbar{{\tt frobenius :: (a -> a, a -> MMaybe a)}}

is \ {\tt undefined} \ for \ {\tt p = char R = 0}, \ \
otherwise, it is \ {\tt (pc, pcInv)}. 

\verb#pc = (^p) :: a -> a# \ is a ring homomorphism, \ 
{\tt pcInv} \ its inverse.
{\tt pcInv} has the same format as \ {\tt MulSemigroup.root}, \ 
\verb#(^p)# may be not invertible for some domains \ {\tt a}.
\bigskip 


\underbar{{\tt dimOverPrime :: InfUnn Z}} \ 
                                        is the dimension over a prime field.

{\tt Examples:} \\
{\tt Z} \ has to contain {\tt UnknownV} in its {\tt dimOverPrime},
\\
{\tt Fraction Z} \ and \ {\tt Z/(5)} \ \ have \ {\tt Fin 1}, 
\\
\verb#(Z/(5))[x] /(x^2+2)# \ has \ {\tt Fin 2}, \ \ \
                          {\tt (Fraction Z)[x]} \ has {\tt Infinity}.
\bigskip 


\underbar{{\tt primeFieldToZ :: a -> Z}}

is \ {\tt undefined} \ for \ {\tt p = char = 0}. 
\\
For {\tt p > 0}, the restriction of {\tt primeFieldToZ} to PF  
has to be the inverse map for \ {\tt fromi} \ on {\tt [0 .. p-1]}.
\bigskip 


\underbar{{\tt primeFieldToRational :: a -> Fraction Z}}

is \ {\tt undefined} \ for \ {\tt p = char > 0}. 
\\
For {\tt p = 0}, it should be the isomorphism: \ 
PF $\rightarrow$ Rational numbers.
\bigskip


\underbar{{\tt primitiveOverPrime :: ([a], [UMon a], a -> [UMon a])}} \ {\tt =}

{\tt (powers, mp, toPol)}

To skip this `primitive element' construct, put \ {\tt powers = []}.
\\
Otherwise, \ \verb#powers = [g^i | i <- [1 ..]]#, 
\\
with {\tt g} some primitive generator for a ring \ {\tt a} \ over PF,
\\
{\tt mp} minimal polynomial for {\tt g} over PF, given as a sparse 
  list of monomials ({\tt []} for the dummy), 
  with the coefficients from  PF,
\\
{\tt toPol :: a -> [UMon a]} \ is either \ {\tt const []} \ (for dummy) 
  or represents canonically each element of \ {\tt a} \ 
  as the value {\tt f(g)} of polynomial {\tt f} over PF.

Here \ {\tt g = head powers} \ is a primitive generator, \ 
{\tt deg f < deg mp}, \
any element of \ {\tt a} \ is {\tt f(g)} for some polynomial \
{\tt f} from PF[x], \ 
the representing polynomial {\tt f(g)} in  {\tt toPol}  is given by a
sparse list of monomials over {\tt PF}.
\bigskip


{\bf Finding primitive element for field extension}
\medskip

There exist clever methods for this --- for example, for the case of a
finite field.
But  DoCon  finds a primitive {\tt g} by brute force.
This can be improved in future.
But even as it is now, this is not so bad. Because starting from \ 
$x, x+1,$ \ldots, \ a primitive element {\tt g} is found fast enough, 
on average. After this, {\tt g} is set in the ring term, and it becomes 
ready for the repeated use.

This is exploited by the factorization function for \  
$ GF(q)[x_1,\ldots,x_n]$, \ $q = p^m$.

Given a finite field tower \ \ 
                   K (prime) \verb#--# F \verb#--# \ldots \ \verb#--# E, 
\\  
{\tt DoCon} finds a generator {\tt g} for E over K and factors the given
polynomial over E by reducing to the case of a canonic  finite field \ 
K[g]/minimalPolynomial(g).




\subsection{ Subring properties }
% -------------------------------
\label{sec-rg.pr} 

\footnotesize
\begin{verbatim}
  data Property_Subring =                        
       IsField | HasZeroDiv | HasNilp | IsPrimaryRing | Factorial
       | PIR | IsOrderedRing | IsRealField | IsGradedRing
       deriving (Eq, Ord, Enum, Show)
                             -- IsGradedRing  refers to Operations_Subring
\end{verbatim}
\normalsize
Below, we describe the properties meaning only for a {\it base ring} R.
\medskip

{\tt PIR} \ === \ R is an abstract principal ideal ring. 

{\tt HasZeroDiv} \ === \ R has a zero divisor. 

{\tt HasNilp} \ === \ R has a nilpotent.

{\tt IsPrimaryRing} \ === \ each zero divisor is a nilpotent.

{\tt Factorial} \ === \ abstract unique-factorization ring.
\medskip

{\tt IsGradedRing} \ === \
  the triplet \ {\tt (Grading' cp weight forms)} \ from \ 
  {\tt operations} \ satisfies the grading laws for the \
  \verb#weight: R -> Z^n,   Z^n# \ ordered by this \ {\tt cp}, \\ 
  {\tt forms: R -> [R]} \ \ yields the list of homogeneous forms.
\medskip

{\tt IsRealField} \ === \ {\tt IsField} \ And \ 
                                   $-1$ is not a sum of squares in R.
\medskip

{\tt IsOrderedRing} \ === \
\\
  {\tt Commutative},\ with \ unity $\neq$ zero, \ \ 
  additive subgroup is ordered by \verb#compare_m#, 
  \\
  \verb#compare_m# yields the positive-negative partition \ \ 
                      $R = \{0\} \cup P \cup (-P)$ \ satisfying 
  \\ 
  $ x, y \in P \ \Longrightarrow \ x+y, \ x*y \in P $

  {\bf Lemma.} \  
  IsOrderedRing(R) $\Longrightarrow$ \ R has not zero divisors, \\
  and there is an induced `Ordered' structure on Fraction(R).
\medskip

DoCon  pays attention mostly to the case of a base ring, 
considering other case as exotic.
Though, the proper subring appears when the ideal bundle is formed.




\subsection{ Several usable functions for ring }
% ----------------------------------------------
\label{sec-rg.fn} 


\footnotesize
\begin{verbatim}
  fromi :: Ring a => a -> Z -> a                  -- map from integer by sample
  fromi              x    n =  fromMaybe (error msg) $ fromi_m x n
    where
    msg = ("fromi x "++) $ shows n $ showsWithDom x "x" "" "\n"

  char :: Ring a => a -> Maybe Z                
  char              a =  subringChar $ snd $ baseRing a Map.empty
                              -- characteristic of ring defined by given sample

  property_Subring_list = [IsField ..]

  dimOverPrimeField :: Subring a -> InfUnn Z
  dimOverPrimeField    rR        =
                     case  lookup DimOverPrimeField$ subringOpers rR
                     of
                       Nothing                     -> UnknownV
                       Just (DimOverPrimeField' v) -> v
      -- examples:
      -- Z, Z[x] --> UnknownV,  Z/(3) --> Fin 1,   (Z/(3))[x] --> Infinity
 
  isField, isOrderedRing :: Subring a -> PropValue

  isPrimeIfField :: Subring a -> PropValue  -- find, whether R is a prime field
                                            -- (correct to apply only for a field)

  zeroSubring :: a -> Subring a -> Subring a   -- zero subring in a Non-zero base ring
  zeroSubring    zr   _         =
    Subring 
      {subringChar  = Just 0,              subringGens    = Just [zr],
       subringProps = props_Subring_zero,  subringConstrs = [],
       subringOpers = []
      }

  multiplicity :: CommutativeRing a =>  a -> a -> (Z, a)
                                     -- x    y     m  q
    -- Multiplicity of  x  in  y  in a factorial ring - correct for (Factorial,Yes)
    -- q = y/(x^m).  x, y  non-zero,  x  should Not be invertible.

  multiplicity x y
    | isZero x || isZero y || isJust (inv_m x) = error ...
    | otherwise                                =
                            if  not $ divides x y  then  (0,y)  else  mlt x y 0
                    where
                    mlt x y m = maybe (m,y) (\q-> mlt x q (m+1)) $ divide_m y x


  isoRing :: (a -> b) -> (b -> a) -> Subring a -> Subring b
             -- f        fInv        rA           rB
    -- Given a ring term  rA  with the base set X on a type `a',
    --       a map  f: a -> b  injective on X,  f_inv inverse to f on X,
    -- produce the ring term  rB  on the base set f(X),  such that  
    -- f_restrictedTo_X  is an isomorphism between these rings.
\end{verbatim}
\normalsize





\section{ GCDRing }
% -----------------
\label{sec-gcd}  


This category is exported from {\tt RingModule}, implemented in  
\verb#Ring*#  modules, \ {\tt GCDRingTerm} --- in module {\tt Categs}.

\footnotesize
\begin{verbatim}
  class Ring a => CommutativeRing a
                  -- Presumed:  Commutative==Yes  for base multiplicative semigroup

  class (CommutativeRing a, OrderedAddGroup a) => OrderedRing a
                                     -- Presumed: (IsOrderedRing, Yes) for the base ring

  class (CommutativeRing a, MulMonoid a) => GCDRing a    -- presumed: (HasZeroDiv, No) 
    where
    baseGCDRing  :: a -> Domains1 a -> (Domains1 a, GCDRingTerm a)
    canAssoc     :: a -> a                   -- canonical associated element
    canInv       :: a -> a                   -- canonical invertible factor
    gcD          :: [a] -> a                 -- gcd, lcm  for a list
    lcM          :: [a] -> a
    hasSquare    :: a -> Bool                -- "has a multiple prime factor"
    toSquareFree :: a -> Factorization a

    canAssoc x = x/(canInv x)

    lcM []     = error "lcM [] \n"
    lcM [x]    = x
    lcM [x,y]  = y*( x/(gcD [x,y]) )
    lcM (x:xs) = lcM [x, lcM xs]

    -- the correctness of these operations depend on the
    -- WithCanAssoc, WithGCD  values - see below

  data GCDRingTerm a = GCDRingTerm {gcdRingProps :: Properties_GCDRing
                                    -- this is all, so far
                                   } deriving (Show)
  type Properties_GCDRing = [(Property_GCDRing, PropValue)]
  data Property_GCDRing   = WithCanAssoc | WithGCD  deriving(Eq, Ord, Enum, Show)
\end{verbatim}
\normalsize

{\tt (WithCanAssoc, Yes)} 
\\ 
means that \ {\tt canAssoc, canInv} \ are correct algorithms for the 
canonical \\
associated element and the canonical invertible factor.
\medskip

{\tt (WithGCD, Yes)} \\ 
means {\tt (Factorial, Yes)} and that {\tt gcD} is a correct algorithm 
for the \\
greatest common divisor.

\begin{center} {\tt toSquareFree :: a -> Factorization a}
\end{center}
returns \ {\tt [($a_1, 1$) \ldots \ ($a_m, m$)]}, \ \
where \ {\tt (canAssoc a) =} $a_1^1 \cdot \ldots \ \cdot a_m^m$, \\
each $a_i$ is square free and \  \
$\gcd \ a_i \ a_j = 1$ \ for $i \neq j$, \\
invertible  $a_i$  are skipped, in particular, {\tt []} is returned for
invertible \ {\tt a}.

\begin{verbatim}
                isGCDRing :: GCDRingTerm a -> PropValue
                isGCDRing = lookupProp WithGCD . gcdRingProps
\end{verbatim}
The property like {\tt WithGCD} for the category {\tt GCDRing} 
may look like a tautology. But recall of the parametric domains.

\underbar{Example 1} \ \ {\tt DoCon} contains the declaration 
\begin{center}
               {\tt instance GCDRing a => GCDRing (Pol a) where} \ldots
\end{center}
which looks quite natural.
\medskip

\underbar{Example 2} \ \ It also contains 
\begin{verbatim}
  instance EuclideanRing a => GCDRing (ResidueE a)
    where
    canInv, canAssoc, gcD   are defined trivially
\end{verbatim}
--- which may look strange.

Consider a residue ring \ {\tt rR = a/(b)} \ of an Euclidean ring \ 
{\tt a}. Evidently,  this instance has sense only for {\tt rR} being
a field (that is for a prime {\tt b}). And the aforementioned three 
operations have to be defined trivially.

For not a prime {\tt b}, \ \ {\tt rR = a/(b)} \ \ still fits the 
{\tt GCDRing} class declaration. \\
But \ \ {\tt isGCDRing rR --> No} \ \
would show that {\tt rR} is not actually a gcd-Ring.
This is why the above properties are introduced.

Similar approach is applied to other categories.
\medskip

\underbar{Examples with GCDRing:}
\begin{verbatim}
  canAssoc (2 :: Z) = 2;    canAssoc (-2) = 2;   canInv (-2) = -1;
  canAssoc (2:/3 :: Fraction Z) =  1:/1
  canAssoc ((2:/3)*x^2 + 1)     =  x^2 + (3:/2)   in  (Fraction Z)[x]
  gcD [12,6,9] = 3
\end{verbatim}





\newpage
\section{ FactorizationRing }
% ---------------------------
\label{sec-ftr}  


This category is exported from the module {\tt RingModule}, 
implemented in \verb#Ring*#  modules,
{\tt FactrRingTerm} is from the module {\tt Categs}.

\footnotesize
\begin{verbatim}
  type {-Ring a => -}  Factorization a = [(a, Z)]

    -- Example:  8*49*3 = 2^3*7^2*3
    --           expresses as  [(2,3),(7,2),(3,1)]  :: Factorization Z

  class GCDRing a => FactorizationRing a    -- presumed: (WithGCD, Yes)
    where
    baseFactrRing :: a -> Domains1 a -> (Domains1 a, FactrRingTerm a)
    isPrime       :: a -> Bool           
    factor        :: a -> Factorization a 
    primes        :: a -> [a]               -- sa

    isPrime x = case  factor x  of  [(_,1)] -> True
                                    _       -> False

  data FactrRingTerm a =
       FactrRingTerm {factrRingProps :: Properties_FactrRing  -- this is all, so far
                     } deriving (Show)

  type Properties_FactrRing = [(Property_FactrRing, PropValue)]
  data Property_FactrRing   = WithIsPrime | WithFactor | WithPrimeList
                              deriving (Eq, Ord, Enum, Show)

  -- (WithIsPrime  , Yes) means  isPrime    is the correct primality test
  -- (WithFactor   , Yes)        factor     is the correct factorization   
  -- (WithPrimeList, Yes)        (primes _) is the correct list of primes

  isRingWithFactor :: FactrRingTerm a -> PropValue
  isRingWithFactor = lookupProp WithFactor . factrRingProps
\end{verbatim}
\normalsize

{\tt primes} {\it sample} 
\\
is some infinite list of primes $p_i$,  free of repetitions,
each $p_i$ in {\tt canAssoc} form; \\ 
it returns {\tt []} for the fail.

{\tt Examples.}

(1) \ \verb#primes _# \ {\tt :: [Z] = \ [2, 3, 5, 7, 11, \ldots]}.

(2) \ For any {\tt f} from \ {\tt (Z/(3))[x]} 
\\ 
\verb#primes f =  [x, x+1, x+2, x^2+1, x^2+x+2, ..., x^3+2*x+2, ...]#

See also \ \verb#demotest/T_pfactor.hs# \ 
for the polynomial factorization examples.




\newpage
\subsection{ Some operations with factorizations }
% ------------------------------------------------
\label{sec-ftr.op} 


\footnotesize
\begin{verbatim}
  unfactor :: MulSemigroup a => Factorization a -> a
                                            -- example:  [(a,1),(b,2)] -> a*b^2
  unfactor []        = error "unfactor []\n"
  unfactor [(a,k)]   = power a k
  unfactor ((a,k):f) = mul (power a k) $ unfactor f

  isPrimeFactrz, isPrimaryFactrz, isSquareFreeFactrz :: Factorization a -> Bool
  isPrimaryFactrz [_] = True
  isPrimaryFactrz _   = False

  isPrimeFactrz [(_, 1)] = True
  isPrimeFactrz _        = False

  isSquareFreeFactrz f = (not $ null f) && all ((==1) . snd) f

  factrzDif :: Eq a => Factorization a -> Factorization a -> Maybe (Factorization a)
    --
    -- Difference of factorizations.  The order of factors immaterial.
    -- Examples:  [(a,1),(b,2)] [(a,1),(b,2)] -> Just []
    --            [(a,1),(b,2)] [(b,1)]       -> Just [(a,1),(b,1)]
    --            [(a,1),(b,2)] [(b,3)]       -> Nothing

  eqFactrz :: Eq a => Factorization a -> Factorization a -> Bool
                                -- Equality. The order of factors is immaterial

  gatherFactrz :: Eq a => Factorization a -> Factorization a
    --
    -- Bring to true factorization by joining the repeated factors.
    -- Example:  [(f,2),(g,1),(f,3)] -> [(f,5),(g,1)]
\end{verbatim}
\normalsize





\newpage
\section{ Syzygy solvable ring }
% ------------------------------
\label{sec-linr}  


This category is exported from {\tt RingModule}, implemented in 
\verb#Ring*# modules, \\ 
{\tt LinSolvRingTerm} --- in module {\tt Categs}.

\footnotesize
\begin{verbatim}
  class (CommutativeRing a, MulMonoid a) => LinSolvRing a
    where
    baseLinSolvRing :: a -> Domains1 a -> (Domains1 a, LinSolvRingTerm a)

    gxBasis :: [a] -> ([a], [[a]])
             --xs      gs   mt

    moduloBasis :: String -> [a] -> a -> (a,[a])
    syzygyGens  :: String -> [a] -> [[a]]
\end{verbatim}
\normalsize
This means a {\tt Ring} with the {\it solvable linear equations  and  solvable
ideal inclusion} \\
(see first Section~\ref{sec-gx}).

{\tt DoCon} decides that these operations make sense and are solvable when the 
corresponding {\tt LinSolvRingTerm} data contains the pair 
{\tt (IsGxRing, Yes)} in its property list.




\subsection{ gxBasis }
% --------------------
\label{sec-linr.g} 


{\tt gxBasis xs} \ yields \ {\tt (gs, mt)},
\\
where {\tt gs} is a gx-basis for \ {\tt I = Ideal(xs) = Ideal(gs)}, \ \ 
that is

  {\tt gs} does not contain zeroes,
  
  {\tt moduloBasis "g"  gs} \ \ is a detaching map modulo {\tt I},

  {\tt moduloBasis "cg" gs} \ \ is a canonic map modulo {\tt I}.

  {\tt mt} \ \ is the transformation matrix.
\medskip

If  {\tt xs}  consists of zeroes, then  {\tt gxBasis}  has to yield 
{\tt ([], Mt [])}.

{\bf Example:} \
for the polynomials over an c-Euclidean ring R, 

  {\tt gs} is a strong reduced Gr\"obner basis --- for R a field, 

  weak reduced Gr\"obner basis --- otherwise 
                    (see (Section~\ref{sec-pol.a.gr} Point pol.a.gr.g)).


\subsection{ moduloBasis }
% ------------------------
\label{sec-linr.m} 


{\tt moduloBasis mode basis f -> (rem, quot)}

is a zero-detaching reduction modulo the given generators \ {\tt basis} \
(of ideal I).

{\tt mode = cMode ++ gMode,  \ cMode = "" | "c", \  gMode = "" | "g"}

{\tt cMode = "c"} \ means a canonic reduction.

{\tt cMode = ""} \ 
      means only the reduction in which the zero modulo I is detached.

{\tt gMode = "g"} \  means a  gx-basis. 
\\
  other value means that nothing is known about the basis. \\
  In this latter case, it is applied the composition of 
  {\tt gxBasis} and \ \verb#moduloBasis (_:'g')#.

{\bf Example:} \\
for the polynomials \ $ f = 2 x^2, \ g = y + x, \ h = y + 2 x $ \ 
from $K[x,y]$, \ K a field, and any admissable power product ordering 
with \ $y > x$,  

{\tt reduceByX mode = fst . moduloBasis mode [x]}, \\
{\tt reduceByX "g"} \ maps $f$ to 0 and leaves \ $g, h$ \ unchanged, \\
{\tt reduceByX "cg"} \ maps $f$ to 0, \ $g, h$ \ to \ $y$.




\subsection{ syzygyGens }
% -----------------------
\label{sec-linr.s} 


{\tt syzygyGens mode xs -> relationVectors}

{\tt mode = ""} \ \ means the generic case, 
 
  {\tt "g"} \ is for a polynomial ring \ $A = R[x_1,\ldots,x_n]$  
         over an Euclidean ring R.

  {\tt "g"} means that {\tt xs} is a (weak) Gr\"obner basis --- the 
            evaluation will be more direct in such case.

{\bf Example:} \\
{\tt syzygyGens "" ([3,4,5,6] :: Z) = [[6,-6,0,1], [5,-5,1,0], [4,-3,0,0]]}
\\
acts as a solution of a generic homogeneous linear system over an
Euclidean ring.




\subsection{ LinSolvRingTerm }
% ----------------------------
\label{sec-linr.t} 


\footnotesize
\begin{verbatim}
  data LinSolvRingTerm a =
       LinSolvRingTerm {linSolvRingProps :: Properties_LinSolvRing
                        -- this is all, so far
                       } deriving (Show)

  type Properties_LinSolvRing = [(Property_LinSolvRing, PropValue)]
  data Property_LinSolvRing   =
       ModuloBasisDetaching | ModuloBasisCanonic | WithSyzygyGens | IsGxRing 
                                                 deriving (Eq, Ord, Enum, Show)
  isGxRing :: LinSolvRingTerm a -> PropValue
  isGxRing = lookupProp IsGxRing . linSolvRingProps
\end{verbatim}
\normalsize

{\tt (ModuloBasisDetaching, Yes)} 
\\  
means that for any \ {\tt xs}, \ \verb#gs = fst $ gxBasis xs,  I = Ideal(gs)#
\\
the map \ {\tt moduloBasis ({\it anycMode}++"g") gs y --> (r, q)}
\\
satisfies the ideal detachability: \ 
{\tt y} $\in$ {\tt I} $\Leftrightarrow$ {\tt r == zero}
\medskip

{\tt (ModuloBasicCanonic, Yes)}
\\
means \ {\tt (ModuloBasisDetaching, Yes)} and that the {\tt 'c'} mode 
is correct. \\
That is for \ \verb#gs = fst $ gxBasis xs,  I = Ideal(gs)#, 
\\  
the map \ \ {\tt moduloBasis "cg" gs y -> (r,q)} \ \ has a canonic
remainder in its result: \\ 
{\tt y-z $\in$ Ideal(xs) $\Longleftrightarrow$ r(y) == r(z)}.
\medskip

{\tt (WithSyzygyGens, Yes)}
\\
means that \ {\tt syzygyGens} {\it anyMode} \ \ 
         is a correct algorithm to find the linear relation generators.
\medskip

{\tt (IsGxRing, Yes)}
\\
means \ {\tt (ModuloBasisDetaching, Yes)} \ and that \\ 
{\tt gxBasis, \ moduloBasis "cg", \ syzygyGens}  \ \
satisfy the laws of a gx-ring (see Section~\ref{sec-gx}). \\
In particular, it holds {\tt (WithSyzygyGens, Yes)} and the 
transformation matrix and quotient vector are correctly evaluated. 





\section{ EuclideanRing }
% -----------------------
\label{sec-euc} 


This category is exported from {\tt RingModule}, implemented in 
\verb#Ring*# modules, \\
{\tt EucRingTerm} --- in the module {\tt Categs}.

\footnotesize
\begin{verbatim}
  class (GCDRing a, LinSolvRing a) => EuclideanRing a  
    where
    baseEucRing :: a -> Domains1 a -> (Domains1 a, EucRingTerm a)
    eucNorm     :: a -> Z
    divRem      :: Char -> a -> a -> (a, a)        -- division with remainder

  data EucRingTerm a = EucRingTerm {eucRingProps :: Properties_EucRing
                                    -- only this, so far
                                   } deriving (Show)
  type Properties_EucRing = [(Property_EucRing, PropValue)]
  data Property_EucRing   = Euclidean | DivRemCan | DivRemMin 
                            deriving (Eq, Ord, Enum, Show)
\end{verbatim}
\normalsize

In  \ {\tt divRem mode x y -> (quotient, remainder)}
\\        
{\tt mode = 'm'} \ means the minimal-norm remainder,

  {\tt 'c'} \ means that for each \ {\tt b /= 0 \ \ x -> divRem 'c' x b} \ \ 
  is a canonical map for the residues modulo {\tt b}.

The correctness of the operations \ {\tt eucNorm, divRem} \ depends on 
the property values for \ {\tt Euclidean, DivRemCan, DivRemMin}.
\medskip

{\tt (Euclidean, Yes)} 
\\ 
means that \ {\tt eucNorm, (divRem {\it anyMode})} \ 
are correct algorithms on R for the Euclidean ring structure. \\
That is, denoting \ 
{\tt e = eucNorm : \verb#R\{0}# -> NonNegativeInteger}, \ \ 
the following holds for any \ {\tt b} $\in$ \verb#R\{0}#

  (1) \ {\tt e(a*b) $\geq$ e(a)} \ for any \ {\tt a $\neq 0$},

  (2) \ for any \ {\tt a} $\in$ R \ and \ {\tt (q,r) =} \verb#divRem _ a b# \\
      it holds \ {\tt a = q*b + r}, \ 
      where either \ {\tt r = 0} \ or \ {\tt e(r) < e(b)}.
\medskip

{\tt DivRemCan, DivRemMin} \\ 
are the correctness conditions for the {\tt divRem} modes of 
{\tt 'c'} and {\tt 'm'} respectively.
               
{\bf Examples:} \ In DoCon, 

  {\tt divRem 'm' (-2) 5 = (0, -2), \ \ divRem 'c' (-2) 5 = (-1, 3)};

  {\tt divRem} on $K[x]$ for a field $K$ does not depend on {\tt mode}.
\medskip

The condition for canonical remainder for \ {\tt mode = 'c'} \ 
is easy to satisfy for simple cases and somewhat harder in 
esoteric ones. In particular, the simple cases are presented by the 
rings \ \ $\Z$, \ \ $k[x]$ with a field $k$, \ \ 
quadratic integer ring \ $\Z[root(d)]$ with negative $d$.
\\
$\Z[root(d)]$ \ with positive $d$ presents a more complex case.




\newpage
\subsection{ Several usable functions for Euclidean ring }
% --------------------------------------------------------
\label{sec-euc.fn} 

\footnotesize
\begin{verbatim}
  isEucRing, isCEucRing :: EucRingTerm a -> PropValue

  isEucRing  = lookupProp Euclidean . eucRingProps 
  isCEucRing = lookupProp DivRemCan . eucRingProps 

  quotEuc, remEuc :: EuclideanRing a => Char -> a -> a -> a
  quotEuc mode x = fst . divRem mode x 
  remEuc  mode x = snd . divRem mode x 

  eucGCDE :: EuclideanRing a => [a] -> (a, [a])          -- extended GCD
    -- 
    -- xs -> (d, qs),    d = gcd[x1...xn] =  q1*x1 +...+ qn*xn
    --
    -- - qi  are any elements satisfying this equation.
                  
  eucGCDE xs = case  xs  of         -- this is also an example of programming:

    []  -> error "eucGCDE []\n"
    x:_ ->
      let
        (zr,un)   = (zeroS x, unity x)
        gc (x:xs) =                      -- reduce to  gcd2
          case  (xs, x==zr)
          of
            ([]  , _   ) -> (x, [un])
            (_   , True) -> (d, zr:qs)  where  (d, qs) = gc xs  
            (y:ys, _   ) -> let  (d, u, v) = gcd2 (un, zr, x) (zr, un, y)
                            in
                            if  null ys  then  (d, [u,v])
                            else               (d', (u*q):(v*q):qs)
                                                 where
                                                 (d', q:qs) = gc (d:ys)
        gcd2 (u1, u2, u3) (v1, v2, v3) =
                  -- It starts with  (un, zr, x) (zr, un, y),  x /= zr.
                  -- Euclidean GCD is applied to u3, v3, operations on
                  -- u1, u2, v1, v2 perform parallelwise to ones of u3, v3
                  --
               if  v3==zr  then  (u3, u1, u2)
               else              gcd2 (v1, v2, v3) (u1-q*v1, u2-q*v2, r)
                                                  where
                                                  (q,r) = divRem '_' u3 v3
      in  gc xs
\end{verbatim}
\normalsize



\newpage
\section{ Field }
% ---------------
\label{sec-fld}


\footnotesize
\begin{verbatim}
  class (EuclideanRing a, FactorizationRing a) => Field a   -- needs (IsField, Yes)
  class Field a => RealField a                              -- needs (IsRealField, Yes)
  class (RealField a, OrderedRing a) => OrderedField a
\end{verbatim}
\normalsize

A field R is implicit: it does not declare any extra operations. \\
R should be an EuclideanRing and satisfy the property of a field: 
\begin{center}
    \verb#(inv_m x)# {\tt == Nothing} \ $\Leftrightarrow$ \ {\tt x == 0}
\end{center}
This corresponds to the attribute  (IsField, Yes)  in the data \
{\tt subringProps rR}.





\section{ Ideal }
% ---------------
\label{sec-il}  


\subsection{ Preface }
% --------------------
\label{sec-il.p} 

An ideal in {\tt DoCon} is {\it not} given by a category instance 
(see Sections \ref{sec-prp.skco.in}, \ref{sec-prp.skco.st}).
Unlike with {\tt Ring}, {\tt DoCon} represents an ideal only as an 
explicit, regular data --- ideal term or, maybe, a bundle.

{\tt DoCon} can really compute only with the ideal  given  by  a  finite
generator list. \\
Setting an ideal means sometimes to set some additional  attributes,
like factorization or some property value.

The attributes of an ideal are used  intensively  by  the  functions 
related to the residue ring.
\medskip

\underbar{Ideal builders:} 
\\
apply the functions \ \ {\tt eucIdeal, gensToIdeal} \ \
to construct an ideal from generators,\\
from the short description.

For computing in \ $R/I$, \ the decription for \ $I$ \ can be prepared 
once by such function, and further, its attributes are  shared  by  the  
elements of $R/I$ \ --- see (Section~\ref{sec-prp.ske} BF).
\bigskip

\underbar{Ideal and its generators}
\\
Different generator lists may define the same ideal.
{\tt DoCon}  mostly operates with the generators,  but sometimes keeps  in 
mind the ideals.
For example, canonic reduction by generators  occurs  the  reduction
by the ideal, if the generators form a gx-basis 
(Sections \ref{sec-linr.t}, \ref{sec-gx}).
A notion of gx-ring ('gx')  exploited by {\tt DoCon} corresponds  to  the 
ring with the solvable ideal inclusion, a solvable residue ring.
\medskip

{\bf Summary:}

  {\tt DoCon} represents an ideal mostly as a data term {\tt iI}.

  The main in {\tt iI} is the generator list.

  {\tt DoCon} abilities depend greatly on what generator list is put in 
  the description {\tt iI} and what property values are put there.





\subsection{ Special ideal for Euclidean ring }
% ---------------------------------------------
\label{sec-il.e} 


These items are exported from {\tt RingModule}, implemented in the
\verb#Ring*# modules.

\begin{verbatim}
  data PIRChinIdeal a =
    PIRChinIdeal
      {pirCIBase      :: a,                 -- b:  Ideal = (b)
       pirCICover     :: [a],               -- bs: (b) = intersect[..]
       pirCIOrtIdemps :: [a],               -- es: idempotents
       pirCIFactz     :: Factorization a    -- ft = [(p1,m1)...(pw,mw)]
      }
    deriving (Show, Read)
\end{verbatim}
%
--- a special representation for a non-trivial ideal \ {\tt I = (b)} \ 
in a \ {\it principal ideal ring} R.

{\tt b} \ is a generator for {\tt I}. 
Other parts are optional --- can be set as {\tt []}.
But providing the factorization for {\tt b},  
or the {\it orthogonal idempotents} for the decomposition of {\tt I}
may enforce and optimize many operations on \ {\tt I, R/I}.
 
The requirements for the data \ {\tt iI :: PIRChinIdeal a} \ are
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt b} \ is neither zero nor invertible.

\item If {\tt bs == []} \ then \ {\tt es == []}

\item If {\tt bs /= []} \ then
  \\
  (1) \ {\tt (b) = idealIntersection [$ (b_j) \ | \ b_j \in bs $]}, 
  \\
  (2) \ $ (b_i) + (b_j) = (1) $ \ for any $i$ /= $j$ \ ---
                             which means reciprocally prime ideals.

\item If {\tt es /= []} \ then 
  \\
  {\tt es =} $[e_1, \ldots, e_w], \ \ e_i \in $ {\tt a} \ 
  are the Lagrange orthogonal idempotents: \\
      $ e_i \ modulo \ b_j $ \ is 1 for $i = j$ \ and 0 otherwise; \ 
      hence \ $ e_i^2 = e_i, \ \ e_1 + \ldots \ + e_w = 1 $

\item If  {\tt ft /= []} \ then
  \\
  {\tt a} \ is a factorial ring, \ \
  {\tt ft = [$(p_1,m_1), \ldots, (p_w,m_w)$]} \ is the factorization: \\
  {\tt b = product bs, \ \ $ b_i = p_i^{m_i}, \ \ i \in $ [1 .. w]} 
  \ \
  ($b_i$ and $p_i$ listed in the same order).
\end{itemize}
%
{\bf Example:} \ the ideal {\tt (24)} in {\tt Z} can be described as
\begin{verbatim}
   PIRChinIdeal {pirCIBase = 24,           pirCICover = [3,8],  
                 pirCIOrtIdemps = [16,9],  pirCIFactz = [(3,1),(2,3)]
                }
\end{verbatim}
The function
\begin{verbatim}
  eucIdeal :: (FactorizationRing a, EuclideanRing a) =>

       String -> a -> [a] -> [a] -> Factorization a -> PIRChinIdeal a
      -- mode    base cover  ids    factz
\end{verbatim}
sets an ideal in an Euclidean ring.
This is an easy way to build the ideal description from incomplete 
parts. The parts are listed as in the {\tt PIRChinIdeal} data fields.\\
Applying {\tt eucIdeal} completes the description.

{\bf Conditions.} \\
In the most complex case, it needs a c-Euclidean ring with the
factorization algorithm. In this case, it is presumed that the 
elements set in \ {\tt cover} \ are the canonical remainders modulo \
{\tt b}, and this function returns the orthogonal idempotents \ 
{\tt ids'} --- as the canonical remainders too 
(if {\tt mode} contains {\tt 'e'}).
\medskip

  {\tt mode = bMode++eMode++fMode} \ 
                               should be a substring of \ {\tt "bef"};

  {\tt 'b' <- mode} \ means to update the {\tt pirCICover} of the 
     ideal term, \ other case means to leave it as it is ;
  
  {\tt 'e', 'f'} \ correspond to the parts \ 
                                {\tt pirCIOrtIdemps, pirCIFactz}.
\medskip


{\bf Method} for {\tt eucIdeal} : \\
the main part is to obtain the Lagrange idempotents \ {\tt es} \
from \ {\tt bs = cover}. \\
It is done via applying {\tt eucGCDE} to decompose \ 
$ 1 = d_{j,k} + d_{k,j} \ \ldots $
\medskip

\underbar{Example:}
\begin{verbatim}
  eucIdeal "bef" (24::Z) [] [] [] =

  PIRChinIdeal {pirCIBase      = 24,      pirCICover = [3,8],  
                pirCIOrtIdemps = [16,9],  pirCIFactz = [(3,1),(2,3)]
               }
  ===
  eucIdeal "b" (24::Z) [] [16,9] [(3,1),(2,3)] 
\end{verbatim}
--- the latter description is cheaper to compute.

See the demonstration modules  \ \verb#T_*.hs# \  for the examples of 
computation in R/I.
\medskip

Further, the {\tt Functor} instance  
\begin{verbatim}
  instance Functor PIRChinIdeal
    where
    fmap f i = PIRChinIdeal {pirCIBase      = f a,
                             pirCICover     = map f cs,
                             pirCIOrtIdemps = map f ids,
                             pirCIFactz     = [(f p, e) | (p,e) <- ft]
                            }
    where 
    (a, cs, ids, ft) =
           (pirCIBase i, pirCICover i, pirCIOrtIdemps i, pirCIFactz i)
\end{verbatim}
enables to `map' between the ideals over different domains R, usually, 
between the isomorphic copies of R.





\subsection{ Generic ideal }
% --------------------------
\label{sec-il.g} 


{\tt data Ideal} \ is exported from {\tt Categs},  
its related items are exported from {\tt RingModule, Residue}, 
implemented in  \ \verb#Ring*.hs, IdealSyz_.hs#.

\footnotesize
\begin{verbatim}
  data Ideal a = Ideal {idealGens     :: Maybe [a],
                        idealProps    :: Properties_Ideal,
                        idealGenProps :: Properties_IdealGen,
                        idealConstrs  :: [Construction_Ideal a],
                        idealOpers    :: Operations_Ideal a
                       }
  type Properties_Ideal    = [(Property_Ideal   , PropValue)]
  type Properties_IdealGen = [(Property_IdealGen, PropValue)]
  data Property_Ideal      = IsMaxIdeal | Prime | Primary
                                                deriving (Eq, Ord, Enum, Show)
  data Property_IdealGen  = IsGxBasis  deriving (Eq, Ord, Enum, Show)
  type Operations_Ideal a = [(OpName_Ideal, Operation_Ideal a)]
  data OpName_Ideal       = IdealRank  deriving (Eq, Ord, Enum, Show)

  newtype Operation_Ideal a    = IdealRank' (InfUnn Z)  deriving (Eq, Show)
  newtype Construction_Ideal a = GenFactorizations [Factorization a]
                                             -- | Intersection of ideals ... ?
\end{verbatim}
\normalsize
%
This presents an ideal I is a ring R.
\bigskip

\underbar{{\tt idealGens :: Maybe [a]}} {\tt =}

  {\tt Just gs} \ --- means a finite list {\tt gs} of generators for I,

  {\tt Nothing} \ --- means ``could not provide such generators''.

\bigskip

\underbar{{\tt idealProps :: Properties}}\verb#_Ideal#

Here \ {\tt IsMaxIdeal, Prime, Primary} \    
have the usual meaning as in classic algebra \\
(\cite{La} Chapter 2).
\bigskip

\underbar{{\tt idealGenProps :: Properties}}\verb#_IdealGen#

Here {\tt (IsGxBasis, Yes)} is the condition for the canonic 
reduction by {\tt I}, and for the algorithmic operation correctness 
in {\tt R/I}. See the gx-basis notion in the 
Sections \ref{sec-gx}, \ref{sec-linr.t}.
\bigskip

\underbar{{\tt idealConstrs :: [Construction}}\verb#_Ideal a]#

So far, it may provide only \ {\tt GenFactorizations}, \ 
and only for the factorial ring.

In the data \ {\tt GenFactorizations fts} \ \
{\tt fts} is either {\tt []} or {\tt (map factor gens)}.
\\
Still \ {\tt factor} \ may return {\tt []} for some elements
--- if \ {\tt WithFactor /= Yes} \\ 
(see \ {\tt FactorizationRing.factor}).
\bigskip


\underbar{{\tt idealOpers :: Operations}}\verb#_Ideal a#

So far only one `operation' is available: 
the key of  {\tt IdealRank}  extracts \ {\tt IdealRank' r}, \ \ 
where  {\tt r}  may occur 

 {\tt Fin n} \ (finite rank) \ \ or \ {\tt Infinity} \ \ or \ {\tt UnknownV}.




\subsubsection{ Several usable functions for generic ideal }
\label{sec-il.g.fn} 

\footnotesize
\begin{verbatim}
  rankFromIdeal :: Ideal a -> InfUnn Z
  rankFromIdeal    iI      =  case  lookup IdealRank $ idealOpers iI
                              of
                                Just (IdealRank' v) -> v
                                _                   -> UnknownV

  isMaxIdeal, isPrimeIdeal, isPrimaryIdeal :: Ideal a -> PropValue
  isMaxIdeal = lookupProp IsMaxIdeal . idealProps 
  ...
  genFactorizationsFromIdeal :: Ideal a -> Maybe [Factorization a]
                                -- extract factorization list from the
                                -- first GenFactorizations construction

  zeroIdeal :: Properties_Ideal -> Subring a -> Ideal a
               -- givenProps
    -- Zero ideal in a non-zero base ring.
    -- givenProps  contains some hints for the ideal properties.

  unityIdeal :: a -> Subring a -> Ideal a     -- unity ideal in given base ring
              --unity             
                              -- this is also example of ideal setting:
  unityIdeal un _ = 
               Ideal {idealGens     = Just [un],          idealProps   = props,
                      idealGenProps = [(IsGxBasis,Yes)],  idealConstrs = [],
                      idealOpers    = operations
                     }
                where  operations = [(IdealRank, IdealRank' (Fin 1))]
                       props      = [(IsMaxIdeal,No), (Prime,No), (Primary,No)]
\end{verbatim}
\normalsize




\subsubsection{ Ideal bundle. Ideal from generators }
\label{sec-il.g.b} 

In mathematics, an ideal {\tt I} in a ring {\tt R} is also a subring
and a subgroup, and so on.
Therefore, to build an ideal {\tt I} and residue ring {\tt R/I}, 
{\tt DoCon} needs a bundle for the ideal, not only its term.
For example, the function \ {\tt gensToIdeal} \ takes \\
(a) a finite list of generators for {\tt I}, \ \
(b) a short ideal description, \\ 
(c) a bundle {\tt dR} for {\tt R}, \ \
(d) a current bundle {\tt dm} for {\tt I} 
\\
and returns the new bundle {\tt dm'} and ideal term.
%
\begin{verbatim}
  gensToIdeal :: LinSolvRing a => [a]                 ->   -- igens
                                  [Factorization a]   ->   -- fts
                                  Properties_IdealGen ->   -- bProps
                                  Properties_Ideal    ->   -- iProps
                                  Domains1 a          ->   -- dR
                                  Domains1 a          ->   -- dm

                                               (Domains1 a, Ideal a)
\end{verbatim}
It makes the description for an ideal {\tt I} from a finite 
generator list {\tt igens} in a base ring {\tt R} possessing the 
property {\tt (ModuloBasisDetaching, Yes)}.


{\tt dR} \ is a base domain filled up to {\tt LinSolvRingTerm}.

{\tt dm} \ is the current ideal bundle (usually empty) to be loaded 
        further with the ideal and, maybe, other terms.

{\tt iProps} \ is the sublist of the full property list.
\medskip

{\tt fts} \\
is ignored if \ it is given empty \ or \ 
{\tt Factorial /= Yes} \ in {\tt R} \ or \ 
{\tt (Prime, Yes)} is set for {\tt I}.

Otherwise, {\tt fts} contains the given factorizations for each basis 
element \\
(see {\tt FactorizationRing.factor}), each unknown 
factorization denoted by {\tt []}, \\
in this case {\tt igens} remains as it is given.
\medskip

{\bf Attention:} \\
if it is known that {\tt igens} is a gx-basis 
(See Sections \ref{sec-gx}, \ref{sec-linr.t}),
then better set this explicitly in \ {\tt bProps : \ (IsGxBasis, Yes)}. 
Otherwise, {\tt gensIdeal} it will still compute {\tt gxBasis} and 
set it in ideal in place of initial one.

For the most important ideal properties, such as \\
{\tt Prime, Primary, IsMaxIdeal}, \ it is better to set them 
explicitly in {\tt iProps}, \\
if the value is known. 

{\tt gensToIdeal} \ tries to make the property values more definite  
--- using also the properties of \ {\tt fts, R}. \ 
In particular, it completes the values according to the dependencies 
between \ {\tt Prime, Primary, IsMaxIdeal}.

But it does not apply the primality test.
\medskip



\underbar{Example.}

Build an ideal defined by a Gr\"obner basis {\tt gs} in \
{\tt R = E[$x_1, \ldots, x_n$]}, \\ 
{\tt E} an Euclidean ring:
%
\begin{verbatim}
   let { g = head gs;  dR = upLinSolvRing g Map.empty }
   in
   gensToIdeal gs [] [(IsGxBasis,Yes)] [] dR Map.empty     -- = (dI, iI)
\end{verbatim}
This forms the ideal bundle {\tt dI} starting from empty, \\
the ideal term {\tt iI} --- starting from {\tt gs}. 
  
{\tt (IsGxBasis, Yes)} is an important information on {\tt gs} --- 
expensive to derive automatically.

Suppose now that 
\begin{verbatim}
              E = Q = Fraction Z  (a field),   R = Q[x,y], 
              gs = [x^3 - 2, y^2 + 1].
\end{verbatim}
Then, {\tt R/I} is actually an extension of rational numbers {\tt Q} 
with \ $\sqrt[3]{2}$ \ and \ $i = \sqrt{-1}$.

It is very useful in this case to to point out in the arguments that  
{\tt I} \ is maximal:
\begin{verbatim}
  let ... in
        gensToIdeal gs [] [(IsGxBasis,Yes)] [(IsMaxIdeal,Yes)] dR Map.empty
\end{verbatim}
Then, {\tt DoCon} would derive very simply that {\tt R/I} is a field.

In this example, the {\tt IsMaxIdeal} value could be found from 
{\tt gs}, \ but at some extra cost.

For more examples see \ \verb#demotest/T_cubeext.hs, T_grbas2.hs#
\\
--- Cyclic Integer ring.




\newpage
\section{ Module over a ring }
% ----------------------------
\label{sec-mod}  

Its items are exported from {\tt RingModule}, implemented in  
{\tt Ring*.hs}, \\ 
{\tt Submodule, LinSolvModuleTerm} data --- in module {\tt Categs}.
\medskip

\underbar{Terminology with `generators' and `basis'}

In mathematics, the notion of linear generator set (`generators')
for a module over a ring specializes to the notions of a 
(a) basis of (sub)module, \ \ (b) basis of ideal.

The basis of a module is required to be {\it free} of linear relations, 
only then it is called a basis (\cite{La} Chapter III \S4).

But sometimes the algorithmic algebraists call a generator list a basis.

The word `basis' in {\tt DoCon} names \\
{\tt gxBasis, moduloBasis, moduloBasisM, gxBasisM, IsGxBasis}
\\
stands for `generator list'.




\subsection{ LeftModule }
% -----------------------
\label{sec-mod.l} 

\footnotesize
\begin{verbatim}
class (Ring r, AddGroup a) => LeftModule r a
  where
  cMul           :: r -> a -> a                        -- module multiplication
  baseLeftModule :: (r, a) -> Domains2 r a -> (Domains2 r a, Submodule r a)
                    -- sa
\end{verbatim}
\normalsize
This category has two parameters: 
a ring {\tt r} and additive group \ {\tt a}.

{\tt baseLeftModule} \ has a sample argument \ {\tt s :: (r, a)} \ \   
which contains the samples for {\tt r} and for \ {\tt a}.
For example, 

  \verb#baseLeftModule (0,0) _# \ \ \ 
           builds the module term for the module {\tt Z} over {\tt Z},

  \verb#baseLeftModule (0, Vec [3,1]) _# \\
     builds module term for the free module of vectors 
     (of range 2) over {\tt Z}.
\medskip

\underbar{Examples}

1. {\tt DoCon} puts \ {\tt Vector R, UPol R, Pol R, EPol R, RPol R}

   to be left modules over a ring {\tt R}.
\medskip

2. It also declares 
\begin{verbatim}
  instance Ring a => LeftModule a a where cMul = mul
                                          ...
\end{verbatim}
which means a ring is a module over itself.
\medskip

3. It also {\it had} to declare
\begin{verbatim}
  instance AddGroup a => LeftModule Z a where cMul n v = times v n
                                              ...
\end{verbatim}
--- ``additive group is a module over {\tt Integer}''.
But the current {\tt Haskell} language cannot resolve this instance 
overlap with the instances from (1).
We have to wait for an appropriate language extension 
(see Section~\ref{sec-lne}).

 


\subsection{ Submodule }
% ----------------------
\label{sec-mod.s} 

\footnotesize
\begin{verbatim}
  data Submodule r a = Submodule {moduleRank     :: InfUnn Z,
                                  moduleGens     :: Maybe [a],
                                  moduleProps    :: Properties_Submodule,
                                  moduleGenProps :: Properties_SubmoduleGens,
                                  moduleConstrs  :: [Construction_Submodule r a],
                                  moduleOpers    :: Operations_Submodule r a
                                 }
  type Properties_Submodule     = [(Property_Submodule, PropValue)]
  type Properties_SubmoduleGens = [(Property_SubmoduleGens, PropValue)]
  type Operations_Submodule r a = [(OpName_Submodule, Operation_Submodule r a)]
  data Property_Submodule       = 
                           IsFreeModule | IsPrimeSubmodule | IsPrimarySubmodule
                           | IsMaxSubmodule | HasZeroDivModule | IsGradedModule
                           deriving (Eq, Ord, Enum, Show)
             --
             -- these properties generalize, as usual, the ring (or ideal) ones

  data Property_SubmoduleGens = IsFreeModuleBasis | IsGxBasisM
                                                 deriving (Eq, Ord, Enum, Show)
  data OpName_Submodule           = GradingM deriving (Eq, Ord, Enum, Show)
  data Operation_Submodule r a    = GradingM' PPComp (a -> PPComp) (a -> [a])
  data Construction_Submodule r a = ConsModuleDUMMY  
\end{verbatim}
\normalsize
%
The {\tt Submodule} \ term is similar to the {\tt Ideal} term.\\
Only {\tt DoCon} does not have, so far, the residue by submodule.
\bigskip

\underbar{{\tt Property}}\verb#_Submodule# 
\\
generalizes the ideal properties. For example, \ (IsPrimeSubmodule, Yes) \ 
for a submodule $N$ of a module $M$ over $R$ means: 
for any  \ $a \in R$ \ the multiplication \ $(a*)$ on $M/N$ 
is either zero homomorphism or an injective one.  
See (\cite{La} Chapter VI \S5).
\bigskip

\underbar{{\tt IsFreeModuleBasis}} \ from \ \verb#Property_SubmoduleGens# 

means that the generators {\tt gs} are linearly independent over a ring 
$R$. In this case  $M$  is isomorphic to \ \ 
$R \oplus \ldots \ \oplus R$ \ \ 
--- direct sum of a finite set of copies of $R$.



\newpage
\subsection{ Syzygy solvable module }
% -----------------------------------
\label{sec-mod.ls} 

\footnotesize
\begin{verbatim}
  class (LinSolvRing r, LeftModule r a) => LinSolvLModule r a
    where
    baseLinSolvLModule :: (r,a) -> Domains2 r a -> (Domains2 r a, LinSolvModuleTerm r a)
                                   --
                                   -- all these operations have sample argument
    canAssocM    :: r -> a -> a
    canInvM      :: r -> a -> r
    gxBasisM     :: r -> [a] -> ([a], [[r]])
    moduloBasisM :: r -> String -> [a] -> a -> (a, [r])
    syzygyGensM  :: r -> String -> [a] -> [[r]]
\end{verbatim}
\normalsize

{\bf Examples.}

{\tt DoCon} declares
\footnotesize
\begin{verbatim}
  instance EuclideanRing a => LinSolvLModule a (Vector a) where...
  instance EuclideanRing a => LinSolvLModule (Pol a) (Vector (Pol a)) where ...
\end{verbatim}
\normalsize
The former defines the solvable submodule structure for the free 
module \ \ $R \oplus R \oplus \ldots \ \oplus R$ \ \ over an Euclidean 
ring $R$. 
It is done via the Gauss method for a linear system over an 
Euclidean ring.
The latter instance uses the  {\tt EPol}  representation for  
{\tt Vector} over {\tt Polynomial} and the Gr\"obner basis for 
e-polynomials. See \cite{MoM}.

{\tt LinSolvLModule} category is very useful for dealing with the 
syzygies (linear relations) of polynomials --- see the examples in
\ \verb#demotest/T_grbas2.hs#.




\subsection{ Syzygy solvable module term }
% ----------------------------------------
\label{sec-mod.lsm} 

\footnotesize
\begin{verbatim}
  data LinSolvModuleTerm r a =
       LinSolvModuleTerm {linSolvModuleProps :: Properties_LinSolvModule
                          -- this is all, so far
                         } deriving (Show)

  type Properties_LinSolvModule = [(Property_LinSolvModule, PropValue)]
  data Property_LinSolvModule =
       IsCanAssocModule | ModuloBasisDetaching_M | ModuloBasisCanonic_M
       | WithSyzygyGens_M | IsGxModule     deriving (Eq, Ord, Enum, Show)
\end{verbatim}
\normalsize
%
{\tt (IsCanAssocModule, Yes)} \ means that

  (1) the ring is commutative,

  (2) \verb#canAssocM _ v# \ \ is a unique vector chosen in the set 

                 $ \{c*v \ : \ c \ \mbox{an invertible factor} \} $,

  (3) \verb#canInvM _ v# \ \ is the corresponding factor.
\medskip

Other properties generalize a ring (ideal) ones.


\newpage
\underbar{Auxiliary functions for {\tt Submodule}}

\footnotesize
\begin{verbatim}
  isGxModule:: LinSolvModuleTerm r a -> PropValue
  isGxModule   (LinSolvModuleTerm ps) = lookupProp IsGxModule ps

  isoModule :: (a -> b) -> (b -> a) -> Submodule r a -> Submodule r b
               -- f        fInv        mM          
    -- Isomorphic submodule.
    -- Given the map f and its inverse `maps' the Submodule description
    -- respectively.
\end{verbatim}
\normalsize




\newpage
\section{ Up-functions }
% ----------------------
\label{sec-up} 

A {\it base bundle} can be built from initial one (maybe, empty)  by
an up-function. 

Up-function is a composition of several base-operations.
See Section~\ref{sec-prp.skco.up}.
Here we list all of them. 

They are exported by the \ {\tt SetGroup, RingModule} \ modules \\
and have a format
\begin{center}
 {\tt up}{\it category} {\tt ::} {\it category} 
                             {\tt a => a -> Domains1 a -> Domains1 a}
\end{center}
{\it category} === 
             {\tt AddSemigroup | MulSemigroup | \ldots \ | Ring \ldots},

An up-function differs from base-functions in that it also forms all 
the implied domains for the given sample {\tt x} and puts them into 
new bundle.

\footnotesize
\begin{verbatim}
  type ADomDom a = a -> Domains1 a -> Domains1 a

  upAddSemigroup :: AddSemigroup a => ADomDom a 
  upAddSemigroup a = fst . baseAddSemigroup a . fst . baseSet a

  upAddGroup          :: (AddGroup          a) => ADomDom a  
  upMulSemigroup      :: (MulSemigroup      a) => ADomDom a  
  upMulGroup          :: (MulGroup          a) => ADomDom a  
  upRing              :: (Ring              a) => ADomDom a
  upGCDRing           :: (GCDRing           a) => ADomDom a
  upFactorizationRing :: (FactorizationRing a) => ADomDom a
  upLinSolvRing       :: (LinSolvRing       a) => ADomDom a
  upEucRing           :: (EuclideanRing     a) => ADomDom a
  upField             :: (Field             a) => ADomDom a

  upGCDLinSolvRing   :: (GCDRing a, LinSolvRing a) => ADomDom a
  upEucFactrRing     :: (EuclideanRing a, FactorizationRing a) => ADomDom a
  upFactrLinSolvRing :: (FactorizationRing a, LinSolvRing a) => ADomDom a

  upAddGroup a = fst . baseAddGroup a . upAddSemigroup a
\end{verbatim}
\normalsize
%
Other up-functions are defined similarly.
The `longest' one is
\begin{center}
{\tt upEucRing = fst . baseEucRing a . fst . baseLinSolvRing a . upGCDRing a}
\end{center}
And \ \ {\tt upField = upEucFactrRing} \ \   
            --- this is because {\tt Field} has not the term of its own.




\newpage
\section{ iso-functions }
% -----------------------
\label{sec-iso} 

They serve for isomorphic copying of domain descriptions and bundles.
\begin{center}
          {\tt isoOSet \ldots \ isoRing \ldots \ isoEucRingTerm \ldots}
\end{center}
are described each in the section on corresponding category.
But there are also such functions for the bundles:
\begin{center} 
            {\tt isoDomain1, isoDomains1, isoDomain22, isoDomains22}
\end{center}
They are exported by \ {\tt RingModule}.  
The idea is simple:  look through the bundle and convert each 
{\tt OSet} term by applying {\tt isoOSet}, \   
{\tt Subsemigroup} term --- by {\tt isoSemigroup}, and so on.

\footnotesize
\begin{verbatim}
 isoDomain1 :: (a -> b) -> (b -> a) -> Domain1 a -> Domain1 b
 isoDomain1    f           f'          dom       =  case  dom  of

              D1Set      t -> D1Set      (isoOSet            f f' t)
              D1Smg      t -> D1Smg      (isoSemigroup       f f' t)
              D1Group    t -> D1Group    (isoGroup           f f' t)
              D1Ring     t -> D1Ring     (isoRing            f f' t)
              D1GCDR     t -> D1GCDR     (isoGCDRingTerm     f f' t)
              D1FactrR   t -> D1FactrR   (isoFactrRingTerm   f f' t)
              D1LinSolvR t -> D1LinSolvR (isoLinSolvRingTerm f f' t)

  isoDomains1 :: (a -> b) -> (b -> a) -> Domains1 a -> Domains1 b
  isoDomains1    f           f'       =  mapFM (\_ dom -> isoDomain1 f f' dom)

  isoDomain22 :: (a -> b) -> (b -> a) -> Domain2 c a -> Domain2 c b
  isoDomain22    f           f'          dom         =  case  dom  of

                          D2Module   t -> D2Module   $ isoModule        f f' t
                          D2LinSolvM t -> D2LinSolvM $ isoLinSolvModule f f' t

  isoDomains22 :: (a -> b) -> (b -> a) -> Domains2 c a -> Domains2 c b
  isoDomains22    f           f'       = mapFM (\_ dom -> isoDomain22 f f' dom)
\end{verbatim}
\normalsize



\newpage
\section{ Domain Char }
% ---------------------
\label{sec-ch}  

In DoCon,  the only {\it ground} domains are \ {\tt Char} and 
{\tt Integer}.
For {\tt Char},  {\tt DoCon} provides only with the {\tt OrderedSet} instance.
We recommend the advanced user to inspect its implementation in \
\verb#auxil/Char_.hs#.




\section{ Domain Integer }
% ------------------------
\label{sec-z} 

{\tt DoCon} calls it \ \ {\tt type Z = Integer}. \ \ 
And \ {\tt Int} \ \ is ignored.
\medskip

The module {\tt Z} exports the instances for the domain {\tt Z}
--- in addition to the {\tt Haskell} Prelude ones:
\begin{verbatim}
  Set, OrderedSet, ..., OrderedAddGroup, 
  MulSemigroup, MulMonoid, 
  Ring, CommutativeRing, OrderedRing, GCDRing, FactorizationRing, 
  LinSolvRing, EuclideanRing.
\end{verbatim}



\subsection{ On GCDRing Z }
% -------------------------
\label{sec-z.gcd} 

The invertible elements in {\tt Z} are \ $\{1, -1\}$, 
\\  
{\tt canInv} \ yields 1 or -1, \ \ 
{\tt canAssoc} \ acts respectively to {\tt canInv}.



\subsection{ On LinSolvRing Z }
% -----------------------------
\label{sec-z.ls} 


{\tt gxBasis} \\
is presented by the extended Euclidean gcd algorithm: \\
{\tt xs -> (g, qs)}, \ \ 
g = gcd [ $x_1, \ldots, x_n$ ] = $ q_1*x_1 + \ldots \ + q_n*x_n $ \ldots,
\ \ {\tt $x_i$ <- xs, \ $q_i$ <- qs}
\medskip

{\tt moduloBasis} : \\
for \ {\tt xs = [d]}, \ it is done via \ {\tt y -> divRem 'c' y d}. \\
For a larger list, the composition with {\tt eucGCDE} applies.
\medskip

{\tt syzygyGens} \\
is presented by linear system solution over an Euclidean ring: 
\verb#solveLinear_euc#.




\subsection{ On EuclideanRing Z }
% -------------------------------
\label{sec-z.eu} 

Do not confuse \ \ {\tt divRem, quotEuc, remEuc} \ \ of {\tt DoCon} 
\\
with \ \ {\tt quotRem, div, mod} \ldots \ of the {\tt Haskell} prelude.

{\tt divRem 'c'} \ 
chooses a non-negative remainder for {\tt Z}, 
and this makes a canonical remainder map modulo ideal.



\subsection{ Bundle dZ }
% ----------------------
\label{sec-z.b} 

{\footnotesize
\begin{verbatim}
  dZ :: Domains1 Z
  dZ = upEucFactrRing 0 Map.empty  -- puts to dZ all the known domain terms for Z
\end{verbatim}
}
See Section~\ref{sec-up}.




\subsection{ Several useful functions for Integer }
% -------------------------------------------------
\label{sec-z.fn} 


\begin{center}  {\tt logInt :: (Ord a, OrderedRing a) => a -> a -> Z}
\end{center}
{\tt logInt b a} \ \ is the integer part of logarithm of \ {\tt a} \
by the base \ {\tt b}, \ \ {\tt a, b > 1}.
  
Where it is correct? At least, for \ {\tt Z, Fraction Z}.
  
Examples: \ \verb#logInt 3 29 = logInt (3:/2) (29:/8) = 3#,

  \verb#          logInt 29 3 = 0#.

{\bf Method:} \\ 
repeat division while the quotient is greater than {\tt b}.
\bigskip


\begin{verbatim} 
         orderModuloNatural :: Natural -> Integer -> Natural
                               -- r       a
\end{verbatim} 
Order of \ {\tt a} \ in \ 
                     \verb#Z/(r)  =  min [k > 0 | a^k = 1 (mod r)]#
\\
--- for \ {\tt r > 1, \ \ r} \ mutually prime with \ {\tt a}.
\bigskip


\begin{center}  {\tt totient :: Natural -> Natural}
\end{center} 
{\tt totient n} \ \ is the number of the {\it totitive} natural 
numbers for {\tt n}. 

A number {\tt k} is totitive for {\tt n} \ iff \ \ 
{\tt 0 < k < n} \ and \ {\tt gcd n k = 1}. 

{\bf Restriction:} \ {\tt n > 1}.

{\bf Method:} \ 
finds \ {\tt gcd n k} \ for {\tt k} in  {\tt [2 .. (n-1)]}.
\bigskip



{\footnotesize
\begin{verbatim} 
  rootOfNatural :: Natural -> Natural -> Natural -> (Natural, Natural)
                   -- e       x          b           r        r^e
\end{verbatim} 
}
Integer part of the \ {\tt e} -th degree root of a natural number \ 
{\tt x} \ \ for {\tt e > 0}.
\\
\verb#r = intPart (root_e x)#.\\
{\tt b} \ is a bound for the search: the root is searched in the 
segment {\tt [0, b]}.\\
By shoosing {\tt b}, the client can save some cost. 
And anyway, {\tt b = x} \ is correct.
\\
{\bf Caution:} \ 
setting \ \verb#b < root_e x# \ \ leads to incorrect result.

Cost estimation: \ $O( (log_2 b)^3*e^2*(log_2 e) )$.

{\bf Method:} \\ 
bisection for the function \verb#^e# --- integer version, 
this is much cheaper than dealing with rational approximations.
\bigskip


\begin{verbatim} 
  minRootOfNatural :: Natural -> Maybe (Natural, Natural)
                      -- n              e        r
\end{verbatim} 
This tests a natural \ {\tt n > 1} \ for being a power of some 
degree \ {\tt e > 1} \ of any \ {\tt r > 1}.  

If the needed \ {\tt e, r} \ exist, then it returns \ 
{\tt Just (e, r)} \ with the minimal possible {\tt e}.

Otherwise, it returns \ {\tt Nothing}.

{\bf Method:} \ 
for each \ \verb#e <- [2, log_2_n]#, \ apply \ 
{\tt rootOfNatural e n bound}, \linebreak 
where \ {\tt bound = (previous root) + 1}.


{\bf Cost estimation:} \ $O( (log \ n)^5*(log \ log \ n) )$.

Examples:  
\begin{verbatim} 
           2, 3 -> Nothing,       4  -> Just (2, 2),   
           16   -> Just (2, 4),   81 -> Just (3, 4).
\end{verbatim}           





\section{ Constructor List }
% --------------------------
\label{sec-l} 

Starting from a ground domain, we can build other domains with the
domain constructors.

For the List constructor \ {\tt []} \ {\tt DoCon} provides only the  \
{\tt Set} \ instance --- in addition to the {\tt Haskell} Prelude 
instances.

They are exported by {\tt DoCon} module \ {\tt DPrelude}.

{\tt baseSet (xs :: [a])} \ \ is valid only for a non-empty {\tt xs}.

We think that we do not need any algebraic instances for \ {\tt List} \ 
beyond \ {\tt Set}.

{\tt Set [a]} \ \ and \ \ Set (Vector a) \ \ are very different.\\
The set for {\tt [a]} contains all non-empty lists; \\
the vectors from the set for {\tt (Vector a)} are of the same size.
Thus
\begin{verbatim}
         osetCard $ snd $ baseSet "b"        Map.empty  = Infinity,  
         osetCard $ snd $ baseSet (Vec "ab") Map.empty  = Fin (256^2)
\end{verbatim}




\newpage
\section{ Permutation }
% ---------------------
\label{sec-pm}



\subsection{ Preface }
% --------------------
\label{sec-pm.p} 

For the permutation constructor
\begin{center}
            {\tt newtype Permutation = Pm [Z] deriving (Eq, Read)}
\end{center}
the module \ {\tt Permut} \ exports the instances up to \ 
{\tt MulGroup, Num} \ with  

  \verb#(*) =# \ permutation composition.

  {\tt (+) =} \ composing permutations on disjoint sets
             (like concatenation or map extension).

In \ \ {\tt Pm xs} \ \ {\tt xs = [$x_1,\ldots,x_n$]} \ \ 
should be non-empty and free of repetitions.

And the domain of the sample \ {\tt Pm xs} \ is \ {\tt S(n)}. \\
{\tt S(n)} is also viewed as the bijections on the set \ 
$ \{x_1,\ldots,x_n\} $.
\medskip

\underbar{Examples}
%
\footnotesize
\begin{verbatim}
  -- base set of  Pm [4,-1,2]  is  S(3):

  (osetCard s, osetList s) where  s = snd $ baseSet (Pm [4,-1,2]) Map.empty
  --> 
     (Fin 6,  Just [Pm [-1,2,4], Pm [-1,4,2], Pm [2,-1,4],
                    Pm [2,4,-1], Pm [4,-1,2], Pm [4,2,-1]]
     )
                                               -- other computations
  Pm [2,1] * Pm [2,1]           = Pm [1,2]
  inv $ Pm [2,1]                = Pm [2,1]
  Pm [2,1] + Pm [7,5,3]         = Pm [2,1,7,5,3]
  permutCycles $ Pm [2,1,7,5,3] = [[2,1], [7,3], [5]]
\end{verbatim}
\normalsize
See also \ \verb#demotest/T_permut.hs#.
\medskip

\underbar{Computation method}

The main tool is simply sorting of an integer pair list by the first
component or by the second.
For the large sets,  it, probably, worths to add the  implementation
based on the binary search trees.


\subsection{ Definitions }
% ------------------------
\label{sec-pm.d} 

\footnotesize
\begin{verbatim}
  newtype Permutation = Pm [Z]  deriving (Eq, Read)
  type    EPermut     = [(Z, Z)] 

  -- In  Pm xs   xs  should not contain repetitions.
  -- EPermut     is a Permutation whose list  xs  is zipped with  xs
  --             sorted increasingly.

  toEPermut :: Permutation -> EPermut
  toEPermut    (Pm xs)     =  zip (sort xs) xs

  fromEPermut :: EPermut -> Permutation 
  fromEPermut = Pm . map snd

  permutRepr :: Permutation -> [Z]
  permutRepr    (Pm xs)     =  xs

  permutSign :: Permutation -> Char                 -- '+'|'-'
  permutSign =  snd . sortE compare . permutRepr

  instance Show Permutation
    where  
    showsPrec _ p =  ("(Pm "++) . shows (permutRepr p) . (')':)

  instance Ord Permutation  
    where
    compare p = lexListComp compare (permutRepr p) . permutRepr 

  applyPermut :: Ord a => [Z] -> [a] -> [a] 
  applyPermut             ks     xs  = map snd . sortBy (compBy fst) . zip ks
                                  --
                                  -- example:  [2,3,4,1] -> "abbc" -> "cabb"

  applyTransp :: (Z, Z) -> [a] -> [a]
    -- Transpose the elements No i and j in list.  head xs  has No 1.
    -- Required: 1 <= i <= j <= length xs.
    -- Example:
    -- let xs = "abcde" in (applyTransp (2,2) xs, applyTransp (2,4) xs)
    --                                             = ("abcde", "adcbe")

  applyTranspSeq :: (Ord a, Show a) => (a,a) -> [(a,b)] -> [(a,b)]
    --
    -- Transpose the entities of indices  i <= j  in the sequence.
    -- A sequence is a list of pairs  (k,x)  ordered increasingly by
    -- the index  k <- `a'.  Skipped index means ``zero'' component.
    -- Example:
    -- for  ps = [(2,'2'),  (4,'4'),  (6,'6'),  (8,'8')]
    --
    -- applyTranspSeq (4,4) ps == applyTranspSeq (3,7) ps == ps,
    -- map (flip applyTranspSeq ps) [(4,8),(4,7),(4,9)] ps
    --        ==
    --        [(2,'2'),   (4,'8'),    (6,'6'),          (8,'4')]
    --        [(2,'2'),               (6,'6'), (7,'4'), (8,'8')]
    --        [(2,'2'),               (6,'6'),          (8,'8'), (9,'4')]


  transpsOfNeighb :: [a] -> [[a]]
    -- Transpositions of neighbour elements in xs = [x1..xn]  presents 
    -- certain small generator list for S(n).
    -- For  xs = [x],  the result is put [[x]].
    -- For  Ord a,  x1 < x2 .. < xn,  the result really represents the 
    -- transposition of neighbours.
    -- Otherwise, it still gives the generator list of cardinality n-1
    -- (for n > 1).

  transpsOfNeighb [x] = [[x]]
  transpsOfNeighb xs  = nbts xs
                          where
                          nbts [_]      = []
                          nbts (x:y:xs) = (y:x:xs):(map (x:) $ nbts (y:xs))

  nextPermut :: [Z] -> Maybe [Z]  -- next permutation in lexicographic order
 
  --------------------------------------------------------------------
  instance Set Permutation 
    where
    baseSet p dm =  ...
    compare_m p  = Just . compare p 

                                   -- on input, permutation looks like a list
    fromExpr (Pm xs) e = case  fromExpr xs e  of

      ([ys],"") -> ([Pm ys], "")
      _         -> ( [], "(fromExpr "++(shows (Pm xs) " ")++(showsExpr e ")\n") )

  invEPermut :: EPermut -> EPermut                        -- inversion
  invEPermut =  map (\ (x,y) -> (y,x)) . sortBy (compBy snd)

  addEPermut :: EPermut -> EPermut -> EPermut 
                                      -- compose permutations on disjoint sets
  addEPermut p = mergeBy (compBy fst) p

  --------------------------------------------------------------------
  instance MulSemigroup Permutation
    where
    baseMulSemigroup = ...
    unity_m          = Just . Pm . sort . permutRepr
    inv_m            = Just . fromEPermut . invEPermut . toEPermut

         -- mul p q = p*q  <--> \x-> p(q(x)   Required:  Set(p)=Set(q)
         --
    mul p q = Pm $ map fst $ sortBy (compBy snd) $ zip (permutRepr p) $ permutRepr r
                                                         where  
                                                         Just r = inv_m q  
  instance MulMonoid Permutation
  instance MulGroup Permutation  where  baseMulGroup p dm = ...

  instance Num Permutation
    where
    (*) = mul

    -- (+) means composing permutations on disjoint sets
    --
    p+q = fromEPermut $ addEPermut (toEPermut p) (toEPermut q)
  --------------------------------------------------------------------
  ePermutCycles :: EPermut -> [EPermut]
  
    Decomposes  s  to cyclic permutations  [c(1) .. c(r)] :  
    s = c(1) + ... + c(r),  length c(1) >= .. >= length c(r).

  permutECycles :: Permutation -> [EPermut]
  permutECycles = ePermutCycles . toEPermut

  permutCycles :: Permutation -> [[Z]]
\end{verbatim}
\normalsize




\newpage
\section{ Constructor Vector }
% ----------------------------
\label{sec-vec}  


\subsection{ Preface }
% --------------------
\label{sec-vec.p} 

In DoCon, \ {\tt Vector} \ represents a direct product of domain \ 
$D \oplus \ldots \oplus D$ \ --- n- times.

In the data \ {\tt Vec xs \ \ xs} \ should be a non-empty list.

{\tt Vector a} \ \  differs radically from \ {\tt [a]} \ in that
\medskip

  {\it the base domain of {\tt (Vec xs)} is parameterized by the 
       length of \ {\tt xs}
  }
\medskip

--- see (Section~\ref{sec-prp.ske} DS).

The base set of a sample \ \ {\tt v = Vec xs \ :: Vector a} \ \
consists of all the vectors \ {\tt u} \ of size \ {\tt vecSize v} \  
with the components from the base set of a component of \\
{\tt v} \ ({\tt = sample v = vecHead v}).

So, the algebra of vectors refer to the vectors of the same length.

The items for {\tt Vector} are exported by the modules \\ 
{\tt VecMatr, RingModule, Pol} \\
and implemented in \ \verb#Categs_.hs, Vec*.hs, Ring*.hs, Pol2_#. \ \ 
The instances
\begin{verbatim}
  Show, Eq, Functor, Random, Dom, Set, OrderedSet, AddSemigroup ...
  OrderedAddGroup, MulSemigroup ... MulGroup ... OrderedRing
\end{verbatim}
are exported from \ {\tt VecMatr} \ and are defined in an evident 
way: the operations perform component-wise.

Concerning  \ \ {\tt instance Random a => Random (Vector a) \ldots}, \\
see Section~\ref{sec-rnd}.

Further, the module \ {\tt RingModule} \ defines

\begin{verbatim}
  instance Ring a          => LeftModule     a (Vector a) where ...
  instance EuclideanRing a => LinSolvLModule a (Vector a) where ...
\end{verbatim}
% 
The line with \ {\tt LeftModule} \ has usual classic meaning.

And \ {\tt LinSolvLModule} \ operations in this case are defined via 
the Gauss reduction to the staircase form over an Euclidean ring.

The module \ \verb#Pol2_# \ also defines
\footnotesize
\begin{verbatim}
  instance EuclideanRing a => LinSolvLModule (UPol a) (Vector (UPol a)) where ...
  instance EuclideanRing a => LinSolvLModule (Pol  a) (Vector (Pol  a)) where ...
\end{verbatim}
\normalsize
Here the {\tt LinSolvLModule} operations are defined via the Gr\"obner
basis technique for a free module over \ {\tt a[x$_1$,\ldots,x$_n$]} \ 
(see \cite{MoM}).

The instance \ \ {\tt \ldots \ => LinSolvLModule (Pol a) (Vector (Pol a)}
\\  
overlaps with  \ \ {\tt \ldots \ LinSolvLModule b (Vector b)}.

With this respect, {\tt DoCon} relies on that {\tt Haskell} chooses for the
domains from the instance intersection the instance for the more 
special type expression.  And here the type expression {\tt (Pol a)}
is more special.

This all makes a free module {\tt (Vector R)} over an Euclidean ring
{\tt R} a module with solvable submodules;

the same is with \ \ {\tt Vector R[x$_1$,\ldots,x$_n$]} \ \  
over \ {\tt R[x$_1$,\ldots,x$_n$]}.



\subsection{ Usable functions for Vector }
% ----------------------------------------
\label{sec-vec.f} 

\footnotesize
\begin{verbatim}
  newtype Vector a = Vec [a]  deriving (Eq)     -- non-empty list boxed in Vec
  vecRepr (Vec l) = l                         -- extract representation 

  vecSize :: Vector a -> Z
  vecSize =  genericLength . vecRepr

  vecHead :: Vector a -> a 
  vecHead    v        =  case vecRepr v of x:_ -> x  
                                           _   -> error "vecHead v:  empty v \n"
  vecTail :: Vector a -> [a] 
  vecTail    v        =  case vecRepr v of _:xs -> xs
                                           _    -> error "vecTail v:  empty v\n"
  scalProduct :: CommutativeRing a => [a] -> [a] -> a
  scalProduct                         xs     ys  = 

    case (xs ++ ys) 
    of
    x: _ -> sum1 ((zeroS x) : (zipWith (*) xs ys))
    _    -> error ("\nscalProduct [] []:   " ++
                   "at least one of the lists must be non-empty.\n"
                  )

  constVec :: Vector a -> b -> Vector b
  constVec    v           b =  fmap (const b) v

  allMaybesVec :: [Maybe a] -> Maybe (Vector a)
  allMaybesVec              =  fmap Vec . allMaybes
\end{verbatim}
\normalsize



\subsection{ Instances }
% ----------------------
\label{sec-vec.i} 

\begin{verbatim}
  instance Functor Vector  where  fmap f = Vec . map f . vecRepr
\end{verbatim}
Here \ {\tt Functor} \ is an {\tt Haskell} Prelude constructor class.
   
For \ {\tt Vector}, \ this instance enables the programmer to `map' 
a function similarly as to the list: \ \ {\tt map f (Vec xs)} \ \
means applying {\tt f} component-wise.
%
\begin{verbatim}
  instance Dom Vector
    where
    sample = vecHead
    dom _  = error "dom (Vec..):  dom  not defined for Vector\n"
\end{verbatim}
Further instances for {\tt Vector} are listed and explained earlier, 
in Section~\ref{sec-vec.p}.

{\bf Example:} \\ 
\verb#(v+v, v*v, fmap neg v)  where  v = Vec [1, 2, 3::Z]   =#
\medskip

        {\tt (Vec [2,4,6], Vec [1,4,9], Vec [-1,-2,-3])}





\section{ Generating random values }
% ----------------------------------
\label{sec-rnd}  

For this, {\tt DoCon} exploits the operation \ {\tt randomR} \ of the 
standard class {\tt Random}.

{\bf Example:} 

\footnotesize
\begin{verbatim}
  instance Random a => Random (Vector a)
    where
                -- put a random vector `between vl and vh' to have random
                -- components `between' l(i) and h(i)  for each  i
                --
    randomR (vl,vh) g = (Vec $ reverse xs, g')
       where
       (xs,g') = foldl rnd ([],g) $ zip (vecRepr vl) (vecRepr vh)

       rnd (xs,g) (l,h) = (x:xs, g')  where  (x,g') = randomR (l,h) g
\end{verbatim}
\normalsize
%
{\tt randomR (l,h) g} \ \ returns a random value between \ {\tt l} \ 
and \ {\tt h} \ and a new state \\ 
{\tt g' :: StdGen}.

Repeating this operation yields a random sequence.

{\tt StdGen} \ \ is an abstract type from the standard {\tt Haskell} 
library {\tt Random}.

The initial state can also be obtained standardly,  for example,  by
\begin{center}
           {\tt mkStdGen n :: StdGen}, \ \ with any \ {\tt n :: Int}.
\end{center}
See also the \ \ {\tt Random UPol, \ Random Pol} \ \ instances.
\medskip

\underbar{Remark}

What does this mean \ `between l and h' \ for \ l, h \ 
from some non-trivial, non-ordered domain?
For example, \ l, h \ may be from \ {\tt Z/(4)}, \ 
or polynomials from {\tt Z[x]}, or such.

The answer is that in \ \ {\tt randomR (l, h), \ \ l, h} \ \  
of some domain R, \ \ {\tt (l, h)} \ denotes only some subset in  R,
this subset is defined individually, by corresponding definition of
opeartion \ {\tt randomR} \ for the particular constructor.

This definition may not depend on the ordering on R.

For example, for \ \ 
  \verb#(l,h) = (-3*x^2 + 1, 3*x^2 + 4)# \ $\in$ \ {\tt (Z[x], Z[x])},

{\tt DoCon} puts that ``between {\tt l} and {\tt h}'' are the polynomials \ 
\verb#a*x^2 + b#, \ \ where
\\
{\tt a <- [-3..3], \ b <- [1..4]}.
\medskip

\underbar{Caution}
\\
{\tt DoCon} also puts 
\begin{center}   {\tt randomR (l, h) == randomR (h, l)} 
\end{center}
for certain good reason.
So that for a random value `between' {\tt l} and {\tt h},  
the `direction' is immaterial.

But we failed so far to agree this convention with the {\tt Haskell} 
standard.
As soon as any practical problems arise from  this  for  the  users,
{\tt DoCon} can introduce its own category \ {\tt DRandom}, 
and define simply its instances, referring when needed, 
to the standard {\tt Random}.
\bigskip

\underbar{Constructors supplied with {\tt Random} instance}
\\
{\tt Z, Bool, Char} \ \ have the standard {\tt Haskell} instances 
of {\tt Random}.

DoCon supplies with the instances of {\tt Random} the constructors
\begin{center}
              {\tt Vector, UPol, Pol, ResidueE, ResidueE, ResidueG}.
\end{center}
            




\section{ Matrix }
% ----------------
\label{sec-mt}  


\subsection{ Preface }
% --------------------
\label{sec-mt.p} 

A matrix is represented by the constructors 
\begin{center}
                {\tt Matrix} \ and \ {\tt SquareMatrix}.
\end{center}

Similarly as for {\tt Vector}, \ \ 
  {\tt mt = Mt rows aD \ :: Matrix a}, \ \ {\tt SqMt rows aD}
\\
should contain a non-empty list {\tt rows} of non-empty lists of 
the same length.

{\tt mt} \ has the base set of all the matrices \ {\tt n by m} \ 
over {\tt aD}, \\
where \ {\tt n = matrHeight mt, \ m = matrWidth mt}, \\
{\tt aD} \ is the base domain of a matrix entity {\tt (sample mt)}.

The base set for {\tt SquareMatrix} is parameterized by one parameter \\
{\tt n = sqMatrSize mt}.

But unlike with {\tt Vector}, the constructors \ 
{\tt Matrix, SquareMatrix} \ have the bundle field --- 
see (Section~\ref{sec-prp.ske} BF).
\medskip

{\bf Example.} \\
Form a matrix \ {\tt m} \ 2 by 2 over {\tt Z[x]} and find its cube: 
power:
\begin{verbatim}
          let  x1 = cToUPol "x" dZ 1    -- unity of Z[x]
               dX = upGCDRing x1 Map.empty
               m' = mapmap (smParse x1) [["x", "x + 2"    ],
                                         ["1", "x^2 - 2*x"] ]
               m  = Mt m' dX 
          in   m^3
\end{verbatim}
The instances \ {\tt Set \ldots \ AddGroup} \ for \ 
{\tt Matrix, SquareMatrix} \ are similar to the {\tt Vector} ones 
--- operations defined component-wise.
%
\begin{verbatim}
  instance CommutativeRing a => Num (Matrix a)       ...
  instance CommutativeRing a => Num (SquareMatrix a) ...
\end{verbatim}
define the operations \verb#(+), (*).  (*)# is the matrix multiplication.

For {\tt SquareMatrix}, \ \verb#(*)# satisfies the semigroup law.  
So, {\tt DoCon} adds
\begin{verbatim}
  CommutativeRing a => MulSemigroup (SquareMatrix a) ...
  CommutativeRing a => Ring         (SquareMatrix a) ...
                                        -- non-commutative for n > 1
\end{verbatim}
The \ {\tt Matrix} \ items are exported from {\tt VecMatr}, 
implemented in \ \verb#VecMatr, Ring0_, Matr*_# \ modules.





\subsection{ Usable items for matrices }
% --------------------------------------
\label{sec-mt.f} 

\footnotesize
\begin{verbatim}
  data Matrix a = Mt [[a]] (Domains1 a)

    -- Mt rows dm  should contain a Non-empty list `rows' of
    --             non-empty lists of the Same length.
 
  data SquareMatrix a = SqMt [[a]] (Domains1 a)

         -- in  SqMt rows dm
         -- (length xs)==(length rows) > 0  for each  xs  from  rows

  matrRows   (Mt   rs _) = rs
  sqMatrRows (SqMt rs _) = rs

  toSqMt :: Matrix a    -> SquareMatrix a
  toSqMt    (Mt rs dom) = SqMt rs dom
                                            -- CAUTION: rs should be square
  fromSqMt :: SquareMatrix a -> Matrix a
  fromSqMt    (SqMt rs d)    =  Mt rs d

  instance Eq a => Eq (Matrix a) where  s==t = (matrRows s)==(matrRows t)

  instance Dom Matrix  where  dom (Mt _ d) = d
                              sample       = matrHead

  -- Similar items are defined for  SquareMatrix.
  -- mt -names refer mostly to [[a]],  matr -names - to Matrix a.

  mtHeight, mtWidth :: [[a]] -> Z
  mtHeight = genericLength 

  mtWidth []    = error "mtWidth []\n"
  mtWidth (r:_) = genericLength r

  matrHeight, matrWidth :: Matrix a -> Z

  matrHeight = mtHeight . matrRows
  matrWidth  = mtWidth  . matrRows

  sqMatrSize :: SquareMatrix a -> Z
  sqMatrSize    (SqMt rs _)    =  genericLength rs

  mtHead :: [[a]] -> a 
  mtHead ((x:_):_) = x
  mtHead _         = error "mtHead m: empty m\n"

  matrHead = mtHead . matrRows

  matrTail :: Matrix a -> [[a]] 
  matrTail    m        =  case matrRows m of _:rs -> rs
                                             _    -> error "matrTail (Mt [] _)\n"
  sqMatrHead :: SquareMatrix a -> a 
  sqMatrHead    (SqMt rs d)    =  matrHead $ Mt rs d

  sqMatrTail :: SquareMatrix a -> [[a]] 
  sqMatrTail    (SqMt rs d)    =  matrTail $ Mt rs d

  transp :: Matrix a ->  Matrix a
  transp    (Mt rs d) =  Mt (transpose rs) d

  constMatr :: Matrix a -> a -> Matrix a
  constMatr    (Mt rs d)   a =  Mt (mapmap (const a) rs) d

  constSqMatr :: SquareMatrix a -> a -> SquareMatrix a
  constSqMatr    (SqMt rs d)       a =  SqMt (mapmap (const a) rs) d

  mapMt :: (a -> a) -> Matrix a  -> Matrix a
  mapMt    f           (Mt rs d) =  Mt (mapmap f rs) d 

  mapSqMt :: (a -> a) -> SquareMatrix a -> SquareMatrix a 
  mapSqMt    f           (SqMt rs d)    =  SqMt (mapmap f rs) d 

  rowMatrMul :: CommutativeRing a => [a] -> [[a]] -> [a]   -- multiply Row by Matrix
  isZeroMt :: AddSemigroup a => [[a]] -> Bool
  isZeroMt                      rows  =  case  rows  of

                (a:_):_ -> case  zero_m a  of  Just z -> all (all (==z)) rows
                                       _      -> False
                _       -> error "isZeroMt m:  empty m \n"

  scalarMt :: [a] -> b -> b -> [[b]]
             -- xs   c    z
     -- Make  scalar matrix  NxN  from the given elements  c, z
     -- and the list  xs  of length N,  xs  serves as a counter.
     -- c  is placed on the main diagonal,  z in the rest of matrix.
     -- COST = O(n^2)

  mainMtDiag :: [[a]] -> [a]    -- main matrix diagonal = [m(i,i) | i <- [1..]

  isDiagMt, isStaircaseMt, isLowTriangMt :: AddGroup a => [[a]] -> Bool
    --
    -- `is diagonal',  `is staircase', 
    -- `is lower-triangular' matrix  (j > i ==> m(i,j) = 0)
\end{verbatim}
\normalsize
%
{\bf Examples:} 
\begin{verbatim}
  [[1,0,2,1,0],
   [0,0,1,1,1],
   [0,0,0,2,0]]   is staircase, not diagonal, not lower-triangular.

  [[0,0,0,0],
   [2,1,0,0],
   [1,1,0,0]]     is lower-triangular, not staircase, not diagonal.
\end{verbatim}


\newpage
\begin{center} {\tt vandermondeMt :: MulMonoid a => [a] -> [[a]]}
\end{center}
presents a map to Vandermonde matrix:
\begin{verbatim}
            [a0,...,an] -> [[a0^n,     ... an^n    ]
                            [a0^(n-1), ... an^(n-1)]
                            ...
                            [1,        ... 1       ] 
                           ]
\end{verbatim}


\begin{center} {\tt resultantMt :: AddGroup a => [a] -> [a] -> [[a]]}
\end{center}
is for resultant matrix.
For the coefficient lists \ \ \verb#xs = x:_,  ys = y:_# \\ 
of dense polynomials \ \ \verb#f = x*t^n + ...,  g = y*t^m + ...#
\\ 
from {\tt a[t],  n = deg f, m = deg g,  n, m > 0, \ x, y} \ non-zero,
\\
build the resultant matrix {\tt M} over \ {\tt a} \ for \ 
{\tt f, g}. \ \ So, \ \ {\tt det M = resultant f g}.

{\bf Example:} 
\begin{verbatim}
   [a3,0,a1,0] -> [b2,b1,b0] -> [[a3, 0 , a1, 0 , 0 ]
                                 [0 , a3, 0 , a1, 0 ]
                                 [b2, b1, b0, 0 , 0 ]
                                 [0 , b2, b1, b0, 0 ]
                                 [0 , 0 , b2, b1, b0]]
\end{verbatim}
{\bf Method.} \\ 
For \ \ {\tt n = deg f = |xs|-1, \ \ m = deg g = |ys|-1}, \ \
zeroes prepend to \ {\tt xs, ys} \ to make \ {\tt xs0, ys0} \ 
both of length \ {\tt n+m}. \\
{\tt M = (xs0 shifted m times)++(ys0 shifted n times)}, \\
where shifting means the round left shift.


\newpage
\section{ Linear algebra }
% ------------------------
\label{sec-lin}

The corresponding items (further than ones of {\tt VecMatr} module)  
are exported from the module \ {\tt LinAlg}, \ \
implemented in \ \verb#Det_.hs, Stairc_.hs, Todiag_.hs, LinAlg.hs#.



\subsection{ Reduction of vector by subspace }
% --------------------------------------------
\label{sec-lin.v} 

\begin{verbatim}
  reduceVec_euc :: EuclideanRing a => Char -> [[a]] -> [a] -> ([a], [a])
                                      --mode  us       v       rem  qs
\end{verbatim}
A {\it staircase} vector list \ \ {\tt us = [u$_1$ \ldots u$_n$]} \ \ 
reduces the vector \ {\tt v} \ as possible, by subtracting from it 
certain linear combination of \ {\tt u$_i$}.

The quotient list \ \ {\tt qs = [q$_1$ \ldots q$_n$]} \ \   
is produced such that\\  
{\tt v = q$_1$*u$_1$ + \ldots + q$_n$*u$_n$ + rem}

`Reducing' means making zeroes in possibly many head positions. 
The tail of remainder is being reduced too.

{\bf Required:} \ \ {\tt v, u$_i$} \ \ should be of the same size.
\medskip

{\tt mode = 'c' | \ldots} \ \ is as in {\tt EuclideanRing.divRem}

The function \verb#reduceVec_euc# \ possesses the following 
properties.
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt isZero rem} \ $\Longleftrightarrow$ \ 
                 {\tt v} depends linearly on the vectors \ {\tt us}

\item For a c-Euclidean ring, \ \verb#(reduceVec_euc 'c' us)#
      \\ 
      is a canonical map by Submodule({\tt us}): \ \ 
   {\tt v==v' modulo us} \ $\Longleftrightarrow$ \ {\tt rem(v) == rem(v')}
\end{itemize}
\medskip

{\bf Method:} \ 
since \ {\tt us} \ is staircase, only one reduction pass has to perform.




\subsection{ Reduction to staircase matrix }
% ------------------------------------------
\label{sec-lin.s} 

\begin{verbatim}
  toStairMatr_euc ::  
  EuclideanRing a => String -> [[a]] -> [[a]] -> ([[a]], [[a]], Char)
                  -- mode      m        t0        s      t      sign
\end{verbatim}
Gauss method for bringing a matrix \ {\tt m} \ to the staircase form.  

For \ {\tt Field a}, \ it performs like usual Gauss method.

For not a field, it repeats the remainder division to obtain zeroes 
down in the current column \ldots \\
For an Euclidean ring, this leads, evidently, to a staircase matrix. 

The transformations are applied parallelwise to the matrix {\tt t}.

{\tt t} \ is the {\it transformation matrix}, \ {\tt height t = height m}.

If \ {\tt t0 = unityMatrix} \ then it holds \hspace{42mm} {\tt t*m = s}, 
\\  
where {\tt t} is the protocol matrix for the Gauss reductions of  
{\tt m}.

In generic case, it holds \hspace{65mm} {\tt u*m = s, \ u*t0 = t} 
\\
for the (invertible) protocol matrix \ {\tt u}.

{\tt t0 = []} \ \ is a synonym for the unity matrix of size 
{\tt (height m)}.

If \ {\tt m} is zero and {\tt t0 = []}, \ then \ {\tt (m, [])} \  
is returned.
\medskip

{\tt mode == "" | "u"}

  {\tt "u"} means that {\tt m} is already staircase, and the function 
should only try to reduce to zero the elements 
{\it super the main diagonal}. 
In this case, \ {\tt (s', t)} \ are returned, where
{\tt s'} has the reduced (as possible) upper part and is diagonal if  
{\tt m} is invertible. 
\medskip

{\tt sign == '+' | '-'} 

  is the accumulated signum of the result row permutation. \\
It holds: \ \ {\tt det(m)==det(s)} \ Or \ {\tt det(m)== -det(s)}; \ \
{\tt sign} \ shows one of these alternatives.

For example, the \ {\tt det} \ function makes use of this signum result.

For \ {\tt mode = "u", \ \ sign} \ is always {\tt '+'}.
\medskip

\underbar{The best case for performance} \ is \ a finite field {\tt a}.
\medskip

The implementation comments are in \verb#Stairc_.hs#.
\medskip

\underbar{Example} 
\\
Find the staircase form {\tt s} for a matrix {\tt m} over {\tt Z}  
and test \ {\tt t*m = s} \ for the corresponding transformation 
matrix.

\footnotesize
\begin{verbatim}
  let m = [[1,2,3,4,5,6],
           [5,0,6,7,1,0],
           [8,9,0,1,2,3]
          ]                               :: [[Z]]
      (s, t, _) = toStairMatr_euc "" m [] 
  in  
  (Mt t dZ)*(Mt m dZ) == (Mt s dZ)
\end{verbatim}
\normalsize



\subsection{ Determinant }
% ------------------------
\label{sec-lin.d} 

\begin{center} {\tt det :: CommutativeRing a => [[a]] -> a}
\end{center}
Determinant of a square matrix.

{\bf Attention:} \\ 
it expands {\tt det(M)} by the row 
(after moving ahead the rows which contain more of zeroes).
It costs \ $O(n!)$ \ in the worst case.
\medskip
   
For the Euclidean case, see the Gauss method: \ \ \verb#det_euc# 
\medskip

\begin{center} \verb#  det_euc :: EuclideanRing a => [[a]] -> a  #
\end{center}
Determinant of a square matrix over an Euclidean ring
computed via the Gauss reduction to the staircase form --- as in \ 
\verb#toStairMatr_euc#

The implementation comments are in \ \verb#Det_.hs#




\subsection{ Reduction to diagonal form }
% ---------------------------------------
\label{sec-lin.dg} 

\begin{verbatim}
  toDiagMatr_euc ::  
  EuclideanRing a => [[a]] -> [[a]] -> [[a]] -> ([[a]], [[a]], [[a]])
                     -- m     t0       u0        d      t      u
\end{verbatim}
Diagonal form \ {\tt d} \ of a matrix {\tt m} over an Euclidean ring 
obtained by the elementary transformations of the rows and columns.
  
{\tt t, u} \ \ 
are the unimodular protocol matrices for the the row
and column transformation respectively.                 
\medskip

{\tt t0 = []} \ or \ {\tt u0 = []} \ \   
is a shorthand for the unity matrix of appropriate size.

Let \ {\tt h = matrixHeight(m), \ wd = matrixWidth(m)}.
\\
If \ {\tt t0, u0} \ are the \ {\tt (h by h) and (wd by wd)} \ 
unity matrices, then
\begin{center}        {\tt t * m * transp(u) = d},
\end{center}
where the (lower) non-zero part of {\tt d} is square and diagonal.
\\
This means, it first applies the elementary transformation to  the 
rows. If {\tt m} is invertible over \ {\tt a}, we always achieve 
a diagonal form by this. If it is not achieved, similar 
transformations are applied to the columns.

Sometimes the returned \ {\tt u} \ occurs an unity matrix 
(that is the row transformations were sufficient).  
This holds when, for example, when {\tt m} is invertible.
\medskip
  
{\bf Remark:} \ 
the determinant can only change its sign under the above transformations.
\medskip

The implementation comments are in \ \verb#Todiag_.hs#.
\medskip

\underbar{Example:} \\
a program in the module \ \verb#demotest/T_diagmatr.hs# \ 
applies diagonalization to matrix over \ $K[x]$, \  
for a finite field $K$.




\newpage
\subsection{ Linear system solution }
% -----------------------------------
\label{sec-lin.sl} 

\begin{center} {\tt diagMatrKernel :: Ring a => [[a]] -> [[a]]}
\end{center}
returns the kernel basis \ {\tt ker} \ for a diagonal matrix {\tt D}
having no zero rows on diagonal.

In particular, it holds \ \ 
  {\tt height(D) <= width(D), \ \ D*(transpose ker) = zeroMatrix}

A domain \ {\tt a} \ should be a ring with unity and no zero 
divisors.\\
For the zero kernel the result is \ {\tt []}.
\bigskip


\begin{verbatim} 
  solveLinear_euc :: EuclideanRing a => [[a]] -> [a] -> ([a], [[a]])
                                        -- mM    v       p    ker
\end{verbatim}
is the general solution of linear system \ \ 
{\tt mM*(transp [x]) = (transp [v])}
\medskip
  
{\tt mM} \ is \ {\tt n by m} \ matrix, \ 
{\tt v} is a vector of size {\tt n}.

{\tt p} \ is a row for some partial solution, \ 
         it is set {\tt []} if there is no such solution.

{\tt ker} \ is the rows generating the \ {\tt a} -module of 
solutions for the homogeneous system \\ 
{\tt mM * transp(x) = zeroColumn}. 

For the zero kernel, \ {\tt ker = []}.
\bigskip


\underbar{Method}

{\tt m} converts to the diagonal form by the Gauss method for 
the rows and columns, the transformation matrices \ {\tt t, u} \
are accumulated. Then, the diagonal system is solved, and the goal 
solution restores via {\tt t, u}.

{\tt IsField} \ is tested first for the domain \ {\tt a} \ to 
separate easy case.

The implementation comments are in \verb#LinAlg.hs#.

{\bf Example:} \ see the \ \verb#solveLinear_euc# \ application in 
Section~\ref{sec-start.2}.
\bigskip
\bigskip
\bigskip




\begin{verbatim} 
  solveLinearTriangular :: CommutativeRing a => [[a]] -> [a] -> Maybe [a]
                                                -- mA    row
\end{verbatim}                                                
solves a system \ \ \ {\tt xRow x mA' = row} \ \ \ \ (1)
\\
for an upper-triangular matrix \ {\tt mA'}.

Size agreement:\\
{\tt mA} is restricted to the main minor {\tt mA'} of size \ 
{\tt |row| by |row|}, \ the remaining part is removed, the solution is 
for {\tt mA'}.

Hence, \ {\tt |xRow| = size mA' = |row|}.

If \ {\tt a} \ is free of zero divisors, \ {\tt mA'} is upper triangular 
and has not zeroes on the main diagonal, then this function satisfies the
property:

   if (1) has solution then {\tt solveLinearTriangular} returns \ 
   {\tt Just xs}, \ \ where {\tt xs} is this (unique) solution,

   otherwise it returns \ {\tt Nothing}.

{\bf Method:} \\
The usual method for solving a triangular system: find {\tt x(1)}, 
then find {\tt x(2)} via {\tt x(1)}, and so on.

{\bf Cost} = \ $O (|row|^2)$.






\subsection{ Other usable functions }
% -----------------------------------
\label{sec-lin.u} 


\footnotesize
\begin{verbatim}
  rank_euc :: EuclideanRing a => [[a]] -> Z
              -- rank of matrix via Gauss method - as in  toStairMatr_euc

  maxMinor :: Z -> Z -> [[a]] -> [[a]]       -- delete i-th row and j-th column
  maxMinor i j rows = delColumn j $ del_n_th i rows
\end{verbatim}
\normalsize
\medskip

\begin{center}
           \verb# inverseMatr_euc :: EuclideanRing a => [[a]] -> [[a]] #
\end{center}
is inversion of a square matrix \ {\tt mM} \ over an Euclidean ring. \\
If {\tt mM} is invertible, the inverse matrix {\tt iM} is returned, 
otherwise, returned is \ {\tt []}.

{\bf Method.} \\
The Gauss reduction to the staircase form {\tt (s,t)} is applied, \\
{\tt t} the transformation matrix, \ {\tt t0 = unityMatrix}. \\
This reduces the task to the inversion of a lower-triangular matrix. \\
The implementation comments are in \verb#Stairc_.hs#.
\bigskip

\begin{center}
\verb# linBasInList_euc :: EuclideanRing a => [[a]] -> ([Bool], [[a]]) #
\end{center}
For the matrix \ \ {\tt M = [v$_1$ \ldots \ v$_n$]}, \ \ mark some 
{\tt v$_i$} that constitute some maximal linearly independent subset 
{\tt M1} in {\tt M}.

In the returned list \ {\tt [b$_1$ \ldots \ b$_n$]}, \ \ 
{\tt b$_i$ = True} \ means \ {\tt v$_i \in $ M1}.

Also it is returned the staircase form for \ {\tt st} \ for {\tt M1}.

The implementation comments are in \verb#Stairc_.hs#.




\newpage
\section{ Pair }
% --------------
\label{sec-pair} 
    

\subsection{ Common approach }
% ----------------------------
\label{sec-pair.c} 

The instances for the pair constructor {\tt (,)} are exported by 
the module \ {\tt DPair} \ --- in addition to the standard 
{\tt Haskell} instances.

The instances \ 
     {\tt Set \ldots \ AddGroup \ldots \ MulGroup \ldots \ LinSolvRing}
\\
are defined for the domain \ {\tt (a,b)} \ under necessary condition 
instances for the types {\tt a, b}.

Naturally, the operations on the pairs are defined component-wise.

{\bf Example:}
\begin{verbatim}
  let  p = (5,6)  :: (Z,Z)
  in   (p*(3,3) - p,  p/p,  fst $ moduloBasis "" [(2,0),(0,3)] p)
  --> 
  ((10,12), (1,1), (1,0))
\end{verbatim}

The base set for the sample \ {\tt (x,y)} \ is the direct product \ \
{\tt xBS $\times$ yBS} \ \ of the base sets for {\tt x} and {\tt y}.

The instances for {\tt (a,b)} before \ {\tt LinSolvRing} \ are evident.
\\
The instance of \ \ {\tt LinSolvRing (a,b)} \ \
bases on that any ideal in {\tt (a,b)} is a direct sum of its 
projection ideals to \ {\tt a} and {\tt b}.

See Section~\ref{sec-gx.ds}, and maybe, {\tt DPair*.hs} programs.

Also {\tt DoCon} provides the following usable function for Pair:
\begin{verbatim}
  maybePair :: Maybe a -> Maybe b -> Maybe (a,b) 
  maybePair    (Just x)   (Just y) = Just (x,y) 
  maybePair    _          _        = Nothing
\end{verbatim}





\subsection{ Direct product of domain terms }
% -------------------------------------------
\label{sec-pair.d} 

Besides the mentioned above category instances, the module {\tt DPair} 
exports the the functions that given the domain descriptions for
{\tt D1, D2}, produce the description for {\tt D1 $\times$ D2}.

\footnotesize
\begin{verbatim}
  directProduct_set :: OSet a -> OSet b -> OSet (a,b)

  directProduct_semigroup :: Subsemigroup a -> Subsemigroup b -> Subsemigroup (a, b)
     --                      sH1               sH2
     -- directProduct_semigroup  yields the subsemigroup of the base
     -- semigroup H1 x H2 of (a,b). Basic operations are inherited from 
     -- H1, H2.  Hence H1, H2 should have the same sort  AddOrMul.
 
  directProduct_group ::
    (Set a, Set b) =>
    a -> OSet a -> Subgroup a -> b -> OSet b -> Subgroup b -> Subgroup (a,b)
  --un1  sS1       sG1           un2  sS2       sG2
  --
  -- the groups should be of the same sort AddOrMul,
  -- un1, un2  the unities of G1, G2 respectively.


  directProduct_ring :: 
  (Ring a, Ring b) => a -> Subring a -> b -> Subring b -> Subring (a,b)
                    --zA   rA           zB   rB  
                    -- zA, zB are the zeroes of A, B
\end{verbatim}
\normalsize





\section{ Fraction }
% ------------------
\label{sec-fr}  


\subsection{ Common approach }
% ----------------------------
\label{sec-fr.c} 

{\tt DoCon}  uses the \ \ {\tt Fraction} \ \ data instead of the 
{\tt Haskell}'s standard library's \ \ {\tt Ratio}.

The reasons for this are 
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Ratio} applies \ {\tt divMod, sign, (<)} \ to cancel 
  fractions, which is not universal, it is hardly applicable, 
  say to polynomials over a field.

\item {\tt Fraction} \ prefers to apply slightly different 
  algorithm for arithmetics. It cancels the intermediate 
  elements by \ {\tt gcd} as soon as possible.
\end{itemize}
%
Of course, whenever needed, the interaction between {\tt Fraction}
and {\tt Ratio}, is simple. \\
For example, to exploit any function \ \
{\tt g :: Ratio a -> Ratio a} \ \ for \ \ {\tt Fraction a} \\  
one can set
\begin{verbatim}
       f (n:/d) = let  h       = g (n%d) :: Ratio a   
                       (n',d') = (numerator h, denominator h)
                  in   n':/d'
\end{verbatim}



\underbar{More difference to {\tt Ratio}}

{\tt Ratio} of {\tt Haskell} Prelude is an {\it abstract type}. \\ 
For example, you cannot match against it: \ \ \verb#f (n%d) =# \ldots
\\
And for the constructor (:/) of DoCon, matching \ \ 
{\tt f (n:/d) = \ldots} \ \ is possible.

But this imposes additional care on the user of avoiding of 
non-canonical fractions. \\
For example, \ \ \verb#(4:/2)^2, (2:/(-3))^2# \ \ 
may cause an incorrect result.
\medskip

In DoCon, the {\tt Fraction} constructor applies correctly
only for the base ring with the attribute 
\begin{center}                            {\tt (WithGCD, Yes)}
\end{center}

This requires, in particular, {\tt (Factorial, Yes)} and a correct
{\tt gcD} algorithm, though the factorization algorithm is not 
necessary. See Section~\ref{sec-rg.pr}.

Hence, {\tt Fraction} yields a {\tt Field}.

The operations take and return the fractions \ $n:/d$ \ in their
canonical form. That is 
$$
d \neq 0, \ \ \ (n:/d) == (n':/d') \ \Longleftrightarrow \ (n,d)==(n',d')
$$
--- the algebraic equality is here the syntax one.

The mathematical correctness of such equality is achieved through
the gcd cancellation and cancellation by \ {\tt (canInv d)}.

Use \ \ {\tt canFr} \ \ for the cancellation in extra cases.

The difficulties may arise for the subtle domains where \ 
{\tt canInv} \ is hard to compute. 
\\
At least, {\tt Z} and {\tt Pol}-like constructors do not bring 
this difficulty.
\bigskip

\underbar{{\tt Rational} via \ {\tt Fraction Z}}

{\tt Haskell} Prelude puts \ \ \ \ \ \ \ \ \ \ {\tt Rational = Ratio Integer} 
\\
In DoCon, this is replaced with \ \ {\tt Fraction Z}.


{\bf Example.} \\ 
Form some polynomial {\tt f} from \ {\tt P = Z[x1,x2]} \ 
and compute \ \ \verb#f^2 + 1/f# \ \ in \ {\tt Fraction P}:
\begin{verbatim}
  let
    p1      = cToPol (lexPPO 2) ["x1","x2"] dZ 1  -- unity polynomial
    [x1,x2] = varPs 1 p1                       
    [p2,p3] = map (fromi p1) [2,3]                -- integers in P
    f       = x1^2*x2^3 + p2*x1 + p3*x2
  in  
  (f:/p1)^2 + (p1:/f)
\end{verbatim}
The instances of 
\begin{center} 
{\tt Set \ldots \ OrderedAddGroup \ldots \ MulMonoid, Ring \ldots \ OrderedField}
\end{center}
are defined according to usual notion of a fraction
(\cite{La} Chapter II \S3). \\
In particular, the instances of 
\begin{center} 
           {\tt LinSolvRing, GCDRing, FactorizationRing, EuclideanRing}
\end{center}
for {\tt Fraction} are valid but trivial, due to the trivial division 
relation in a field.

Further, any correct ordering instance for \ \verb#compare_m# \ on \ {\tt a} \
induces correct \ \verb#compare_m# \ on \ {\tt Fraction a} \  
(agreed with operations) --- see {\tt IsOrderedRing} in 
Section~\ref{sec-rg.pr} and theory in \cite{La}.
\bigskip


\underbar{{\tt Fraction Z}}

Special instances are defined for \ \ {\tt Fraction Z}, \ \
overlapping with the generic one. 

This is arranged so, because \ {\tt Fraction Z} \ has more 
definite domain attributes than the generic \ 
{\tt GCDRing a => Fraction a}.
\bigskip

The items for {\tt Fraction} are exported by the module {\tt Fraction}.




\subsection{ Main items for Fraction }
% ------------------------------------
\label{sec-fr.i} 

\footnotesize
\begin{verbatim}
  infixl 7  :/
  data Fraction a = a :/ a  deriving (Eq, Read)
                    -- deriving Eq refers to the canonic representation approach
  num   (n :/ _) = n
  denom (_ :/ d) = d

  zeroFr, unityFr :: Ring a => a -> Fraction a

  zeroFr  x = (zeroS x):/(unity x)
  unityFr x = (unity x):/(unity x)

  canFr :: GCDRing a => String -> a -> a -> Fraction a
    --
    -- This is for bringing the intermediate result to the canonical
    -- fraction.
    -- mode = "g"  means to cancel the pair by gcd,
    --        "i"                           by canonical invertible,
    --        ""                            by both.
 
  instance Functor Fraction  where  fmap f (n:/d) = (f n):/(f d)
  instance Dom     Fraction  where  sample= num
                                    dom _ = error "dom (n:/d)  not defined\n"
\end{verbatim}
\normalsize






\newpage
\section{ PolLike class }
% -----------------------
\label{sec-pl}
   

This constructor class unifies certain operations for

  {\tt UPol} \ --- sparse univariate polynomial, 

  {\tt Pol} \ --- multivariate polynomial with dense power products,

  {\tt RPol} \ --- `recursive' form (the power products are sparse too),

  {\tt EPol} \ --- sparse representation for vectors over polynomials, 

  {\tt SymPol} \ --- symmetric function (polynomial).
\medskip

For example, the leading coefficient \ {\tt lc f}, \ 
total degree \ {\tt deg f} \ have the same denotation for all five 
models listed above.

Some of the below operations can be understood more definitely when
observing their instances for \ {\tt UPol, Pol, \ldots}


\footnotesize
\begin{verbatim}
  class Dom p => PolLike p            
    where                               
    pIsConst  :: CommutativeRing a => p a -> Bool          -- "is constant"
    lpp       :: CommutativeRing a => p a -> PowerProduct  -- leading power product       
    deg       :: CommutativeRing a => p a -> Z             -- total degree
    ldeg      :: CommutativeRing a => p a -> Z   
                                      -- total degree of lpp (depends on ordering)
    lm        :: CommutativeRing a => p a -> Mon a         -- leading monomial
    pTail     :: CommutativeRing a => p a -> p a   
    pFreeCoef :: CommutativeRing a => p a -> a             -- free coefficient
    pCoefs    :: p a -> [a]      -- coefficients listed in same order as monomials;
                                 -- for RPol, the order is "depth first"

    pCoef     :: CommutativeRing a => p a -> [Z] -> a
                                             -- coefficient of given power product
    pVars     :: p a -> [PolVar]                         -- variable list
    pPPO      :: p a -> PPOrdTerm                        -- PP ordering description
    degInVar  :: CommutativeRing a =>  Z -> Z -> p a -> Z
                                    -- for0 i    f
                           -- deg f  in variable No i; put it  for0  for zero f

    pMapCoef :: AddGroup a => Char -> (a -> a) -> p a -> p a
                           -- mode    f
                           -- map  f  to each coefficient.  mode = 'r' means
                           -- to detect (and delete) appeared zero monomials

    pMapPP   :: AddGroup a => ([Z] -> [Z]) -> p a -> p a
                --             f
                -- map f to each exponent. It does not reorder the
                -- monomials, nor sums similars. Examples:
                -- pMapPP (\ [i]   -> [i+2]  ) (x+1)   = x^3+x^2  in Z[x]
                -- pMapPP (\ [i,j] -> [i+j,j]) (x*y+1) = x^2*y + 1

    pCDiv :: CommutativeRing a => p a -> a -> Maybe (p a) -- quotient by coeficient
    varPs :: CommutativeRing a => a -> p a -> [p a]       
                           -- Convert each variable from  f :: p a  multiplied 
                           -- by the given non-zero coefficient to  p a.


    pValue :: CommutativeRing a => p a -> [a] -> a
           --
           -- Value of "polynomial" at  [a1 .. an],  extra  ai  are cut.
           -- Example: for a[x], a[x,y]   x^2   -> [2]     -> 4   
           --                             x^2+y -> [2,0]   -> 4   
           --                             x^2+y -> [2,0,3] -> 4
           --                             x^2+y -> [2]     -> error...

    pDeriv  :: CommutativeRing a => Multiindex Z -> p a -> p a
              -- Derivative by multiindex.
              -- Example: for  variables = [x1,x2,x3,x4],
              --          pDeriv [(2,3), (4,2)] === (d/dx2)^3*(d/dx4)^2
     
    pDivRem :: CommutativeRing a => p a -> p a -> (p a, p a)
      --
      -- f -> g -> (quotient, remainder)
      -- For  a[x] and Field(a),  it has to satisfy the Euclidean division 
      -- property.
      -- In any case, it has to continue the Euclidean-like reduction 
      -- (applying  divide_m  to divide coefficients) 
      -- while  lm(g)  divides  lm(currentRemainder).
      -- Example:  
      -- 5*x^2+1, 2*x -> ((2/5)*x, 1      )   for  a = Rational
      --                 (0,       5*x^2+1)   for      Z

    pFromVec :: CommutativeRing a => p a -> [a] -> p a
                --
                -- Convert (dense) vector to p. of the given sample.
                -- Example:  2*x -> [0,1,0,2,3,0,0] -> x^5 + 2*x^3 + 3*x^2
                -- So far, consider it ONLY for  UPol.

    pToVec   :: CommutativeRing a => Z -> p a -> [a]
                -- List of the given length of p. coefficients,
                -- gaps between the power products filled with zeroes.
                -- So far, consider it ONLY for  UPol.
\end{verbatim}
\normalsize

\underbar{Remarks}
\medskip

{\tt lpp f} \ \ is \ {\tt Vec [deg f]} \ \ for {\tt UPol} \ \ and \ \ 
                             \verb#snd $ eLpp f# \ \ for {\tt EPol}
\medskip

{\tt ldeg} \ \ is \ {\tt totalDeg . lpp} \ \ for {\tt Pol}, \ \ and

        \hspace{18mm} {\tt totalDeg . snd . eLpp} \ \ for {\tt EPol}
\medskip

{\tt lm} \ \ is extended \ {\tt lmU} \ for {\tt UPol} \ \ and 

    \hspace{10mm} \verb#case eLm f of (c, (_,p)) -> (c,p)# \ \ \ \ for {\tt EPol}
\medskip

{\tt pPPO} \ \ is \ {\tt (lexPPO 1)} \ for {\tt UPol} \ \ and \ \ 
                                {\tt pPPO . epolPol} \ \ for {\tt EPol}
\medskip

{\tt pToVec n f = cs} \ \ \ is formed as follows. 
\\
let $m$ be the number of monomials in the dense form of a polynomial 
{\tt f}.

If \ $n > m$ \ then \ $n-m$ \ zeroes are prepended to the result,\\
otherwise, \ $m-n$ \ higher monomials are cut out.

Example: \ \verb# 7 (a*x^4 + b*x^2 + c)   -> [0,0,a,0,b,0,c] #

\verb#          7 (a*x^9 + b*x^5 + c*x) -> [0,b,0,0,0,c,0] #
\medskip

{\tt varPs} \ \ is widely usable. For example, for a polynomial \ 
{\tt f} \ from \ {\tt P = Z["x","y"]} 
\\
{\tt varPs 1 f --> [x,y]}, \ \ where \ {\tt x, y} \ are the elements 
of {\tt P}. \ See also {\tt varP}.
\medskip

{\tt deg, ldeg} \ \ may differ only in the multivariate case.\\ 
For example, for \ \verb#f = x + y^2*z# \ represented as \ 
\verb#Pol [<x>, <y^2*z>]# \ldots,\\
{\tt ldeg f = 1, \ deg f = 3}.  
\medskip

{\tt c = pCoef f js} \ \ has the following meaning.
\\
For {\tt UPol} : \ \ {\tt js = [j]} \ and \
          {\tt c =} coefficient of degree {\tt j} in {\tt f}.
\\
For {\tt Pol} : \ \ {\tt c =} coefficient of power product \ {\tt Vec js}.
\\
For {\tt EPol} : \ \ {\tt js = j:ks} \ and \ 
                       {\tt c =} coefficient of {\tt (j, Vec ks)}.
\\
For {\tt RPol, SymPol} \ \ it is undefined.
\bigskip



\underbar{Some polymorphic functions under PolLike context}

\footnotesize
\begin{verbatim}
  lc :: (PolLike p, Set a) => p a -> a             -- leading coefficient
  lc  f = case  pCoefs f  of
                        a:_ -> a
                        _   -> error $ ("lc 0, \n0 <- R"++) $ shows (pVars f) $
                                     (",\nR = "++) $ showsDomOf (sample f) "\n"

  pCont :: (GCDRing a, PolLike p) => p a -> a            -- gcd of coefficients
  pCont =  gcD . pCoefs                          

  pHeadVar :: (PolLike p, Set a) => p a -> PolVar 
  pHeadVar f = case pVars f of  v:_ -> v
                                _   -> error (...++"Empty variable list\n")
  numOfPVars :: PolLike p => p a -> Z
  numOfPVars = genericLength . pVars

  varP :: (PolLike p, CommutativeRing a) => a -> p a -> p a    
  varP a = head . varPs a                         -- useful in univariate case 

  lc0 :: (PolLike p, AddSemigroup (p a), Set a) => a -> p a -> a
  lc0 zr f = if isZero f then zr else lc f

  deg0 :: (PolLike p, AddSemigroup (p a), CommutativeRing a)
          =>
          Char -> Z -> p a -> Z
  deg0    mode    d    f   =  case (isZero f, mode) of (True, _  ) -> d
                                                       (_   , 'l') -> ldeg f
                                                       _           -> deg f
  cPMul :: (PolLike p, Ring a) => a -> p a -> p a
  cPMul a = pMapCoef 'r' (mul a)                      -- product by coefficient
\end{verbatim}
\normalsize
%
The examples with these useful functions appear all through this
manual and in\\ 
\verb#demotest/T_*.hs#.
\medskip

Further, for \ {\tt PolLike p}, \ {\tt cPMul} \ already makes \ 
{\tt (p a)} \ a module over \ {\tt a} :
\footnotesize
\begin{verbatim}
  instance (Ring a, PolLike p, AddGroup (p a)) => LeftModule a (p a)
    where
    cMul                    = cPMul 
    baseLeftModule (_,f) dm = ...
\end{verbatim}
\normalsize



\newpage
\section{ Univariate polynomial }
% -------------------------------
\label{sec-upo}


\subsection{ Preface }
% --------------------
\label{sec-upo.p} 

\begin{verbatim}
  type PolVar = String     -- polynomial "variable"
  type UMon a = (a, Z)     -- univariate monomial

  data UPol a = UPol [UMon a] a PolVar (Domains1 a)
\end{verbatim}
This describes a sparsely represented univariate polynomial \ 
{\tt UPol mons c v aD} :

  {\tt mons} \ \ is the list of monomials ordered decreasingly by 
              {\tt deg}, with zero monomials skipped,

  {\tt c} \ \ a sample coefficient, \ \ \ 
                         {\tt aD} \ domain description for \ {\tt a}.
\medskip

{\bf Example:} \ \ {\tt UPol [(1,4),(-2,2),(3,0)]  0 "t" dZ} 

 \hspace{22mm} represents the polynomial \ 
                                \ $t^4 - 2 t^2 + 3$ \ \ from \ {\tt Z[t]}.

The equality for {\tt UPol} uses the above presumed conditions on
representation: it compares only the monomial lists.
\footnotesize
\begin{verbatim}
  instance Dom UPol where  dom    (UPol _ _ _ d) = d
                           sample (UPol _ c _ _) = c
\end{verbatim}
\normalsize
The polynomial constructors need several fields for auxiliary
information. Therefore,

  {\it to build polynomials, apply \ \ \ \ \ \ {\tt cToUPol, cToPol}, 

       and then, \ casting by a sample.}  
\medskip

The casting by sample for \ {\tt UPol} \ \ 
(besides the maps of {\tt fromi, smParse}) 
is done via the operations \ {\tt ct, ctr} \ related to the \ 
{\tt Cast} \ instances:
they cast to \ {\tt UPol a} \ from \ {\tt a}, \ 
monomial, monomial list over {\tt a}.

{\tt ct} \ casts "as it is", \ \ \ {\tt ctr} \ --- 
with filtering out zero coefficient monomials.

{\bf Example:} \\ 
for \ \verb#f = UPol _ 1 "x" d# \ \ $\in$ \ {\tt P = Z[x]}, 
\\
\verb#cast _ f 2             # \ \ maps \ 2 \ \             to {\tt P},
\\
\verb#cast _ f (2,3)         # \ \ 
                                maps \ monomial $2 x^3$  \ \ to {\tt P},
\\
\verb#cast _ f [(2,3),(-1,1)]# \ \ 
                               maps \ given monomial list \ \ to {\tt P}.

We hope, with the next {\tt Haskell} version, {\tt DoCon} would be able to 
cast from the {\it variable} too.

\footnotesize
\begin{verbatim}
  instance Ring a => Cast (UPol a) a
    where
    cast mode (UPol _ _ v d) a = case mode of 'r'-> cToUPol v d a
                                              _  -> UPol [(a,0)] a v d

  instance AddGroup a => Cast (UPol a) (UMon a)       -- monomial to polynomial
    where
    cast mode (UPol _ c v d) (a,p) = UPol mons c v d
                        where
                        mons = if  mode=='r' && isZero a  then []  else [(a,p)]




  instance AddGroup a => Cast (UPol a) [UMon a] 
    where
    cast mode (UPol _ c v d) mons = UPol ms c v d
      where                                                -- order NOT checked
      ms = if mode /= 'r' then mons  else filter ((/= z) . fst) mons
      z  = zeroS c
\end{verbatim}
\normalsize

The algebraic instances for \ \ 
{\tt UPol a \ $\longleftrightarrow$ \ a[x]} 
\ \
are defined only for the \ Commutative ring \ {\tt a} \ with \ unity:
\begin{verbatim}
  Set ... AddGroup ... MulMonoid, Ring ... LinSolvRing, 
  EuclideanRing, FactorizationRing, 
  LinSolvLModule (UPol a) (Vector (UPol a))  
\end{verbatim}
--- each of them is correct under the corresponding condition.

The items for \ {\tt UPol} \ are exported from the module \ {\tt Pol},
\\
implemented in \ \verb#UPol*_.hs, Pol*_.hs, RPol*_.hs#.




\subsection{ PolLike UPol }
% -------------------------
\label{sec-upo.pl} 

This also illustrates the {\tt PolLike} class meaning.
It uses several auxiliary functions
\\
({\tt lmU, upolMons} \ldots) explained in the next section. 
Also note the use of \ {\tt ct, ctr} \ below.
%
\footnotesize
\begin{verbatim}
  instance PolLike UPol
    where  
    pIsConst f           = iszero_ f || (deg f)==0
    deg                  = snd . lmU      -- for UPol,  
    ldeg                 = snd . lmU      --   deg = ldeg
    lpp      f           = Vec [deg f]    -- :: PowerProduct 
    pVars (UPol _ _ v _) = [v]
    pPPO     _           = lexPPO 1
    pCoefs               = map fst . upolMons
    degInVar for0 i f    = case (upolMons f,i) of ([] , _) -> for0
                                                  (m:_, 1) -> snd m
                                                  _        -> 0
    varPs a f = [ct f (a, 1::Z)]

    pTail f = case upolMons f of _:ms -> ct f ms
                                 _    -> error$ ("pTail 0  in  R"++)$ shows (pVars f)$
                                         (",\nR = "++) $ showsDomOf (sample f) "\n"
    pFreeCoef (UPol mons c _ _) = if null mons then zeroS c
                                  else            case last mons of (a,0) -> a
                                                                    _     -> zeroS c
    pCoef f js = let {z = zeroS $ sample f;  vs = pVars f}
                 in
                 case js of [j] -> case  dropWhile ((>j) . snd) $ upolMons f
                                   of
                                     (a,i):_ -> if i==j then a else z
                                     _       -> z
                            _   -> error ...

    lm f = (a, Vec [j])  where  (a,j) = lmU f         -- lmU is usable

    pMapCoef mode f g = cast mode g [(f a, i) | (a,i) <- upolMons g]
    pMapPP f g        = ct g [(a, head $ f [n]) | (a,n) <- upolMons g]

    pCDiv f c = let (cs, exps) = unzip $ upolMons f
                in
                case allMaybes [divide_m a c | a <- cs] of
                                         Just qts -> Just $ ct f $ zip qts exps
                                         _        -> Nothing
    pValue f []    = error ...
    pValue f (a:_) = case unzip $ upolMons f of
                                 ([],_ ) -> zeroS a
                                 (cs,es) -> sum1$ zipWith (*) cs $ powersOfOne es a
    pDeriv [(1,n)] f = deriv_ n f
    pDeriv mInd    f = error ...

    pFromVec f coefs = ctr f $ reverse $ zip (reverse coefs) [0::Z ..]

    pToVec n f = case  (upolMons f, zeroS (sample f))  of

      (ms, z) -> dv n $ dropWhile ((>= n) . snd) ms
                  where
                  dv n []         = genericReplicate n z
                  dv n ((a,j):ms) = (genericReplicate (n-j-1) z)++(a:(dv j ms))

    pDivRem (UPol monsF c _ _) g =  ...    -- see UPol*.hs

  type Multiindex i = [(i,i)]
\end{verbatim}
\normalsize



\subsection{ Usable items for UPol }
% ----------------------------------
\label{sec-upo.i} 

\footnotesize
\begin{verbatim}
  upolMons :: UPol a -> [UMon a]
  upolMons    (UPol ms _ _ _) = ms

  instance Eq a => Eq (UPol a) where f==g = (upolMons f)==(upolMons g)

  lmU :: Set a => UPol a -> UMon a                          -- leading monomial
  lmU             f      =  case upolMons f of m:_ -> m
                                               _   -> error $ (..."lmU 0"...)

  leastUPolMon :: Set a => UPol a -> UMon a
  leastUPolMon f = case upolMons f of [] -> error $ (..."leastUPolMon 0"...)
                                      ms -> last ms

  mUPolMul :: Ring a => UMon a -> UPol a -> UPol a      -- multiply by monomial


  cToUPol :: Ring a => PolVar -> Domains1 a -> a -> UPol a
    --
    -- Coefficient --> polynomial.
    -- Apply it to create a  sample polynomial.  
    -- See the examples all through this manual.
    --
  cToUPol v aDom a = if a==(zeroS a) then  UPol []      a v aDom
                     else                  UPol [(a,0)] a v aDom
  

  umonLcm :: GCDRing a => UMon a -> UMon a -> UMon a
    --
    -- Lcm  of monomials over a  gcd-ring.
    -- For the Field case, it is better to compute this "in place", as
    -- (unity a, ppLcm ...)
    --
  umonLcm (a,p) (b,q) = case gcD [a,b] of g -> (a*(b/g), lcm p q)
  --------------------------------------------------------------------
  monicUPols_overFin :: CommutativeRing a => UPol a -> [[UPol a]]

    -- Given  f  from  a[x],  deg f > 0,  `a' a Finite ring,
    -- build the infinite listing --- partition  [gs(d), gs(d+1) ..]
    -- for the set  {g <- a[x] |  deg g >= d, lc g = 1},
    --
    -- were  d = deg f,   gs(n) = [g | deg g = n, lc g = 1]
    -- EXAMPLE:  a = Z/(3),
    --           2*x   -> [[x,x+1,x+2], [x^2,x^2+1..x^2+2x+2], [x^3..] .. ]
    --           2*x^2 -> [             [x^2,x^2+1..x^2+2x+2], [x^3..] .. ]
  -------------------------------------------------------------------- 
  upolPseudoRem :: CommutativeRing a => UPol a -> UPol a -> UPol a

    -- Pseudodivision in  R[x]  ([Kn], vol 2, section 4.6.1).
    -- For non-zero  f,g,  there exist  k,q,r  such that
    --   (lc(g)^k)*f = q*g + r,   k <= deg(f)-deg(g)+1,
    --   and either  r = 0  or  deg r < deg g.
    -- upolPseudoRem  returns only  r.
    -- It does not use the coefficient division, and it should be cheaper
    -- than   pDivRem (lc(g)^(n-m+1)*f) g
  --------------------------------------------------------------------  
  resultant_1_euc :: EuclideanRing a => UPol a -> UPol a -> a
                          -- resultant of  f,g  from  a[x],  `a' an Euclidean ring
  resultant_1_euc f g =
    if
      pIsConst f || pIsConst g  
      then
        error $ ("resultant_1_euc f g,"++) $
          ("\nf = "++)$ shows f $ showsWithDom g "g" "" "\ndeg f, deg g > 0  required\n"
    else  case ((deg f)+1, (deg g)+1) of
                           (n, m) -> det_euc $ resultantMt (pToVec n f) (pToVec m g)
  -------------------------------------------------------------------- 
  upolSubst :: CommutativeRing a => UPol a -> UPol a -> [UPol a] -> UPol a
                                    -- f      g         gPowers

    -- Substitute  g  for the variable into  f,  f,g <- R[x].
    -- The powers [g^2,g^3 ..] are either given in  gPowers
    -- or  gPowers = [],  and they are computed by the Horner scheme.

----------------------------------------------------------------------------
  upolInterpol :: CommutativeRing a => UPol a -> [(a,a)] -> UPol a
                                       -- smp    tab
\end{verbatim}
\normalsize
Interpolate (rebuild) polynomial \ \ $y = y(x)$ \ \ of degree \ 
$n$,\\ 
$x, y \ \in$ \ {\tt a}, \ \ \ $y(x)$ \ given by a sample polynomial \ 
{\tt smp} \ and by a table\\ 
{\tt tab = [$(x_0,y_0),\ldots,(x_n,y_n)$]} \ \ 
                                           in which \ $x_i$ \ do not repeat.
  
Required:  \ {\tt a} \ should have unity.

{\bf Example:}\\
for {\tt Z[x]}, \ \
      \verb#upolInterpol _ [(0,1),(1,-2),(2,-1)] --># \ $2 x^2 - 5 x + 1$

{\bf Method:} \\ 
Newton interpolation formula with the difference ratios:
$$
  p(x) = y_0 + (x-x_0) \cdot y[0,1] + \ \ldots \ + 
               (x-x_0) \cdot \ldots \cdot (x-x_{n-1}) \cdot y[0,1..n],
$$
where  \ $y[0,1..k]$ \ is the difference ratio of order $k$:
$$
  y[0,1] = (y_1-y_0)/(x_1-x_0), \ \ \
           y[0,1,2] = (y[1,2]-y[0,1])/(x_2-x_0), \ \ldots
$$



\subsection{ Random UPol }
% ------------------------
\label{sec-upo.rn} 

{\tt DoCon} declares

\footnotesize
\begin{verbatim}
  instance (CommutativeRing a, Random a) => Random (UPol a)
    where
                    -- put a random polynomial "between l and h" to have random
                    -- coefficients "between"  coef(i,l)  and  coef(i,h),
                    -- for each  i <- [0 .. (max (deg l) (deg h)]
    randomR (l,h) g =
               let  d      = succ $ maximum $ map (deg0 '_' 0) [l,h]
                    [u,v]  = map (Vec . pToVec d) [l,h]
                    (w,g') = randomR (u,v) g
               in   (pFromVec l $ vecRepr w, g')
\end{verbatim}
\normalsize

{\bf Example} of usage.\\
Make the list of random polynomials \ \ 
{\tt f $\in$ Z[x], \ \ deg f $\leq$ 2},
\\ 
{\tt f} having coefficients in the list \ {\tt [-2 .. 6]} :
\footnotesize
\begin{verbatim}
  ps $ mkStdGen 0
    where
    ps g = f:(ps g')  where  (f,g') = randomR (l,h) g
    p1   = cToUPol "x" dZ 1
    l = ct p1 [(-2,2),(-2,1),(-2,0) :: UMon Z]    -- convert monomial list
    h = ct p1 [(6 ,2),(6 ,1),(6 ,0) :: UMon Z]    -- to polynomial
\end{verbatim}
\normalsize
Further, to put, for example, the restriction\\
"coefficient $c_1$ of degree 1 is 0", \ 
the programmer has to skip the second monomial in the lists \ {\tt l, h};
\\
and the restriction \ $c_1 = 9$ \ is obtained by setting the second 
monomial {\tt (9,1)} in {\tt l} and in {\tt h}.

       


\newpage
\subsection{ Advanced methods for univariate polynomial }
% -------------------------------------------------------
\label{sec-upo.a} 


\subsubsection{ GCDRing, FactorizationRing, LinSolvRing }
\label{sec-upo.a.gfl} 

These instances refer to the possibilities of \\
polynomial GCD, \ factorization, \ Gr\"obner basis,
\\
and they are done as in the generic case of multivariate polynomial:
see Section~\ref{sec-pol.a}.

\underbar{Example}
\\
For the rings \ {\tt T = Z[t],  X = K[x]}  and a field \ {\tt K = Z/(p)},
\\
form some polynomials \ {\tt f, g} \ from \ {\tt T, \ \ h} \ from \ 
{\tt X}, \ and find

  {\tt f' =} derivative of {\tt f}, \ \ \ {\tt gcd f f'}, 
 
  Gr\"obner basis of {\tt [f,f',g]} \ over {\tt Z}, \ \ \
                                        {\tt factor h} \ over {\tt K}.
\footnotesize
\begin{verbatim}
  let  t1      = cToUPol "t" dZ (1 :: Z)       -- unity of T
       t       = varP 1 t1
       [t2,t3] = map (fromi t1) [2,3]
       f       = (t2*t + t1)^2 * (t - t1)
       g       = t2*t^2 + t2*t + t3
       f'      = pDeriv [(1,1)] f

       p  = 7 :: Z
       iI = eucIdeal "bef" p [] [] []          -- ideal (p) in Z
       k1 = Rse 1 iI dZ                        -- unity of K
       dK = upField k1 Map.empty                     -- domain description
       x1 = cToUPol "x" dK k1
       h  = smParse x1 "(x^2 + x + 3)*(x^14 + 2)" 
  in
  (gcD [f,f'],  fst $ gxBasis [f,f',g],  factor h)
\end{verbatim}
\normalsize
More examples can be found in \ 
\verb#demotest/T_polArit_.hs, T_finfield.hs#.



\newpage
\subsubsection{ Hensel lift }
\label{sec-upo.a.h} 

\footnotesize
\begin{verbatim}
  henselLift ::                            -- so far
    (EuclideanRing a, FactorizationRing a, Ring (ResidueE a))
    =>
    UPol a -> UPol a -> UPol a -> Maybe (UPol a) -> a -> a -> Z -> Z ->
    -- f      h1        g1               v1         p    p^n  n    m

                                                  (UPol a, UPol a, UPol a, a)
                                                   -- h'   g'      v'      p^m
\end{verbatim}
\normalsize
Denote \ $F_k = a/(p^k), \ \ r_k : a[x] \longrightarrow F_k[x]$ \ \ 
natural projection modulo \ $p^k$.

Given
\begin{itemize}
\setlength\itemsep{0pt}
\item a square free \ {\tt f} \ from \ $A[x]$,

\item a prime \ {\tt p} \ from $A$ \ such that \ 
      {\tt p} \ does not divide \ {\tt resultant f f'} 
      \\ 
      (hence \ {\tt deg $r_1$(f) = deg f, \ and \ $r_1$(f) } is square free),

\item {\tt h1, g1, v1, n} \ 
      such that \ {\tt f - h1*g1 \ $\in$ \ (\verb#p^n#)},
     \\
  \verb#v1 = (f - h1*g1)/(p^n)#, \ \ 
                            {\tt 0 < l = deg h1 < deg f, \ \ lc h1 = 1},
\item {\tt m $\geq$ n}
\end{itemize}
find \ \ \verb#(h', g', v', p^m)# \ \ such that

  {\tt f - h'*g'} \ $\in$ \ \verb#(p^m)#, \ \ \ 
                                     {\tt v' = (f - h'*g')/}\verb#(p^m)#,

  {\tt deg h' = deg h1, \ \ deg g' = deg g1, \ \ lc h' = 1, \ \ 
       |h'|, |g'| \ < n$\cdot$|p|
  }.
\medskip

The algorithm cost is bounded by some degree of \ {\tt |p|$\cdot$(deg f)}.



\subsubsection{ Extension of finite field }
\label{sec-upo.a.e} 

Given a finite field \ $k$ \ and degree \ $d > 1$, \ \ 
{\tt extendFieldToDeg} \ builds an extension field \ $F$ \ over \ 
$k$ \ of dimension \ $d$.

DoCon does this by testing certain list of polynomials over \ 
$k$ \ for primality. The cost is bounded with \ 
$ O(d^3 \cdot |k|^{d+1}) $. \ It is usable for small $d$.
%
\footnotesize
\begin{verbatim}
  extendFieldToDeg :: Field k => UPol k -> Domains1 (UPol k) -> Z ->
                                 -- s      sDom                 d 
  
                              (ResidueE (UPol k), Domains1 (ResidueE (UPol k)))
                               -- u               domF
\end{verbatim}
\normalsize

{\tt k} \ is given by the sample polynomial \ {\tt s} \ over \ {\tt k}.

{\tt sDom} \ is the domain description for \ {\tt s}, setting it with  
  {\tt Map.empty} \ will cause its forming by new with \ {\tt upEucRing} 
  function.
  
{\tt u} \ is the unity of the reslt field \ {\tt F = k[x]/(p)}, \ 
  where \ {\tt p $\in$ k[x]} \ is the found irreducible polynomial 
  of sample \ {\tt s, \ deg r = d}.

{\tt domF} \ is the domain description (bundle) for the result field \ 
             {\tt F}. 

This function is exported from the module \ {\tt Pol}, \ 
implemented in \ \verb#Pfact1_.hs#.
  


\subsubsection{ Determinant over $k[x]$ for a finite field $k$ }
\label{sec-upo.a.d} 

For the large data, it is computed much cheaper by interpolation,
than by the Gauss elimination.
Sometimes,  it requires to build first certain extension \ $K$ \ of \ 
$k$ \ ({\tt extendFieldToDeg} applied), and then, interpolate \ 
$\det M$ \ over \ $K$, \ and project the result to \ $k$.
Still, the cost is very low.   See the module \ 
\verb#demotest/T_detinterp.hs#.
%
\footnotesize
\begin{verbatim}
  det_upol_finField :: Field k => [ResidueE (UPol k)] -> [[UPol k]] -> UPol k
                                  -- ext                 mM
\end{verbatim}
\normalsize
Certain degree cost method to compute \ $\det M$ \ over a domain \ 
$k[x]$ \ for a finite field \ $k$.
\\
For \ $M = (f_{i,j} \ldots)$ \ of size \ $m$, \ \ 
  $ r_i = \max \{ \deg f_{i,j} \ldots \}, $ \ \
  $ r = \sum_i [r_i | \ldots], \ \ \ \deg \det(M) \leq r $, 
\\ 
the cost of \ $\det$ \ is bounded by \ $ O( r^4 m^3 |k|^2 ) $.
 
This function is exported from the modle \ {\tt Pol}, \ implemented in \ 
\verb#Pfact1_.hs#.




\newpage
\section{ Power product }
% -----------------------
\label{sec-pp} 


\subsection{ Preface }
% --------------------
\label{sec-pp.p} 

The ordered additive group for the domain \ \ 
{\tt PowerProduct = Vector Z} \ \ 
expresses the ordered multiplicative group of monomials of kind \ \
$ x_1^{i_1} \ldots \ x_n^{i_n}, \ \ i_k \geq 0. $

So, the arithmetic for the power products has  to  be  defined,  and
several most usable admissible comparisons.
The arithmetic ({\tt OrderedAddGroup}) is induced by the {\tt Vector} 
instances. It remains to implement other useful items.

They are exported by the \ {\tt Pol} \ module,
and implemented in \ \verb#PP_.hs#.



\subsection{ Definitions }
% ------------------------
\label{sec-pp.d} 


\footnotesize
\begin{verbatim}
  type PowerProduct = Vector Z

  -- CAUTION:  Vec ns   can serve as a power product only if
  --                    ns = [n(1)...n(k)]  is non-empty  and  n(i) >= 0

  type PPComp = Comparison PowerProduct
  
  isMonicPP :: PowerProduct -> Bool
  isMonicPP =  (< 2) . genericLength . filter (/= 0) . vecRepr
                                    -- corresponds to monomial  xi^ki,  ki >= 0

  vecMax, ppLcm :: Ord a => Vector a -> Vector a -> Vector a
  vecMax v = Vec . zipWith max (vecRepr v) . vecRepr
  ppLcm = vecMax              -- Least Common Multiple of the power products

  ppComplement :: PowerProduct -> PowerProduct -> PowerProduct
  ppComplement    u               v            =  (ppLcm u v) - u

    -- Examples:  ppLcm (Vec [1,0,2]) (Vec [0,1,3]) -->  Vec [1,1,3]
    --
    --            let {p = Vec [1,0,1,1,1,0];  q = Vec [0,1,2,1,0,0]}
    --            in  (ppComplement p q, ppComplement q p)
    --            -->
    --            (Vec [0,1,1,0,0,0], Vec [1,0,0,0,1,0])

  vecMutPrime :: AddMonoid a => Vector a -> Vector a -> Bool
  vecMutPrime                   v        =  
    case  zeroS $ vecHead v
    of  
      z -> and . zipWith (\x y -> (x==z||y==z)) (vecRepr v) . vecRepr

  ppMutPrime, ppDivides :: PowerProduct -> PowerProduct -> Bool

  ppMutPrime = vecMutPrime          -- "power products are Mutually Prime"

  ppDivides p q = all (>= 0) $ vecRepr (q-p)       -- "p divides q"
\end{verbatim}
\normalsize


\underbar{Some usable admissible comparisons for power products}
\medskip

Admissible pp-comparison \ {\tt cp} \ means it is agreed with the 
multiplication by monomial, that is for the relation ($(<)$ 
expressed by condition \ {\tt cp u v == LT},
 
  (1) \ $zeroVector < v$ \ for any non-zero \ $v$,
  
  (2) \ $ u < v \ \Rightarrow \ u+w < v+w $ \ \  
        for any power products \ $u, v, w$.

Different  cp-s  define  different  representations  for  isomorphic
polynomial rings and express various {\it gradings} on the polynomial
algebra. Choosing power product comparison is important for the 
computational tasks with polynomials.
{\tt DoCon} pre-defines the following most usable orderings:
\begin{center}
         \verb#lexComp, lexFromEnd, degLex, degRevLexppComp_blockwise#
\end{center}
Looking at their definitions, the user can easily define one's own 
ordering and transmit it to polynomials.
Also keep in mind that for any admissible ordering \ {\tt cp}  

  {\bf (1)} \ {\tt cp} can be defined by a {\it flag}, that is a matrix 
 M over real numbers. This means that \ {\tt cp p q} \ compares first 
 {\tt f$_1$(p), f$_1$(q)}, \ where \ {\tt f$_1$} \ is the linear 
 functional defined by the first row of M, the rows \ 
 {\tt f$_1$, f$_2$, \ldots} \ are applied until the comparison is 
 solved.

 {\bf (2)} \ For any finite set of the power products
   (and this is a common case for the computational tasks), 
    M is equivalent to some integer matrix with non-negative elements.

\footnotesize
\begin{verbatim}
  lexComp, lexFromEnd, degLex, degRevLex :: PPComp 

  lexComp    v = lexListComp compare (vecRepr v) . vecRepr
  lexFromEnd v = lexListComp compare (reverse $ vecRepr v) . reverse . vecRepr

  degLex p@(Vec ns) q@(Vec ms) = case compare (sum ns) (sum ms) of EQ -> lexComp p q
                                                                   v  -> v
  degRevLex  p@(Vec ns) q@(Vec ms) = case compare (sum ns) (sum ms) of
                                                                EQ -> lexFromEnd q p
                                                                v  -> v
    -- degRevLex  is not so trivial.  For example, for  n = 3
    -- it is presented by the matrix [u1,-e3,-e2] = [[1, 1, 1],
    --                                               [0, 0,-1],
    --                                               [0,-1, 0]
    --                                              ]



  ppComp_blockwise :: Z -> PPComp -> PPComp -> PowerProduct -> PowerProduct -> CompValue
                   -- m    cp        cp'       p               q  
    -- compare p q according by the direct sum of comparisons  cp, cp':
    -- first  cp  compares the vectors of the first  m  items from  p, q,
    -- then, if equal, the rests are compared by  cp'.
\end{verbatim}
\normalsize



\subsection{ PP Ordering description }
% ------------------------------------
\label{sec-pp.o} 

These items are exported by the \ {\tt Pol} \ module, \ 
implemented in \ \verb#UPol_.hs#.
\begin{verbatim}
  type PPOId     = (String, Z)
  type PPOrdTerm = (PPOId, PPComp, [[Z]])
\end{verbatim}
The power product ordering description (term) \ \ {\tt (id, cp, ws)} \ \
consists of the \ identifier \ {\tt id}, \ comparison function \ 
{\tt cp}, \ and a list \ {\tt ws} \ of integer {\it weights}.
{\tt []} \ for \ {\tt ws} \ means the weights are not given.
  
For most purposes, it suffices to set this term, for example, like
this: 
\begin{center}   {\tt (("dlex", 3), degLex, [])}
\end{center}
{\tt id} \ is set by the programmer (in addition to var list) in order 
to identify the domain parameter for polynomial. 
{\tt DoCon} looks into \ {\tt id} \ only when trying to find whether the two
polynomials are under the same pp-ordering --- this may be useful,
for example, for the conversion between domains.
\footnotesize
\begin{verbatim}
  ppoId      = tuple31   -- extracting parts of PPOrdTerm
  ppoComp    = tuple32   --
  ppoWeights = tuple33   --

  lexPPO :: Z -> PPOrdTerm                -- most usable ppo is  lexPPO n
  lexPPO    i =  (("lex", i), lexComp, []) 
\end{verbatim}
\normalsize
Why do we need the pp ordering description to add to the comparison 
function?
Because sometimes one needs the `space' of all admissible orderings,
to find there the ordering with certain property.  In this case, it
is natural to represent a pp ordering as say an integer matrix.





\newpage
\section{ Multivariate Polynomial }
% ---------------------------------
\label{sec-pol}  

For the polynomials, everything is exported from the \ {\tt Pol} \
module. Most of implementation is in the subtree \ \verb#source/pol/*#  



\subsection{ Representation }
% ---------------------------
\label{sec-pol.rp} 

\footnotesize
\begin{verbatim}
  type Mon a = (a, PowerProduct)              -- multivariate monomial

  data Pol a = Pol [Mon a] a PPOrdTerm [PolVar] (Domains1 a)
                                                       -- (multivariate) polynomial
  instance Dom Pol  where  dom    (Pol _ _ _ _ d) = d
                           sample (Pol _ c _ _ _) = c

  instance Eq a => Eq (Pol a) where  f==g = (polMons f)==(polMons g)

  -- extracting parts of (Pol ..)

  polMons       :: Pol a -> [Mon a]
  polPPOId      :: Pol a -> PPOId 
  polPPComp     :: Pol a -> PPComp
  polPPOWeights :: Pol a -> [[Z]]

  polMons (Pol ms _  _  _  _ ) = ms

  polPPOId      = ppoId      . pPPO
  polPPComp     = ppoComp    . pPPO
  polPPOWeights = ppoWeights . pPPO
\end{verbatim}
\normalsize
A polynomial \hspace{46mm}  {\tt Pol mons c o vars aD}
\\
contains the 
%
\begin{itemize}
\setlength\itemsep{0pt}
\item monomial list \ {\tt mons} \ sorted decreasingly under the 
      pp-ordering \ {\tt o}, \ zero coefficient monomials skipped, 
      each exponent is a vector of same size \ {\tt n = length vars},

\item sample coefficient \ {\tt c},
\item admissible pp ordering description \ {\tt o},
\item finite list \ {\tt vars} \ of variables (indeterminates),
\item description \ {\tt aD} \ of the coefficient domain.
\end{itemize}
--- see (Section~\ref{sec-prp.ske} DF), ~\ref{sec-prp.skco.df}. 

The equality of polynomials means only the equality of the {\tt mons}
lists. The domain of polynomials is parameterized by the 

  (1) coefficient domain {\tt aD}, \ \ \ 
                         (2) number {\tt n = length vars} \ of variables, 

  (3) pp ordering \ {\tt o}.

For example, different \ {\tt o} \ correspond to different membership
functions for the polynomial set, because the monomial list is sorted 
by {\tt o}.

{\bf Warning:} \\
{\tt DoCon} is not safe against mixing of polynomials with different 
domain parameters, or against mixing of exponents of different size 
in one polynomial.
\medskip

Thus, evaluating \ \ \verb#(Pol mons 0 o1 _ _) + (Pol mons 0 o2 _ _)#
\ \ 
with different comparisons in \ {\tt o1, o2} \ may yield incorrect 
result.

Naturally, the constructors may compose. For example, the types
\\ 
{\tt UPol (UPol a)} \ \ and \ \ {\tt UPol (Pol (UPol a))} 
\\ 
represent (together with sample polynomials) the domains
\\ 
$a[x][y]$ \ and \ $ ((a[x])[y_1,\ldots,y_n])[z] $ \ \ \ respectively.


\underbar{Examples} 

For \ $R = Z[x,y,z,u]$ \ and lexicographic pp ordering, \ 
$f = 2 x z^2 + y^4$ 
\\  
is represented internally as
\footnotesize
\begin{verbatim}
  Pol [(2, Vec [1,0,2,0]), (1, Vec [0,4,0,0])]  0 (lexPPO 4) ["x","y","z","u"] dZ
\end{verbatim}
\normalsize
Under the \ {\tt degLex} \ comparison, it represents as
\footnotesize
\begin{verbatim}
  Pol [(1, Vec [0,4,0,0]), (2, Vec [1,0,2,0])]  0 (...) ["x","y","z","u"] dZ
\end{verbatim}
\normalsize




\subsection{ How to build polynomials }
% -------------------------------------
\label{sec-pol.b} 

Apply \ {\tt cToPol} \ to obtain an initial sample \ {\tt s} \ for a
polynomial domain \ $P = a[x_1,\ldots,x_n]$. 
\\
Then, apply the casting maps 
\begin{center}  {\tt fromi s, \ \ ct s, \ ctr s, \ \ smParse s}
\end{center}
to obtain a polynomial from \ 
integer, coefficient or monomial(s), string \ \ respectively.

Apply also the map of variables \ 
{\tt varPs 1 s -->} [x$_1$',\ldots,x$_n$'],
\\
with \ $x_i'$ \ are all the variables as polynomials from $P$, \ 
and then, combine \ $x_i'$ \ in arithmetic expressions.  
\medskip

{\bf Example:} \\
Form the polynomials \ \ 
$ 5/6, \ \ -2 x^2 y + 3 y^4 + (1/2) x + y, \ \ 7x + 8y$ \ \ in \ {\tt Q[x,y], 
\\ 
Q = Fraction Z}, \ \ with the degree-lexicographic ordering; 
also form a polynomial in {\tt Q[x,y]} from the given monomial \
{\tt m = (a,p)} :


\newpage
\footnotesize
\begin{verbatim}
  f (a,p) = let  o          = (("degLex",2), degLex, [])
                 uQ         = 1:/1 :: Fraction Z
                 dQ         = upField uQ Map.empty
                 p1         = cToPol o ["x","y"] dQ uQ
                 [x,y]      = varPs uQ p1;
                 [p2,p3,p4] = map (fromi p1) [2,3,4] 
                 f56        = 5:/6 :: Fraction Z 
          in
          (ct p1 f56,               -p2*x^2*y + p3*y^4 + (p1/p2)*x + y, 
           smParse p1 "7*x + 8*y",  ctr p1 (a,p)
          )
\end{verbatim}
\normalsize
%
{\bf Remarks.} 
Applying {\tt smParse} may cost a couple of times more than the rest 
of this program.

{\tt ctr p1 (a,p)} \ differs from \ {\tt ct p1 (a,p)} \ in the case 
when \ {\tt a = 0} \ in that \ {\tt ctr} \ also tests for zero.

See the \ {\tt Cast} \ instances for the constructors \ 
{\tt Pol, UPol, RPol} \ and others.

Apply similar approach to the \ {\tt UPol, RPol} \ constructors.




\subsection{ Usable items for polynomials }
% -----------------------------------------
\label{sec-pol.f} 

\footnotesize
\begin{verbatim}
  type PolPol a = Pol (Pol a) 

  instance AddGroup a => Cast (Pol a) (Mon a)           -- from monomial
    where
    cast mode (Pol _ c o v d) (a,p) = Pol mons c o v d
                           where
                           mons = if mode=='r' && isZero a then [] else [(a,p)]
 
  instance AddGroup a => Cast (Pol a) [Mon a]           -- from monomial list
    where                                      
    cast mode (Pol _ c o v d) mons = Pol ms c o v d
      where                                            -- order is NOT checked
      ms = if mode/='r' then mons  else filter ((/= z) . fst) mons
      z  = zeroS c

  instance Ring a => Cast (Pol a) a                        -- from coefficient
    where
    cast mode (Pol _ _ o vs d) a = case (mode, isZero a, Vec $ map (const 0) vs)
                                   of  
                                     ('r', True, _ ) -> Pol []       a o vs d
                                     (_  , _   , pp) -> Pol [(a,pp)] a o vs d
  --------------------------------------------------------------------
  instance PolLike Pol        -- see first class PolLike, instance PolLike UPol
    where  
    pIsConst f = case polMons f of (_,p):_ -> all (==0) $ vecRepr p
                                   _       -> True
    pPPO  (Pol _  _  o  _  _ ) = o
    pVars (Pol _  _  _  vs _ ) = vs

    lm  f   = case polMons f of m:_ -> m
                                _   -> error ...
    lpp f   = snd $ lm f
    pDeriv  = deriv_
    pCoefs  = map fst . polMons 
    pTail f = case polMons f of _:ms -> ct f ms 
                                _    -> error ...
    pFreeCoef (Pol mons c _ _ _) =  ... similar to UPol
    pCoef f js =           ...          -- coefficient of power product  Vec js

    ldeg f = case polMons f of (_,Vec js):_ -> sum1 js
                               _            -> error ...

    deg f = case  map (sum1 . vecRepr . snd) $ polMons f  of [] -> error ...
                                                             ds -> maximum ds
    degInVar for0 i f = case (i >= 0, polMons f) of

      (False, _ ) -> error (..."positive i needed \n")
      (_    , []) -> for0
      (_    , ms) -> maximum $ map (ith . vecRepr . snd) ms  where ith js = ...

    pMapCoef mode f g = cast mode g [(f a, pp) | (a,pp) <- polMons g]
    pMapPP f g     = ct g [(a, Vec $ f js) | (a, Vec js) <- polMons g]

    pCDiv f c = case  unzip $ polMons f  of ... -- similar to UPol
    varPs a f = [ct f (a, Vec js) | js <- scalarMt (pVars f) 1 (0::Z)]
      -- because
      -- variable's power product is a row in the unity matrix of size |vars|

    pDivRem     = ... -- similar to UPol - see comments to class PolLike
    pValue f cs = ... -- substitute  xi = ci  into  f

  leastMon :: Set a => Pol a -> Mon a
  leastMon f = case polMons f  
               of
                 m:ms -> last (m:ms)
                 _    -> error $ ("leastMon 0  in  R"++) $ shows (pVars f) $
                                 (",\nR = "++) $ showsDomOf (sample f) "\n"

  reordPol :: PPOrdTerm -> Pol a -> Pol a        -- bring to given pp ordering
  reordPol ppo (Pol ms c _ vars dom) =  
              Pol (sortBy cmp ms) c ppo vars dom  where 
                                                  cmp (_,p) (_,q) = cp q p 
                                                  cp              = ppoComp ppo
  fromUPol :: UPol a -> Pol a
  fromUPol (UPol ms c v d) = Pol [(a,Vec [p]) | (a,p) <- ms] c (lexPPO 1) [v] d
    --
    -- to convert from univariate polynomial means to make a vector of size 1 
    -- from each exponent, to set the variable list [v] and lexPPO ordering

  toUPol :: Ring a => Pol a -> UPol a
    -- to convert to univariate polynomial means to remove the pp-ordering 
    -- term,  to take the head variable only and the head of each power 
    -- product,  to order obtained monomials by degree,  
    -- to sum up the monomials of repeating degree

  monMul :: Ring a =>  a -> Mon a -> Mon a -> [Mon a]
                     --zero
  monMul z (a,p) (b,q) = case a*b of c -> if c==z then [] else [(c,p+q)]

  mPolMul :: Ring a => Mon a -> Pol a -> Pol a
  mPolMul              (a,p)    f     =  ctr f [(a*b,p+q) | (b,q) <- polMons f]

  monLcm :: GCDRing a => Mon a -> Mon a -> Mon a
    -- Lcm of monomials over a gcd-ring.
    -- For the  field  case, it is better not to call monLcm, 
    -- but to set directly  (unity a, ppLcm...)

  monLcm (a,p) (b,q) = case gcD [a,b] of g -> (a*(b/g), ppLcm p q)
  --------------------------------------------------------------------
  cToPol :: Ring a => PPOrdTerm -> [PolVar] -> Domains1 a -> a -> Pol a
  cToPol              ord          vars        aDom          a =
    -- Coefficient --> polynomial.
    -- Applying cToPol is the ONLY natural way to initiate a sample 
    -- polynomial.
    case  Vec $ map (const 0) vars  -- power product for  x1^0*..*xn^0,  xi<- vars
    of
      p -> if a==(zeroS a) then Pol []      a ord vars aDom
           else                 Pol [(a,p)] a ord vars aDom
\end{verbatim}
\normalsize

\footnotesize
\begin{verbatim}
  headVarPol :: CommutativeRing a => Domains1 (Pol a) -> Pol a -> UPol (Pol a)
                                     -- pDom             f        g
\end{verbatim}
\normalsize
Bring polynomial to head variable: \ 
$ 
a[x_1,x_2,\ldots,x_n] \ \longrightarrow \ PP'= P'[x1], 
\\ 
P' = a[x_2,\ldots,x_n], \ n > 1
$.
This is \ {\tt only} \ for \ the \ {\tt lexComp} \ ordering on 
\\  
$a[x_1,x_2,\ldots,x_n], \ a[x_2,\ldots,x_n]$.

New \ {\tt PPOId} \ for \ $a[x_2,\ldots,x_n]$ \ is \ {\tt ("lex", n-1)}. 

{\tt pDom} \ is the domain description for $P'$.

How to prepare \ {\tt pDom} ? \ \

Starting from the empty, it may be, say \ {\tt up{\it C} a Map.empty}, 
with {\it C} the strongest declared class possible in environment.

\begin{center}   {\tt fromHeadVarPol :: UPol (Pol a) -> Pol a}
\end{center}
$(a[x_2,\ldots,x_n])[x1] \ \longrightarrow \ a[x_1,x_2,\ldots,x_n], \ \ n > 1$.
\\
Inverse to \ {\tt headVarPol}. \ \ 
It is for the {\tt lexComp} ordering \ {\it only}.

New {\tt PPOId} is {\tt ("lex", n)}.

\footnotesize
\begin{verbatim}
toOverHeadVar :: CommutativeRing a => Domains1 (UPol a) -> Pol a -> Pol (UPol a)
                                      -- dX1  
\end{verbatim}
\normalsize
%
Bring polynomial to tail variables: \ \
      $ a[x_1,x_2,\ldots,x_n] \ \longrightarrow \ (a[x1])[x_2,\ldots,x_n] $.

$n > 1$ \ is required, and only \ {\tt lexComp} \ ordering is 
considered for the power products of \ 
$ [x_1,x_2,\ldots,x_n], [x_2,\ldots,x_n]$.

New {\tt PPOId} for \ $[x_2,\ldots,x_n]$ \ is \ {\tt ("lex", n-1)}.

{\tt dX1} \ is the domain description for \ $a[x1]$.


\begin{center}
       {\tt fromOverHeadVar :: CommutativeRing a => Pol (UPol a) -> Pol a}
\end{center}
$ (a[y])[x_1,\ldots,x_n] \ \longrightarrow \ a[y,x_1,\ldots,x_n]. $ \ \ 
This is inverse to \ {\tt toOverHeadVar}.

Only {\tt lexComp} ordering is considered for the power products.
\medskip


{\footnotesize
\begin{verbatim}
  data PPCoefRelationMode = HeadPPRelatesCoef | TailPPRelatesCoef
                                                deriving (Eq, Ord, Enum, Show)
\end{verbatim}
}
This is the {\it mode} for the functions \ {\tt toPolOverPol}, 
{\tt fromPolOverPol} \ shown below.
\medskip


{\footnotesize
\begin{verbatim}
  toPolOverPol :: CommutativeRing a => PPCoefRelationMode ->      -- mode
                                       Natural            ->      -- n
                                       PPOrdTerm          ->      -- coefO
                                       PPOrdTerm          ->      -- ppO
                                       Pol a              ->      -- f
                                       Pol (Pol a)
\end{verbatim}
}
For \ {\tt f} \ from \ {\tt a[xs \ ys]}, 
 
if \ {\tt mode = HeadPPRelatesCoef} \ then it embeds {\tt f} to \ 
                                                       {\tt a[xs][ys]}, 

otherwise, embeds to \ {\tt a[ys][xs]}.

Here \ {\tt n = length ys}, \\
{\tt coefO, ppO} \  is the pp-ordering for the coef-part and the 
power-product part in \linebreak 
{\tt a[coefVars][pVars]} \ respectively.

The new domain bundles are supported as {\tt upRing}.
\medskip



{\footnotesize
\begin{verbatim}
fromPolOverPol ::
  CommutativeRing a => PPCoefRelationMode -> PPOrdTerm -> Pol (Pol a) -> Pol a
                       -- mode               ppo          f
\end{verbatim}
}
If \ {\tt mode = HeadPPRelatesCoef} \ then it embeds from \ 
                             {\tt a[xs][ys]} \ to \ {\tt a[xs \ ys]},  \\
otherwise, it embeds to \ {\tt a[ys \ xs]}.

{\tt ppo} \ is the pp-ordering for the result.
\medskip




\footnotesize
\begin{verbatim}
  polToHomogForms :: (AddGroup a, Eq b) => (PowerProduct -> b) -> Pol a -> [Pol a]
                                         -- weight                
  polToHomogForms w f = 
            map (ct f) $ partitionN (\ (_,p) (_,q) -> (w p)==(w q)) $ polMons f
\end{verbatim}
\normalsize
(non-ordered) list of homogeneous forms of polynomial over \ {\tt a} \ 
with respect to\\ 
{\tt weight :: PowerProduct -> b}
\begin{center}
          {\tt addVarsPol :: Char -> PPOrdTerm -> [PolVar] -> Pol a -> Pol a}
\end{center}
Embed from \ $a[x_1,\ldots,x_n]$ \ to \ $a[y_1,\ldots,y_m, x_1,\ldots,x_n]$ 
\ \ 
or to \ $a[x_1,\ldots,x_n y_1,\ldots,y_m]$ \ \ 
by prepending/appending the variable list \ 
{\tt vars' = [$y_1,\ldots,y_m$]} \ to {\tt vars} and extending 
exponents with zeroes.

{\bf Caution:} \ the new pp-order term {\tt ord'} is required which 
should agree to the old one: \ 
{\tt (cp' restricted to \ $y_1 = \ldots = y_m = 0$) == cp},
\ \
and the weights agreed too.
  
{\tt mode = 'h'} \ \ means prepending {\tt vars'} to head of {\tt vars},

       any other value means appending to tail.


\footnotesize
\begin{verbatim}
   coefsToPol :: Ring a => Char -> Pol a -> [Z] -> [a] -> (Pol a, [a])
                           --mode  sample   degs   cs
\end{verbatim}
\normalsize
Convert coefficient list to polynomial of given sample.

Coefficients zip with the power products from the cube
\\
{\tt 
 [[$k_1,\ldots,k_n$] \ | \  $ 0 \leq k_i \leq d_i, \ d_i \in $  {\tt degs}]
}
\ \ 
listed in the {\tt lexComp} order.

Then, the zero coefficient monomials are filtered out.

{\tt mode = 'l'} \ \ means the sample is under {\tt lexComp}, \ 
                     in this case the final re-ordering is skipped.


\footnotesize
\begin{verbatim}
   polDegs ::   [Z] -> Pol a -> [Z]
             -- zdegs  f
\end{verbatim}
\normalsize
Returns the degrees in each variable, \ {\tt zdegs} \ for zero \ {\tt f}.

{\bf Example:}\\ 
for \ {\tt f} $ = x^2 z + x z^4 + 1  \ \in \ Z[x,y,z], $ \ \ 
{\tt polDegs [] f = [2,0,4]}


\begin{center} {\tt polPermuteVars :: AddGroup a => [Z] -> Pol a -> Pol a}
\end{center}
Substitution for polynomial variables \ $[x_1,\ldots,x_n]$ \ 
given by permutation at \ {\tt [1 .. n]}.

Monomial list reorders, but the variable list remains.

{\bf Example:} \ \ {\tt [2,1]} \ 
  $ \longrightarrow \ x^2 y + x y^3 \ \longrightarrow \ x^3 y + x y^2 $


\footnotesize
\begin{verbatim}
  polSubst :: CommutativeRing a => Char -> Pol a -> [Pol a] -> [[Pol a]] -> Pol a
                                -- mode    f        gs         powerLists
\end{verbatim}
\normalsize
Substitute polynomials \ 
              {\tt  gs = [$g_1,\ldots,g_m$] \ $\in R[x_1,\ldots,x_n]$ }
\\
for the variables \ $x_1,\ldots,x_m$ \ in a polynomial \ 
{\tt f} $\in R[x_1,\ldots,x_n]$.

The rest of $x_i$ remain. \ 
If \ $m > n$ \ then the rest of \ $g_i$ \ are ignored.

{\bf Method.}\\
{\tt f} converts recursively to \ $R[x_2,\ldots,x_n][x1]$, \ 
and so on, and the Horner scheme of substitution is applied by each $x_i$.

  {\tt mode = 'l'} \ \ means {\tt f} has the {\tt lexComp} ordering,
                  in this case the evaluations would be somewhat cheaper,

    \hspace{15mm} any other letter \ means generic case.

  {\tt powerLists} \ is either \ {\tt []} \ or \ 
    $ [g_{1}Powers,\ldots,g_{k}Powers], $ \ 
    where \ 
    $g_{i}Powers$ \ is either {\tt []} or the infinite list \ 
    {\tt [$g_i^2, g_i^3$ \ldots]}.

  {\tt powersLists = []} \ \ means the powers are not listed at all, 
                            compute them by the Horner scheme.

  $g_{i}Powers$ \ \ are ignored for \ $i > m$.

  $k < m$ \ \ means \ {\tt giPowers = []} \ for \ $i > m$.

  $g_{i}Powers$ {\tt = []} \ \ means again, to compute $g_i^j$ by 
                               the Horner scheme.


\footnotesize
\begin{verbatim}
  sPol :: GCDRing a => Pol a -> Pol a -> (Pol a, Mon a, Mon a)
                                          -- sp  m1     m2
\end{verbatim}
\normalsize
S-polynomial \ (the one related to Gr\"obner bases)
for non-zero polynomials: \\ 
{\tt sp = m1*f - m2*g}.

It also returns the corresponding complementary monomial factors \ 
{\tt m1}, {\tt m2}.

\begin{center}     {\tt  type PVecP a = (Pol a, [Pol a]) }
\end{center}
Polynomial-vector-polynomial \ {\tt fv = (f,v)} \ is supplied with the
polynomial pre-vector {\tt v}.

{\tt v} \ is often used to accumulate the coefficients \ $f_i$ \ 
of some \ $f$ \ --- relatively to some initial basis \ $gs$ : \ \
$ f = \sum_1^m f_i g_i $.

This serves accumulating of the {\it quotient} (transformation) part in
\\ 
the functions \ {\tt moduloBasis, gBasis}.


\footnotesize
\begin{verbatim}
  mPVecPMul :: Ring a => Mon a -> PVecP a -> PVecP a
  mPVecPMul              m        (f,gs)  =  (mPolMul m f, map (mPolMul m) gs)

  sPVecP :: GCDRing a => PVecP a -> PVecP a -> (PVecP a,Mon a,Mon a)
  sPVecP                 (f,us)     (g,vs) =   -- s-polynomial for  PVecP a
    let  (_,m1,m2) = sPol f g
         pdiff     = Pol_.sub_ (mPolMul m1 f) (mPolMul m2 g)

         (ps, qs)  = (map (mPolMul m1) us, map (mPolMul m2) vs)
         vdiff     = (zipWith Pol_.sub_ ps qs)
    in   ((pdiff,vdiff), m1, m2)
\end{verbatim}
\normalsize




\subsection{ Random Pol }
% -----------------------
\label{sec-pol.rn} 

Similarly to instance of \ {\tt Random UPol} \ (Section~\ref{sec-upo.rn}), 
{\tt DoCon} declares
%
\footnotesize
\begin{verbatim}
  instance (CommutativeRing a, Random a) => Random (Pol a) where
                                                           randomR (l,h) g = ...
\end{verbatim}
\normalsize
It puts a random polynomial  \ {\tt f} \ distributed uniformly in the 
``segment between polynomials {\tt l} and {\tt h}'' to have random
coefficients \ {\tt coef(pp)} \ between \ {\tt coef(pp,l)} \ and \
{\tt coef(pp,h)} \ for all the power products {\tt pp} such that \ 
{\tt coef(pp,l) $\neq$ 0} \ or \ {\tt coef(pp,h) $\neq$ 0}.

{\bf Example:} \ \ 
the polynomials from \ \ 
{\tt rands \ ($3 x^4 y^3 + 2 x y - 2, \ x y^2 - x y$) \ g}
\\
may have the coefficients

  {\tt a <- [0..3]} \ for {\tt pp = [4,3]}, \ \ \  
                          {\tt b <- [0..1]} \ for {\tt [1,2]}, 

  {\tt c <- [-1..2]} \ for {\tt [1,1]}, \ \ \  
                        {\tt d <- [-2..0]} \ for {\tt [0,0]}, 

  and \ {\tt 0} --- for all other power products {\tt pp}.




\subsection{ Advanced methods for Pol }
% -------------------------------------
\label{sec-pol.a} 

The \ {\tt GCDRing, FactorizationRing, LinSolvRing} \ instances for 
\ {\tt Pol} \ refer to the functions of \ 
polynomial GCD, factorization, Gr\"obner basis,
Their algorithms are set as follows.


\subsubsection{ Polynomial GCD }
\label{sec-pol.a.g} 

{\tt DoCon} defines \ {\tt instance GCDRing a => GCDRing (Pol a) where \ldots}
\\
But its methods  

 {\tt canInv, canAssoc} \ have sense when \ {\tt a} \ possesses 
                           {\tt (WithCanAssoc, Yes)},

 {\tt gcD} \ has sense when  {\tt a} \ possesses \ {\tt (IsGCDRing, Yes)}

--- see Section~\ref{sec-rg.pr}.

{\tt canInv, canAssoc} \ are defined via the (division by) \ 
{\tt canInv(lc(f))}.

For \ gcd, \ the simplest method with pseudodivision is applied,  
so far: (\cite{Kn} Volum 2, Section 4.6.1).
 
{\tt headVarPol} \ maps \ {\tt f, g} \ from \ $a[x_1,x_2,\ldots,x_n]$ \ 
to \ $a[x_2,\ldots,x_n][x1]$, \ \
{\tt f, g} \ reduced to primitives, then, gcd for the primitive
{\tt f, g} \ $\in R[x]$ \ is found for a gcd-ring \ 
$R = a[x_2,\ldots,x_n]$ \ via the pseudodivision.

The implementation notes are in \ \verb#Pgcd_.hs#.



\subsubsection{ Factorization in $k[x,y]$ }
\label{sec-pol.a.f} 

DoCon can do it for any finite field \ $k$, \ \ presented as \ \
$k = F[t]/(g)$, \ \ $g$ \ a generator over a prime field $F$. \ 
Such representation can always be found.

The residue ring here is represented by the {\tt ResidueE} constructor.

For \ $k[x]$, \ the usual (generalized) Berlekamp's method is applied,
with the cost bounded by \ $O( (\deg f)^3 )$.

For \ $k[x,y]$, \ the method is adopted from \cite{CG}. 
See \cite{Me3}. 
It allows the cost bound in \ $deg_x, deg_y$ \ with the main part
of \ $O( (deg_x f)^4*(deg_y f)^3 )$.

See \ \verb#demotest/T_pfactor.hs# \ 
for the examples of factorization.



\subsubsection{ Gr\"obner basis, syzygies }
\label{sec-pol.a.gr} 

The corresponding items are exported by the modules\\
{\tt RingModule (LinSolvRing(..)), \ GBasis} \\
and implemented in \ \verb#PolNF_, GBasFld_, GBasEuc_, Polrel_#.
\begin{center}  
  {\tt instance (EuclideanRing a) => LinSolvRing (Pol a) where \ldots}
\end{center}
is defined as follows.

  {\tt gxBasis} \ \ is the (weak) reduced Gr\"obner basis for  
                polynomials over an Euclidean ring \ {\tt a}.

  {\tt syzygyGens} \ \ is the syzygy generators found via the 
                   Gr\"obner basis function.

  {\tt moduloBasis mode fs} \ \  
    is either \ \verb#polNF _ fs# \ --- Gr\"obner reduction by the 
    Gr\"obner basis \ {\tt fs} \ over an Euclidean ring,
    or composition of \ \verb#gs = fst $ gBasis fs# \ and \ 
    \verb#polNF _ gs#.
\medskip

{\tt (Euclidean, Yes)} \   
is sufficient for the necessary properties of the syzygy basis 
finding and the ideal inclusion solvability.

For the canonical reduction modulo the ideal  
(presented by some fixed basis),  it is required \ {\tt (DivRemCan, Yes)} \  
for the base domain of \ {\tt a}. \
That is the canonical remainder property for \ {\tt remEuc 'c'}. 
\\
See (Section~\ref{sec-euc} DivRemCan), ~\ref{sec-linr.g}.

For example, {\tt DoCon} supports \ {\tt (DivRemCan, Yes)} \ for \  
{\tt Z}, \ and \ $k[x]$ \ for a field \ $k$ \ in a standard way.
\bigskip   


\underbar{ \{g\} \ Gr\"obner basis}

For \ 
{\tt P = Euclidean a => Pol a,  \ fs :: [P], \ \ \ gxBasis fs --> (gs,mt)}
\\
possesses the generic properties required by the {\tt LinSolvModule} 
category and the following specific ones. \ 
{\tt gs} \ \ is the reduced Gr\"obner basis {\tt gBasis} for the 
polynomials {\tt fs} over an Euclidean ring \ {\tt a}.   

In particular, \ {\tt a} \ may be a field.
When {\tt a} is a field, \ {\tt gBasis}\ builds the (strong) 
reduced Gr\"obner basis which is the unique representation of the 
{\it ideal}.

If {\tt a} is not a field, returned is a {\it weak} reduced 
Gr\"obner basis. 
So far, this is arranged so only because it is simpler to obtain the
canonical remainder by {\tt gs} applying the {\tt polNF} reduction 
with the {\tt "c"} mode.

{\tt gs} \ is ordered increasingly by lpp by the pp-comparison contained 
in \ $f_i$.

For a field {\tt a}, and more generally, for {\tt a} possessing \ 
{\tt (WithCanAssoc, Yes)}, \ $g_i$ are in the canonical associated form.

The matrix \ {\tt mt} \ is also accumulated such that 
\\ 
{\tt mt*(transpose [fs]) == transpose [gs]}
\ \ \
(the requirement of LinSolvModule).

Zero elements of {\tt fs} correspond to the zero columns in {\tt mt}.

In the case of all {\tt fs} being zeroes, the result is \ {\tt ([],[])}.
\medskip

{\bf Method.}\\
{\tt isField} \ is tested first for the base ring of {\tt a}. \ 
Then, for \ {\tt (IsField, Yes)}, \ 
certain adaptation of the method from [GM] is implemented
in \ \verb#GBasFld_.hs# \ for the strong reduced Gr\"obner basis.
See the comments there.

{\it Otherwise}, \ 
the weak Gr\"obner basis over a generic Euclidean ring is found.
The method is adopted from \cite{Mo}. See the comments in \ 
\verb#GBasEuc_.hs#.
\bigskip   


\underbar {Reduction from {\tt gxBasis} to real method}

{\tt gxBasis} \ for \ $f_i \ \in \ a[x_1,\ldots,x_n]$ \ \ 
allows also zeroes in the given list, and it corrects the transformation 
matrix respectively.

Also it calls the Gr\"obner basis for the (more generic) e-polynomials.

{\bf Examples:} \ see \ \verb#demotest/T_grbas1.hs,  T_grbas2.hs#.
\bigskip   


\underbar{\{ig\} isGBasis}

\begin{center}  {\tt isGBasis :: EuclideanRing a => [Pol a] -> Bool}
\end{center}
``{\tt fs} is a Gr\"obner basis''. \ 
For \ {\tt a} \ not a field, it means a weak Gr\"obner basis.

{\bf Method.} \\
Some of the s-polynomials \ {\tt sPol $f_i \ f_j$} \ 
are formed and reduced with the Gr\"obner normal form \ {\tt polNF} by 
\ {\tt fs}.  Optimizations are applied to test possibly smaller set of 
pairs --- the same optimization as in {\tt gBasis}.
  
See \ \verb#isGBasis*# \ in \ \verb#GBas_, GBasFld_.hs, GBasEuc_.hs# \ \    
for the implementation comments.
\bigskip   
 

\underbar{\{s\} Syzygy generators}

For \ 
{\tt fs :: [P], \ P = Euclidean a => Pol a, \ \  
syzygyGens mode fs --> [rels]
}\\
gives the list of linear relations (syzygies) on {\tt fs} 
(of type {\tt [P]})  that generates the module of all their syzygies.

For this polynomial case,  

  {\tt mode = "g"} \ \ means that {\tt fs} is a (weak reduced) 
      Gr\"obner basis, in this case the evaluation would be more direct.

  \hspace{15mm} {\tt ""} \ \ means the generic case.

For the weak Gr\"obner basis {\tt fs} over a {\it field} and \ 
\verb#ecpTOP_weight# \ ordering \cite{MoM} on the module \ $P^n$ \ 
generated by the weights \ {\tt lpp($f_i$), \ $f_i \in$ fs}, \ \
the result {\it is also a weak Gr\"obner basis} of the submodule 
\cite{MoM}.

(does this also hold for the Euclidean coefficients?)
\medskip

{\bf Caution.} \ We are not sure for the case when {\tt a} is not 
a field: maybe, the method is correct, but we had not dealt with the 
proof.

{\bf Method}
\\
For the {\tt "g"} mode, \ the needed generators \ {\tt rels} \ are 
obtained as the quotient results of the \ {\tt sPol $f_i \ f_j$} \ 
reduction to zero by {\tt fs} with the Gr\"obner normal form \ {\tt polNF}.

For other mode, \ \ {\tt gBasis fs --> (gs,mt)} \ \ 
finds the Gr\"obner basis and the transformation matrix \ {\tt mt}; \ \ 
{\tt syzygyGens "g" gs --> relsG} \ \ evaluate;
\\
then, {\tt rels} is composed via {\tt relsG} and {\tt mt} 
in a certain simple way --- see \cite{Bu}.

See \ \verb#Polrel_.hs# \ for the implementation comments.

{\bf Examples:} \ see \ \verb#demotest/T_grbas2.hs#
\bigskip



\underbar{\{n\} Gr\"obner normal form}

For \ {\tt P = Euclidean a => Pol a, \ \ fs :: [P]}
\\  
a weak Gr\"obner basis \ \ {\tt moduloBasis mode fs f --> (rem, qs)}
\\
is the reduction of {\tt f} by  \ {\tt Ideal(fs)} \ 
with the generic properties required by {\tt LinSolvRing}.

In this particular {\tt Pol} case, it applies the Gr\"obner normal 
form \ {\tt polNF}.

But if \ {\tt fs} \ is a Gr\"obner basis, then better ignore {\tt polNF} 
and apply \ {\tt moduloBasis mode} \ 
--- with \ {\tt mode = "g"} \ or {\tt "cg"}.

If  {\tt fs}  is not a Gr\"obner basis, then \ \
\verb#moduloBasis _ fs# \ \ and \ \verb#polNF _ fs# \ \ 
do very different things.
The former finds the Gr\"obner basis  {\tt gs} and applies  \ 
\verb#polNF _ gs#. 

While \ \verb#polNF _ fs f# \ reduces {\tt f} directly to normal form.
And in this latter case, the {\tt polNF} reduction does not necessarily
detaches the ideal. {\tt polNF} is applied repeatedly when the Gr\"obner
basis is computed.

\footnotesize
\begin{verbatim}
  polNF :: EuclideanRing a => String -> [Pol a] -> Pol a -> (Pol a, [Pol a])
                              -- mode   gs         f        rem     qs
\end{verbatim}
\normalsize
The following properties hold.

If {\tt gs} is a weak Gr\"obner basis \cite{Mo}, then

  \verb#(fst $ polNF anyMode gs f) == 0# \ $\Longleftrightarrow$ \ 
                                          {\tt f $\in$ \ I = Ideal(gs)}
\\
and if also {\tt a} is a c-Euclidean ring, then \ \ 
{\tt fst . polNF "c" gs} \ \ is a canonical map modulo {\tt I}.
\medskip

{\tt mode = tailMode++cMode}, \ \ the order is immaterial, 
                   also {\tt "c"} is equivalent to \ {\tt "cr", "rc"}.

{\tt tailMode} \ \ can be \ {\tt ""} \ or \ {\tt "r"}. 
\\
{\tt ""} \ means to reduce the head monomials only, \ \
{\tt "r"} \ --- to reduce the tail too.

{\tt cMode} \ 
is the mode for the coefficient reduction in moduloBasis;
it is processed only when the current {\tt (lm f)} is not the 
multiple of any {\tt (lm g)}. \\
{\tt (moduloBasis m bs a)} \ is applied for \ \ 
{\tt bs = [lc g | (lpp g) divides (lpp f)]} \ \ with \ {\tt m = cMode}.
\medskip

{\bf About method.}
\\
For the current \ {\tt monF = (a,ppF) = lm(f)}, \ find 
\\ 
{\tt gsPPF = [g <- gs | (lpp g) divides ppF]}, \ \ 
{\tt bs  = [lc g | g <- gsPPF] :: [a]}.
 
Then, \ $b_i$ \ first try to divide \ {\tt a} \ precisely.  
Hence, for \ {\tt Field a}, \ it turns to usual strong reduction of 
{\tt f} by {\tt gs}.

Otherwise (if {\tt a} is not a multiple of any $b_i$), \\ 
{\tt (a',ds) = coefNF cMode bs a}  \ \ reduces \  
{\tt a :: `a'} \ to  \ {\tt a'} \ by  {\tt bs}  accumulating the 
quotients {\tt ds}. 

And as the ring is Euclidean, \ {\tt coefNF} \ acts like extended gcd,\\ 
applying \ \ \verb#divRem _ a gcd(bs)# \ \ in the end.

Each $d_i$ multiplies the corresponding power product \ 
{\tt pi' = ppF-(lpp $g_i$)}. 

The new head monomial for {\tt f} is {\tt (a',ppF)} \ for non-zero
{\tt a'};
\\  
the new tail is \ {\tt pTail(f)} \ --- 
$\sum_ (d_i p_i' pTail(g_i) ...)$.

And so on, while {\tt (lpp f)} or {\tt (lc f)} can reduce. \ 
This is a weak reduction.

See \ \verb#PolNF_.hs# \ for the implementation comments.
\bigskip



\underbar{ \{ar\} Algebraic relations for polynomials }
\footnotesize
\begin{verbatim}
  algRelsPols :: EuclideanRing k =>
                 [Pol k] -> [PolVar] -> PPOrdTerm -> [Pol k] -> [Pol k]
                 -- hs      ys          oY           fs         rels
\end{verbatim}
\normalsize
Ideal generators for the algebraic relations for the polynomials \ 
{\tt fs} \ considered modulo \ {\tt Ideal(hs)}, \ \
$f_i, h_i$ \ are from \ $A = k[x_1,\ldots,x_n]$, \ \ $k$ \ a field
\\  
({\it would this work for Euclidean $k$ too?}).
  
Any \ {\tt rel $\in$ rels} \ is from \ $B = k[y_1,\ldots,y_m]$;

$y_i$ \ form the list {\tt ys} of the variables corresponding 
   bijectively to $f_i$, \ \ so that 
\\ 
$ rel(f_1,\ldots,f_m) = 0 \ in \ A $.

{\tt rels} \ is the reduced Gr\"obner basis in $B$ for the ideal 
  of all such algebraic relations for \ {\tt fs}.

{\tt oY} \ is the power product ordering description chosen for $B$.
  
{\bf Restriction:} \ no $f_i$ should belong to \ {\tt Ideal(hs)}.
\medskip

\underbar{Method} \ \ is taken from the paper \cite{GTZ}:
\begin{enumerate}
\item Embed \ $f_i, h_i$ \ to \ 
                        $C = k[x_1,\ldots,x_n,y_1,\ldots,y_m] = k[X,Y]$;

\item Let \ $ p_i = f_i - y_i$ \ in $C$, \\ 
   $C$ is viewed under the direct-sum power product comparison 
  \\
   \verb#(ppComp_blockwise |xs| cpX cpY)# \\ 
   (so, X-power-products $>$ Y-power-products),
   \\
   {\tt gs =} Gr\"obnerBasis {\tt ([$p_1,\ldots,p_m$]++hs)} \ \ in $C$;

\item {\tt rels' = [g | g <- gs \ and \ g \ does not depend on X]}

\item {\tt rels = rels'} \ embedded in $k[Y]$.                 
\end{enumerate}

{\bf Example 1:} \\ 
\verb#demotest/T_cubeext.hs# \ applies \ \ 
{\tt algRelsPols hs ["y","x"] o [y',x']} \ \
to find certain quadratic relation over the discriminant field \ 
$k(d)$ \ between the two roots of a polynomial \ 
$x^3 + a x + b, \ \ a, b$ \ from the field $k$.
\medskip

{\bf Example 2.} \\
Find the equation system in \ {\tt x, y, z} \ for some curve in \ 
{\tt K}$^3$ \ given by parametric equations \ \ 
{\tt x = x(t), y = y(t), z = z(t)}, \ \ {\tt K = Fraction Z}.
%
\footnotesize
\begin{verbatim}
  type K = Fraction Z
  type P = Pol K
  eqs =
    let  k1  = 1:/1 :: K
         dK  = upField k1 Map.empty
         zyx = ["z","y","x"]
         ord = (("",3), degLex, [])            -- pp ordering for z, y, x
         t1  = cToPol (lexPPO 1) ["t"] dK k1   -- 1 of T = K[t]
         p1  = cToPol ord        zyx   dK k1   -- 1 of P = K[z,y,x]
         dP  = upLinSolvRing p1 Map.empty
         t   = varP k1 t1
         fs  = [t^4, t^3, t + t^5]
               -- z  y    x         this is called the Abyankhar curve
         rels = algRelsPols [] zyx ord fs
    in
    transp $ Mt [rels] dP     -- to print nicely `rels'
\end{verbatim}
\normalsize
{\tt eqs} yields the Gr\"obner basis for all the equations in \ 
{\tt z, x, y} \ for the above curve: 

  [$ z^2 - y x + z, \ \ \ y^3 x + z y^2 - z x^2 + y^2, $

   $ y^4 - z y x + y x - z, \ \ \ z y^2 x + 2 y^2 x - x^3 + zy + y, $

   $ z y^3 + y^3 - y x^2 + z x $
  ]
\bigskip


\underbar{\{und\} `Under' power products}

\begin{center}  
          {\tt underPPs :: [PowerProduct] -> (InfUnn Z, [PowerProduct])}
\end{center}
A power product \ {\tt p} \ is called an `under' power product with 
respect to the power product list \ {\tt pps} \ 
if none of \ {\tt pps} divides {\tt p}.

`Under' monomials are useful in computation in the residue rings of 
a polynomial ring. This is because for the coefficient field  $k$, \ \
$P = k[x_1,\ldots,x_n]$, \ {\tt gs} a Gr\"obner basis, 
\\ 
{\tt pps = map lpp gs}, \ \ under-s form a linear basis over \ $k$ \ 
for the residue domain \ $P/Ideal(gs)$.

Trivial {\bf Lemma:} \\
the set of `under' power products is finite if and only if

  for any \ {\tt $x_i$ <- vars}, \ $1 \geq i \leq n$, \ \ 
  {\tt pps} contains \ {\tt p = $x_i^k$}, \ with some $k > 0$ \ --- that is\\ 
  {\tt p = Vec [0,\ldots,0,k,0,\ldots,0]}.
\medskip

{\tt underPPs pps} \   
yields the list (and number) of `under' power products for a given
list of any power products {\tt pps}.
\\
It returns \ {\tt (Infinity, [])} \ for the infinite list, \ \ 
{\tt (Fin 0, [])} \ for the empty list.

{\bf Examples:} 
\footnotesize
\begin{verbatim}
  underPPs [Vec [0,3], Vec [1,2]]            --> (Infinity, [])
  underPPs [Vec [0,3], Vec [1,2], Vec [2,0]] -->
     
              (Fin 5,  [Vec [0,0], Vec [0,1], Vec [0,2], Vec [1,0], Vec [1,1]])
\end{verbatim}
\normalsize
{\bf Mind:} \  
the very list may be sometimes stupidly long, hard to print, and so
on. For example, for \ \ {\tt pps =} [$x^{10}, y^{10}, z^{10}, u^{10}$], \ \
{\tt underPPs pps} \ \ yields \ {\tt (10000, pps')}, \ with 
\\ 
{\tt pps' = [[0,0,0,0], [0,0,0,1] \dots]}.

But if you use only the {\it number}, like say in \ \ 
\verb#let (n, _) = underPPs pps in# \ldots,
\\
then the evaluation is much cheaper.






\section{ Free module over Polynomial }
% -------------------------------------
\label{sec-polv}  



\subsection{ Introduction }
% -------------------------
\label{sec-polv.i} 


For any ring $P$, \ $M = P^m$ \ is a free module over \ $P$ of rank \ 
$m$.

Further, for \ $P = a[x_1,\ldots,x_n]$, \ \ 
$M$ may have the gradings induced from $P$, and hence, 
the Gr\"obner bases induced by these gradings \cite{MoM}.

We keep in mind that the Gr\"obner bases in $M$ evaluate differently
depending on the way the pp ordering (or grading) is continued from \ 
{\tt cp} \ of $P$ \ to \ {\tt cpE} \ of $M$.

Different {\tt cpE} make isomorphic copies of $M$,  
but the isomorphism may not preserve the grading.



\subsubsection{ Vector . Pol \ and VecPol}
\label{sec-polv.i.vp} 

This additional algorithmic structure expresses as 
\footnotesize
\begin{verbatim}
  instance EuclideanRing a => LinSolvLModule (Pol  a) (Vector (Pol a))
  ...                         LinSolvLModule (Pol  a) (EPol a)
  ...                         LinSolvLModule (UPol a) (Vector (UPol a))
\end{verbatim}
\normalsize
For the \ \ {\tt Vector . Pol} \ \   
model of the free module  $M$, \ {\tt DoCon} puts the comparison (or grading) 
in  $M$  to be the so-called TOP (term over position) with the reverse
position.  This compares first the power products by  {\tt cp},  then,  
if equal, the reverse position numbers in the vectors.

But there exist other useful comparisons for $M$ --- see \cite{MoM}.
So, {\tt DoCon} introduces also
\begin{center}            {\tt  data VecPol a = VP [Pol a] EPPOTerm} 
\end{center}
which expresses the domain  $M$  isomorphic to  \ {\tt Vector (Pol a)},
but provides a field for the extended pp ordering (epp ordering) \ 
{\tt cpE}.

So, {\tt VecPol},  with its  {\tt cpE}  choice,  is an appropriate,  
flex model for the free module  $M$  over  $P = a[x_1,\ldots,x_n]$.
And  \ {\tt Vector . Pol} \ is a special case of  {\tt VecPol}.

Further, to compute the Gr\"obner bases, 
{\tt VecPol} uses the isomorphism to {\tt EPol}.



\subsubsection{ EPol }
\label{sec-polv.i.e} 

is one more representation for  {\tt VecPol}: \ 
a linear combination of the extended power products \ $m_i \cdot e_i$, \ \    
$m_i$ a monomial, \ $e_i$ \ canonical vector of i-th coordinate 
\cite{MoM}. \ 
The admissible comparison on \ $m_i \cdot e_i$ \ are as above, 
for {\tt VecPol}.

{\bf Example.}

Let \ {\tt V = EPol Z, \ \ ord = (("dlex",2), degLex, [])}
\\
and the extended comparison is \ {\tt ecp = eAntiLex:} 
\footnotesize
\begin{verbatim}
  eAntiLex (i,p) (j,q) = case degLex p q of EQ -> compare j i 
                                            r  -> r
\end{verbatim}
\normalsize

With this \ {\tt ecp} \ and \ \verb#eTerm = (ecp, "a", [], _)#, \ \ 
the vector \ \ {\tt V = ($ 5 x + 4, 5 x^2 y + 4 x, 4 y $)} \ \ 
(with coordinate No-s 1, 2, 3) 
\ \ 
corresponds to e-pol =
\footnotesize
\begin{verbatim}
  (2, 5*x^2*y) + (1, 5*x) + (2, 4*x) + (3, 4*y) + (1,4)  <-->
  EPol
      [(5, (2, Vec [2,1])), (5, (1, Vec [1,0])), (4, (2, Vec [1,0])),
       (4, (3, Vec [0,1])), (4, (1, Vec [0,0]))
      ]  eTerm  _ 
\end{verbatim}
\normalsize
That is the initial list \ {\tt fs :: [Vector P]} \ converts in this 
way to \ \verb#fe_s :: [EPol a].#

For \ \verb#fe_s#, \ there are defined the functions 

  \hspace{40mm} \verb#polNF_e, gBasis_e, polRelGens_e#,
\\
which generalize respectively the functions \ {\tt polNF, gBasis, polRelGens}
\\
to e-polynomials.

{\tt VecPol} \ is supplied with the same instances as {\tt EPol}, and  
applies the conversion to/from {\tt EPol} for the gx-operations.
The conversions
\footnotesize
\begin{verbatim}
               epolToVecPol :: ... Z -> EPol a -> Vector (Pol a)
               vecPolToEPol :: ... EPPOTerm -> Vector (Pol a) -> EPol a
\end{verbatim}
\normalsize
and the gx-module structure for \ {\tt EPol a} \   
bring the the gx-module structure to\\ 
\verb#Vector $ Pol a,  VecPol a#.
\medskip

{\bf Compute with {\tt VecPol} or with {\tt EPol} ?}

{\tt VecPol} looks better, more traditional, when parsed/unparsed.
But the programmer has to decide in each case,  whether  this  costs
the conversion to/from {\tt EPol} applied in each gx-operation.

{\bf Example:} \\
\verb#demotest/T_grbas2.hs# \ (function {\tt abya})\\
presents the computation of the generator lists \ {\tt rels, check}
(of different origin) for the syzygies in \ $P^5$ \ of the Abyankhar
curve equations \\
(Section~\ref{sec-pol.a.gr} Point \{ar\} Example 2).
Then, it tests, via {\tt gxBasisM}, that  \ {\tt rels}, {\tt check} \ 
generate the same submodule.




\subsection{ E-polynomial }
% -------------------------
\label{sec-polv.e} 

The e-polynomial items are exported by the module {\tt Pol},\\
and implemented in \verb#pol/EPol*, Pol2_#.


\subsubsection{ Various items for EPol }
% --------------------------------------
\label{sec-polv.e.i} 

\footnotesize
\begin{verbatim}
  type EPP = (Z, PowerProduct)       -- in the Extended power product  (i,pp)
                                     -- i = 1,2,... is the coordinate No
  type EPPComp = Comparison EPP

  ecpTOP_weights, ecpPOT_weights :: Bool -> [PowerProduct] -> PPComp -> EPPComp
                                  -- mode   weights           cp
\end{verbatim}
\normalsize
are the widely used EPP-comparisons induced by the  pp-comparison {\tt cp}  
and a list of weights \ $w_i$.

$w_i$ {\tt :: PowerProduct} \ \ is for the coordinate No $i$.

TOP stands for the ``term over position'', \ 
POT --- ``position over term''.
\\
TOP means to compare first the pp parts of the given \ $(i,p), \ (j,q)$ \ 
by \ \ {\tt cp} ($w_i+p$) ($w_j+q$), \ \ then, if equal, compare the 
positions.

POT means to compare first the positions. 

It is said this TOP/POT terminology is by W.Adams \& P.Loustaunau.

{\tt mode :: Bool} \ describes the comparison for the positions (integers),

  {\tt True} \ means \ {\tt compare} \ --- the straight order,

  {\tt False} \ --- \ {\tt flip compare} \ --- reverse order.
\medskip
  
{\bf Example:} 
\footnotesize
\begin{verbatim}
   ecpTOP_weights False [w1,w2,w3] degLex (3,p) (1,q) ==
                                         case degLex (w3+p) (w1+q) of EQ -> LT
                                                                      v  -> v
\end{verbatim}
\normalsize
%
Some items for epp orderings:
%
\footnotesize
\begin{verbatim}
  ecpTOP0 :: Bool -> PPComp -> EPPComp
             -- Specialization of ecpTOP_weights to zero weights.
             -- Compares first pp by cp, then, if equal, loks into position No.

  ecpTOP0 mode cp (i,p) (j,q) = case (cp p q, compare i j) 
                                of
                                  (EQ, v) -> if mode then v else antiComp v
                                  (v , _) -> v

  type EPPOTerm = (EPPComp, String, [PowerProduct], PPComp)
                   -- ecp   mode    wts             cp

  eppoECp     :: EPPOTerm -> EPPComp 
  eppoMode    :: EPPOTerm -> String
  eppoWeights :: EPPOTerm -> [PowerProduct]
  eppoCp      :: EPPOTerm -> PPComp

  eppoECp     = tuple41 
  eppoMode    = tuple42 
  eppoWeights = tuple43 
  eppoCp      = tuple44
\end{verbatim}
\normalsize
%
{\tt eterm = (ecp, mode, wts, cp)} \ \ describes the epp ordering. 

{\tt ecp} \ the epp comparison function, is the main part.

\verb#mode = 'a':_# \ \ 
means that {\tt ecp} agrees with the pp-ordering {\tt cp'} 
contained in the polynomial sample of e-polynomial:\\
{\tt cp'} \ and \ {\tt ecp} restricted to any fixed {\tt i} \ 
define the same ordering.

{\tt wts} \ \ 
is a list of weights, each related to its position in vector.
\\
{\tt wts = []} \ means the weights and {\tt cp} are ignored.\\
Other value means that {\tt ecp} is defined as the TOP or POT
comparison respectively to {\tt wts} and {\tt cp}.

{\tt mode = [aMode, tMode, dMode]}

{\tt aMode = 'a'} \ \ means {\tt ecp} agreed with the pp-ordering from 
                    the polynomial sample of e-polynomial.

{\tt tMode = 't'} \ \ means TOP comparison, other letter means POT comparison.

{\tt dMode = 'l'} \ \ means the less position No is considered as greater,
                      other letter means the reverse direction.
\medskip


{\tt Examples.} 
\\
\verb#(ecp, "", [], _, _)# \ \ 
               means no extra description for {\tt ecp} is given.
\\
{\tt (ecp, "atl", [w1,w2], degLex)} \ \
means the agreed TOP-degLex-(reverse-position) comparison \ \ 
\verb#ecpTOP_weights False [w1,w2] degLex#
\medskip

\footnotesize
\begin{verbatim}
  type EMon a = (a, EPP)
  data EPol a = EPol [EMon a] EPPOTerm (Pol a)
\end{verbatim}
\normalsize
{\tt EPol} \ is the indexed monomial-wise representation  for polynomial
             vector.

In \ {\tt EPol emons eterm pol} 

{\tt pol} \ \ is a sample polynomial, \ \ \ \verb#eterm = (ecp, _, _, _)#,

{\tt ecp} \ \ is an admissible extended power product comparison. 
\\
See Sections \ref{sec-polv.i}, \ref{sec-polv.i.e}.

\footnotesize
\begin{verbatim}
  instance Eq a => Eq (EPol a) where  f==g = (epolMons f)==(epolMons g)
  epolMons     :: EPol a -> [EMon a]
  epolEPPOTerm :: EPol a -> EPPOTerm
  epolPol      :: EPol a -> Pol a
  epolECp      :: EPol a -> EPPComp

  epolMons     (EPol ms _ _) = ms
  epolEPPOTerm (EPol _  t _) = t
  epolPol      (EPol _  _ p) = p 
  epolECp = eppoECp . epolEPPOTerm

  epolPPCp = polPPComp . epolPol    -- the one contained in polynomial sample

  eLm :: CommutativeRing a => EPol a -> EMon a  -- leading e-monomial
  eLm f = case epolMons f of m:_ -> m
                             _   -> error $ ("eLm 0 \nin  "++) $ showsDomOf f "\n"
  eLpp :: CommutativeRing a => EPol a -> EPP
  eLpp =  snd . eLm
  epolLCoord :: CommutativeRing a => EPol a -> Z    -- coordinate ("position") 
  epolLCoord =  fst . eLpp                          -- of leading monomial

  leastEMon :: CommutativeRing a => EPol a -> EMon a
  leastEMon f = case epolMons f 
                of
                  m:ms -> last (m:ms)
                  _    -> error $ ("leastEMon 0  \nin  "++) $ showsDomOf f "\n"

  zeroEPol :: EPPOTerm -> Pol a -> EPol a
  zeroEPol    t           f     =  EPol [] t f

  instance Dom EPol where  dom    = dom    . epolPol
                           sample = sample . epolPol

  instance AddGroup a => Cast (EPol a) (EMon a) 
    where
    cast mode (EPol _ t p) (a,e) = EPol mons t p
                         where
                         mons = if mode=='r' && isZero a  then []  else [(a,e)]

  instance AddGroup a => Cast (EPol a) [EMon a] 
    where
    cast mode (EPol _ cp p) mons = EPol ms cp p     -- order NOT checked
      where
      ms = if mode /= 'r' then mons  else filter ((/= z) . fst) mons
      z  = zeroS $ sample p

  instance PolLike EPol
    where
    varPs        = error (..."varPs (EPol..)  is senseless\n")
    pFromVec _ _ = error (..."pFromVec (EPol..) _  is senseless\n")
    pToVec   _ _ = error (..."pToVec _ (EPol..)  is senseless\n")
    pIsConst     = all (isZero . snd . snd) . epolMons
    pVars        = pVars   . epolPol
    pCoefs       = map fst . epolMons 
    lpp  = snd . eLpp           -- :: PowerProduct, in addition to eLpp
    pPPO = pPPO . epolPol       -- :: PPComp
    ldeg = sum . vecRepr . lpp 

    deg f = case  map (sum . vecRepr . snd . snd) $ epolMons f  of
                                                        [] -> error ("deg 0"..)
                                                        ds -> maximum ds
    pTail f = case epolMons f of _:ms -> ct f ms
                                 _    -> error ("pTail 0"...)
    pFreeCoef _    = error (..."pFreeCoef (EPol..)  is senseless\n")
    pCoef f (j:js) =  -- ... coefficient of  (j, Vec js)

    lm f = if null $ epolMons f then  error ("lm 0"...)
           else  
             case eLm f of (c,(_,p)) -> (c,p)   -- :: Mon a, in addition to eLm

    degInVar for0 i f = ... maximum [deg_i mon | mon <- unExtendedMonomialsOf_f]
    pMapCoef mode f g = cast mode g [(f a, e) | (a,e) <- epolMons g]

    pMapPP f g = ct g [(a, (j, Vec ks)) | (a, (i, Vec js)) <- epolMons g,
                                          let j:ks = f (i:js)
                      ]
    pCDiv f c = ... similar to Pol case.

    pDeriv  mInd  f@(EPol emons _ g) =  ctr f $ map monDeriv emons
                                           ...differentiate each e-monomial...
    pValue  _ _= error (.."pValue  (EPol..)..to be defined in future")
    pDivRem _ _= error (.."pDivRem (EPol..)..to be defined in future")

  reordEPol :: EPPOTerm -> EPol a -> EPol a      -- bring to given epp ordering
  reordEPol t (EPol ms _ pol) = case  eppoECp t  of

            ecp -> EPol (sortBy cmp ms) t pol   where cmp (_,p) (_,q) = ecp q p

  cToEMon :: [a] -> Z -> b -> EMon b
  cToEMon    xs     i    b =  (b, (i, Vec $ map (const 0) xs))

  cToEPol :: AddGroup a => EPol a -> Z -> a -> EPol a
                           --sample
  cToEPol (EPol _ t f) i a = if a==(zeroS a) then  EPol [] t f
                             else                  EPol [cToEMon (pVars f) i a] t f
  polToEPol :: Z -> EPPOTerm -> Pol a -> EPol a
                          -- embed polynomial to the e-polynomial of the given 
                          -- constant coordinate No i and epp ordering term
                          --
  polToEPol i o f = EPol [(c, (i,p)) | (c,p) <- polMons f] o f

                        -- the inverse operation is correct 
                        -- * when the polynomial power products do not repeat *
                        --
  epolToPol :: AddGroup a => EPol a -> Pol a
  epolToPol                  (EPol ms _ f) = ct f [(a,p) | (a, (_,p)) <- ms]

  instance CommutativeRing a => Show (EPol a)   
    where
    showsPrec _ (EPol ms _ f) = case [(i, ct f (a,p)) | (a, (i,p)) <- ms] of

                          indexedPols -> ("(EPol "++) . shows indexedPols . (" )"++)
  instance CommutativeRing a => Set (EPol a) where ...
    
  -- ... The instances up to  AddGroup  are evident.
  -- The addition is similar to `Pol' one.

  instance CommutativeRing a => Num (EPol a) where negate = neg
                                                   (+)    = add
                                                   (-)    = sub  
                                                   -- NO (*) 
                             -- EPol can be multiplied by Pol but not by EPol

  instance CommutativeRing a => LeftModule (Pol a) (EPol a)
    where
    cMul = polEPolMul
    baseLeftModule (_, EPol _ _ pol) fdom = ...

  instance EuclideanRing a => LinSolvLModule (Pol a) (EPol a)
    where
    canAssocM _ f = case (isZero f, inv $ canInv$ lc f) of
                         (True, _) -> f
                         (_   , c) -> if c==(unity c) then f  else  cPMul c f

    canInvM smp f = if isZero f then
                      error $ ("canInvM smp 0 \n"++) $ ("for  "++) $ showsDomOf f "\n"
                    else  ct smp $ canInv $ lc f
  
    gxBasisM     _                  = gBasis_e
    syzygyGensM  _                  = polRelGens_e
    moduloBasisM                    = ... via  polNF_e, gBasis_e
    baseLinSolvLModule (pol,_) fdom = ...

  emonMul :: Ring a =>  a -> Mon a -> EMon a -> [EMon a]
                        --zero 
  emonMul z (a,p) (b, (j,q)) = case mul a b of c -> 
                                            if c==z then [] else [(c, (j,p+q))]
  mEPolMul :: Ring a => Mon a -> EPol a -> EPol a
  mEPolMul (a,p) f =  ctr f [(a*b, (i, p+q)) | (b, (i,q)) <- epolMons f]

epolToVecPol :: CommutativeRing a =>   Z -> EPol a -> Vector (Pol a)
                                    -- n    f
\end{verbatim}
\normalsize
%
Convert e-polynomial {\tt f} to the polynomial vector \ 
{\tt Vec [$f_1,\ldots,f_n$]} \ of the given size 
\\ 
{\tt n} \ $\geq$ \ maximal coordinate No in {\tt f}.

It gathers the monomials of each coordinate to polynomial.

If {\tt f} does not contain monomials of i-th coordinate 
(for $1 \leq i \leq n$), then  $f_i = 0$.

{\bf Detail of method:} \\
the gathered monomials are being sorted --- unless the {\tt eppoMode} 
in {\tt f} starts with the `agreed' mode {\tt 'a'}.

{\bf Example:}
\footnotesize
\begin{verbatim}
  let  f   = EPol [(5, (2,x^2*y)), (5, (1,x)), (4, (2,x)), (1, (4,y)),
                   (4, (1, x^0*y^0))
                  ] eo  pol
       pol = cToPol o ["x","y"] 0  :: Pol Z
       o   = (("",2), degLex, [])
       eo  = (eAntiLex, "a", [], _)
  in   epolToVector 6 f     
                                       --> Vec [5*x+4, 5*x^2*y+4*x, 0, y, 0, 0]


  vecPolToEPol : CommutativeRing a => EPPOTerm -> Vector (Pol a) -> EPol a
                                      -- eo       Vec [f1 ..]
\end{verbatim}
\normalsize
Inverse to \ {\tt epolToVecPol}.\\ 
The monomials of each $f_i$ extend with the coordinate number i, 
are sorted under {\tt eo} (this is skipped if {\tt eo} shows `agreed'), 
and merged to the previously accumulated (eo-ordered) e-polynomial.

\footnotesize
\begin{verbatim}
  sEPol :: GCDRing a => EPol a -> EPol a -> Maybe (EPol a, Mon a, Mon a)
\end{verbatim}
\normalsize
{\tt sEPol f g} \ differs from \ {\tt sPol} \ in that it is in the 
{\tt Maybe} format and returns 

  {\tt Nothing} \ when the leading coordinates of {\tt f}, and 
                  {\tt g} differ,

  {\tt Just (s-epol, m1, m2)}, \ \ otherwise.


\footnotesize
\begin{verbatim}
  sEPol f g = if (epolLCoord f)/=(epolLCoord g) then  Nothing
              else
                let h         = epolPol f
                    (a,b)     = (lc f, lc g)
                    (_,m1,m2) = sPol (ct h (a, lpp f)) (ct h (b, lpp g))
                in  Just ((mEPolMul m1 f)+(mEPolMul m2 g), m1, m2) 

  type EPVecP a = (EPol a, [Pol a])                -- similar to PVecP

  mEPVecPMul m (f,v) = (mEPolMul m f, map (mPolMul m) v)

  sEPVecP :: GCDRing a => EPVecP a -> EPVecP a -> Maybe (EPVecP a, Mon a, Mon a)

  sEPVecP (f,v1) (g,v2) = case sEPol f g of          -- similar to sPVecP

    Nothing          -> Nothing
    Just (_, m1, m2) -> 
             let epdiff = (mEPolMul m1 f) - (mEPolMul m2 g)
                 vdiff  = zipWith (\s t -> (mPolMul m1 s)-(mPolMul m2 t)) v1 v2
             in  Just ((epdiff, vdiff), m1, m2)
\end{verbatim}
\normalsize



\subsubsection{ Gx-operations for EPol }
\label{sec-polv.e.gr} 

For {\tt EPol}, \ apply \ \ \ \ \ \ \ \ \ \ \ \ \
{\tt gxBasisM, syzygyGensM, moduloBasisM} 
\\
for the similar purpose as \ {\tt gxBasis, syzygyGens, moduloBasis} 
\\ 
are applied for {\tt Pol} (see first Section~\ref{sec-pol.a.gr}).

Here the 'M' operations are the analogies for the ones for vectors 
represented by {\tt EPol}.
\\
The implementation for this is in \ \verb#pol/GBas*.hs, PolNF_.hs, Polrel_.hs#.

\footnotesize
\begin{verbatim}
  polNF_e :: EuclideanRing a => String -> [EPol a] -> EPol a -> (EPol a, [Pol a])
\end{verbatim}
\normalsize
It differs from \ {\tt polNF} \ in that the power products are extended
and in that the condition \ ``{\tt (lpp $g_i$) divides (lpp f)}'' \ 
is enforced by with adding of\\
``and {\tt (eLpp $g_i$), (eLpp f)} have the same coordinate No''.

{\tt gxBasisM} \ for {\tt EPol} is defined via \ \verb#gBasis_e#
- see [MoM] and the comments in\\ 
\verb#GBasFld_.hs GBasEuc_.hs#,
 
By the way, the \ {\tt Pol} case is done via the generic {\tt EPol} case.
The main difference is that the s-e-polynomials are formed only  for
the items with the same leading coordinate.

Similar approach is for \ {\tt syzygyGensM} \ for {\tt EPol}.

{\bf Example:}\\
\verb#demotest/T_grbas2.hs# \  (function {\tt abya})
contains the computation of the generator lists \ {\tt rels, check} \ 
(of different origin) for the syzygies in \ $P^5$ \ of the Abyankhar
curve equations (Section~\ref{sec-pol.a.gr} Point \{ar\} Example 2).

Then, it tests, via {\tt gxBasisM}, that \ {\tt rels}, and {\tt check} 
generate the same submodule.


\underbar{On submodule resolvent}
\\
The gx-structure on \ $P^n, \ P$ \ a polynomial ring, is very important.
In particular, for the polynomials \ [$f_1,\ldots,f_n$], \ 
the syzygies \ [$r_1,\ldots,r_k$] \ are in  $P^n$.   
Then it is possible to find the g-bases and syzygies \ 
[$s_1,\ldots,s_l$] \ for \ [$r_1,\ldots,r_k$], \ $s_i \in P^k$. \ 
And so on. This gives us the resolvent of an ideal 
(or a submodule) resolvent. Choosing specially the term ordering
\cite{MoM} and the theorem on the Taylor syzygies, one also can avoid 
the intermediate g-bases computation.




\newpage
\section{ R-polynomial }
% ----------------------
\label{sec-rpol}  


\subsection{ Preface }
% --------------------
\label{sec-rpol.p} 


`Recursively' represented polynomials, with their constructor \ 
{\tt RPol}, \ are introduced to represent a totally sparse polynomial.
For example, it is in-efficient to represent \\
$ 2 x_1^3 x_{100}^4 + 1  \ \ \in \ a[x_1,\ldots,x_{100}] $ \ \
via \ {\tt Pol} --- that is by 
\\ 
{\tt [(2, [3,0,0,\ldots,0,4]), (1, [0,0,\ldots,0])]}. 

It is better to set the r-polynomial with the variable multiindex 
\ {\tt [i]} \ ranging in \\ 
{\tt [1 .. 100]}.

{\tt RPol} \ consists of the \ proper r-polynomial \ \ ({\tt RPol'}) \ \ 
and the \ description of the variable set and ordering.

It is considered as a polynomial in the (finite) set of variables
\\ 
$X = \{ x[multiindex] \ | \ \ldots \}$, \ \  
$X$ represented as rectangular in the space of multiindice.

The instances \ {\tt Set, \ldots, GCDRing} \ for {\tt RPol} \
are defined almost same as for {\tt Pol}.
Naturally, {\tt RPol} has the intance of \ {\tt PolLike} class.

The items for {\tt RPol} are exported by the module \ {\tt Pol},\\
implemented in \ \verb#RPol_.hs, RPol0_.hs#.



\subsection{ Examples }
% ---------------------
\label{sec-rpol.e} 

\underbar{Example 1}

1. Put the  r-variable set \ {\tt vs = \{x[i,j] | i <- [1..3], i <- [0..2]\}},
\\
ordered lex-increasingly;

2. Form  \ \verb#gr = x_1_1 + 2*x_3_0# \ of \ {\tt R = Z[\{vs\}]} \ 
   represented as {\tt RPol};

3. Convert {\tt gr} to {\tt g} of \ {\tt P = Z[\{vs\}]} \ represented as 
   {\tt Pol}

4. Test that {\tt g}$^2$ converted to {\tt RPol} equals {\tt gr}$^2$;

5. Find the number of variables set and list them.
%
\footnotesize
\begin{verbatim}
  import Pol ...
  ...
  type P = Pol  Z   -- for  Z[{vs}]
  type R = RPol Z   -- for  P  represented as RPol
  f =
    let  vcp         = flip (lexListComp compare) 
         ranges      = [(1,3), (0,2)]
         vt          = (vcp, "x", ranges)  
         (vn, rvars) = (rvarsVolum ranges, rvarsOfRanges ranges)
         o           = lexPPO vn
         r1          = cToRPol vt dZ 1                -- 1 of R 
         gr          = smParse r1 "x_1_1 + 2*x_3_0"
         g           = fromRPol o gr                 
         gp'         = toRPol 'l' vt rvars (g^2)
    in   (gr^2==gp', vn, rvars)
    -->
    (True, 9, [[1,0],[1,1],[1,2],[2,0],[2,1],[2,2],[3,0],[3,1],[3,2]])
\end{verbatim}
\normalsize
\bigskip


\underbar{Example 2}
\\
Here how {\tt DoCon} exploits {\tt RPol} for factoring in \ $k[x,y]$, \ 
$k$ a finite field.
To factor {\tt f} from \ $k[t][x]$, \ {\tt DoCon} builds the basis  
$B$ of certain lattice over $k[t]$, \ {\tt mB} being a 
triangular matrix over $k[t]$ (see the theory in \cite{Me3}).

Then, it has to find a vector \ $b = [b_1 \ldots]$ \ 
in this lattice with \ $\deg b_i < bound$ \ for each \ $i$ 
\\
(the {\tt DoCon} module \ \verb#Pfact2_# \ applies \ 
\verb#Pfact0_.smallInLattice_triang_# \ to do this).

This  $b$ is found by putting the linear equations  for  the  unknown 
coefficients  $u_{i,j}$  of polynomials  $u_i$  from $k[t]$: 
\ \
$ b = u \times B, \ \ u = [u_1,\ldots,u_m]$, \ \ $m =$ {\tt height} $B$.

It should hold \ \ $ \deg (u \times B)_i \ < \ bound $ \ for all $i$.
\\
And it is known a bound for \ $|u|$ : \ $ \deg u_i \ < boundU, $
\\
under which the needed \ $u \times B$ \ is found --- if such ever exists.
\\
This condition \ \ $ \deg (u \times B)_i \ < bound $ 
\ \ 
presents a linear system on unknown \ $u_{i,j} \in k$. \ 
The ring \ $U = k[u_{i,j} | \ldots]$ \ is built as represented by  
{\tt RPol}, where the polynomials \ 
$ u_i = \sum [u_{i,j} t^j | \ldots] $ 
\ \ 
are lifted to  $U[t]$  and make the vector \ $uVec$ \ over \ $U[t]$.

$ub = uVec \times B$ \ is again of {\tt Vector $U[t]$}, \ 
and the conditions \ $\deg ub_i < bound$ \ 
express as the equalities \ $c = 0$ \ for \ $c \in k[u_{i,j} \ldots]$ \ 
all the coefficients from \ $ub_i \in U[t]$ \ 
of monomials of  \ degree $\geq bound$. \ 
This list of r-polynomials $c$ is called \ {\tt eqs}, \ 
and it forms a matrix, with the rows represented sparsely, as the linear 
r-polynomials. For example,
\\
{\tt eqs =}  [ $ u_{1,2} + 3 u_{3,3} + 2 u_{3,8}, $
    
 \hspace{8mm}  $ 4 u_{1,2} + 3 u_{2,1} + 1, $

 \hspace{8mm}  \ldots ]
\\
Here $u_{i,j}$ are the unknowns.
Then the Gauss method \ {\tt linRPolsToStaircase} \ applies and 
converts it to the staircase form matrix {\tt eqs'}. \ And {\tt eqs'}
is solved as usual, by substituting the values for the free variables 
starting from the last equation. Here the matrix {\tt eqs} has the 
sparse rows --- represented by the linear r-polynomials, each 
variable corresponds to the position in the row.



\subsection{ Definitions }
% ------------------------
\label{sec-rpol.d} 

Here follows a more precise description of {\tt RPol} operations.

\footnotesize
\begin{verbatim}
  type RPolVar      = [Z]            -- r-pol variable is actually a multiindex
  type RPolVarComp  = Comparison RPolVar
  ...
  type RPolVarsTerm = (RPolVarComp, String, [(Z,Z)])
\end{verbatim}
\normalsize
%
{\tt (vcp, pref, ranges)} \ \   
presents the variable ordering \ {\tt vcp} \ and the variable set
description for \ {\tt [pref[$i_1,\ldots,i_n$] | \ldots]}. 
  
{\tt pref} \ \ is the prefix to print variable,

{\tt ranges = [($l_1, h_1),\ldots,(l_n, h_n)$]} \ \ 
contains the range \ $(l_k, h_k)$ \ for each variable index component: \ 
$l_k \leq i_k \leq h_k$

\footnotesize
\begin{verbatim}
  rvarsTermCp :: RPolVarsTerm -> RPolVarComp
  rvarsTermCp =  tuple31

  rvarsTermPref :: RPolVarsTerm -> String
  rvarsTermPref =  tuple32

  rvarsTermRanges :: RPolVarsTerm -> [(Z,Z)]
  rvarsTermRanges =  tuple33

  data RPol a = RPol (RPol' a) a RPolVarsTerm (Domains1 a)
\end{verbatim}
\normalsize
%
In \ {\tt f = RPol rpol' a vterm aDom}

{\tt a} \ is a sample coefficient,

{\tt vterm = (cp, pref, rgs)} \ \ 
variable comparison and full variable set description,

{\tt aDom} \ \ domain description for  \ {\tt a},

{\tt rpol' :: RPol' a} \ \ very representation.

{\tt f} \ is viewed as the element of \ {\tt a[XX]}, 

{\tt XX = [pref$_{ind}$ \ | \ $ind \in$ \ setDefinedBy-rgs]},

{\tt setDefinedBy-rgs = 
     [[$i_1,\ldots,i_n$] \ | \ for each $k \ \ l_k \leq i_k \leq h_k$]
}.
\medskip

{\bf Example:} \\ 
{\tt f = RPol rpol' 0 (cp, "y", [(0,2),(0,1)]) dZ} \ \ \ denotes some
\\ 
{\tt  f \  $\in \ Z[ y_{i,j} \ | \ i \in [0,2], j \in [0,1] ]$ }, \ \
what {\tt f} namely, this shows {\tt rpol'}.


\footnotesize
\begin{verbatim}
  data RPol' a =   CRP a                                 -- constant r-pol
                 | NRP RPolVar Z (RPol' a) (RPol' a)     -- non-constant
                 deriving (Eq, Show, Read)
\end{verbatim}
\normalsize

{\tt CRP a} \ \ means a constant R-polynomial,

{\tt NRP v n cf tl} \ \ 
means a non-constant R-polynomial \ $ cf \cdot v^n + tl, \ \ n > 0,$
\\   
$0 \neq cf$ \ {\tt :: RPol' a}, \ \ variables in  $cf$ are smaller than  
$v$, \\ 
$tl$ {\tt :: RPol' a}, \ \ variables in $tl$ are not greater than $v$, 
\ \ {\tt deg} $v \ tl \ < n$.

{\bf Example.}\\
If  $x_1 > x_2$ \ in a comparison  {\tt cp}, 

  $x1 \leftrightarrow [1], \ x2 \leftrightarrow [2]$, \ 
  {\tt varsTerm = (cp, "x", [(1,2)])}, 
\\ 
then \ $5 x_1^2 x_2^3 + x_1^2 + 6 x_1$ \ of $Z[x_1,x_2]$ \ \ converts to 
\\  
$ x_1^2 \cdot (5 x_2^3 + 1) + x_1 \cdot (6) \ \longrightarrow $ 
\footnotesize
\begin{verbatim}
   RPol (NRP [1] 2 (NRP [2] 3 (CRP 5) (CRP 1)) (NRP [1] 1 (CRP 6) (CRP 0))) 
        0 varsTerm dZ
\end{verbatim}
\normalsize

Furthger main definitions for {\tt RPol} are as follows.
\footnotesize
\begin{verbatim}
  rpolRepr :: RPol a -> RPol' a
  rpolRepr    (RPol f _ _ _) = f

  rpolVTerm :: RPol a -> RPolVarsTerm
  rpolVTerm    (RPol _ _ t _) = t

  rpolVComp :: RPol a -> RPolVarComp
  rpolVComp =  rvarsTermCp . rpolVTerm

  rpolVPrefix :: RPol a -> String 
  rpolVPrefix = rvarsTermPref . rpolVTerm

  rpolVRanges :: RPol a -> [(Z, Z)]
  rpolVRanges = rvarsTermRanges . rpolVTerm

  rp'HeadVar :: RPol' a -> Maybe RPolVar
  rp'HeadVar (NRP v _ _ _) = Just v
  rp'HeadVar _             = Nothing

  rpolHeadVar :: RPol a -> Maybe RPolVar
  rpolHeadVar = rp'HeadVar . rpolRepr

  -- rp'Vars f, rpolVars f
  -- yield only the variables  v(i,j)  on which  f  really depends.

  rp'Vars :: Char -> RPol' a -> [RPolVar]
    --       mode    f
    -- List variables, first - into depth, then to the right, 
    -- repetitions cancelled.
    -- mode = 'l'  means f is linear, in this case the computation is simpler.

  rpolVars :: Char -> RPol a -> [RPolVar]          
    --        mode    f   
    -- The result is ordered by comparison from f.
    -- mode = 'l'  means f is linear - in this case the computation is simpler.
    --
  rpolVars mode (RPol f _ t _) = case  (rp'Vars mode f, mode, rvarsTermCp t)
                                 of 
                                   (vs, 'o', cp) -> sortBy (flip cp) vs
                                   (vs, _  , _ ) -> vs
  instance Dom RPol' where  
                     dom _  = error ("no  dom  needed for RPol'" ...)

                     sample = sm  where  sm (CRP a)       = a
                                         sm (NRP _ _ c _) = sm c

  instance Dom RPol where  sample (RPol _ a _ _) =  a
                           dom    (RPol _ _ _ d) =  d

  instance Cast (RPol a) (RPol' a) where
                                   cast _ (RPol _ c t d) f = RPol f c t d
  instance Cast (RPol' a) a where cast _ _ a = CRP a
  instance Cast (RPol a) a  where 
                            cast _ (RPol _ c t d) a = RPol (CRP a) c t d

  rvarsVolum :: [(Z,Z)] -> Z
  rvarsVolum    []      =  error "rvarsVolum []\n"
  rvarsVolum    ranges  =  product [h-l+1 | (l,h) <- ranges]

  rvarsOfRanges :: [(Z,Z)] -> [RPolVar]
    --   
    -- All r-vars in the given ranges listed in the lexicographic-increasing order.
    -- Example:  rvarsOfRanges [(0,2),(3,4)] = [[0,3],[0,4],[1,3],[1,4],[2,3],[2,4]]
    -- CAUTION:  it may be very expensive, think before applying it.
  ------------------------------------------------------------------- 
  instance PolLike RPol'
    where
    pIsConst (CRP _) = True
    pIsConst _       = False

    pCoefs f = pc f []  where  pc (CRP a)         = (a:)
                               pc (NRP _ _ cf tl) = pc cf .pc tl
                                  -- coefficients listed "first in depth"
    pTail (CRP a)       = CRP a
    pTail (NRP _ _ _ t) = t

    pFreeCoef (CRP a)        = a
    pFreeCoef (NRP _ _ _ tl) = pFreeCoef tl

    ldeg (CRP _      ) = 0                  -- deg in leading variable
    ldeg (NRP _ n _ _) = n                  --

    deg = dg  where  dg (CRP _)       = 0                     -- sum of degs
                     dg (NRP _ n c t) = max (n+(dg c)) (dg t)

    degInVar _ n f = case genericIndex (rp'Vars '_' f) (n-1) of  

           v -> dg f  where  
                      dg (CRP _)       = 0
                      dg (NRP u n c t) = if u==v then n  else max (dg c) (dg t)

    pMapCoef 'r' f g = fmap f g      -- example of programming 
    pMapCoef _   f g = m g           -- with  RPol
      where
      z = zeroS $ head $ pCoefs g
      m (CRP a)       = CRP $ f a
      m (NRP v n c t) = case m c 
                        of
                          CRP b -> if b==z then m t  else NRP v n (CRP b) (m t)
                          c'    -> NRP v n c' (m t)
    pMapPP f = m  where
                  m (CRP a)       = CRP a
                  m (NRP v n c t) = NRP v (head $ f [n]) (m c) (m t)
                    -- CAUTION:
                    -- applying bad f may yield incorrect r-polynomial
    pCDiv f a =  ... 
    varPs a f = [NRP v 1 (CRP a) $ CRP $ zeroS a | v <- rp'Vars '_' f]

    -- lpp, lm, pDivRem  skipped
  --------------------------------------------------------------------
  instance Eq a => Eq (RPol a) where  f==g = (rpolRepr f)==(rpolRepr g)
  instance Functor RPol' 
    where  
    fmap f (CRP a)       = CRP (f a)
    fmap f (NRP v n c t) = NRP v n (fmap f c) (fmap f t)
      --
      -- When this  map f :: RPol a -> RPol b  yields correct polynomial?
      -- When  f c  is non-zero for all the coefficient r-pols  c
      -- in the given r-pol g.
  --------------------------------------------------------------------
  instance PolLike RPol
    where  
    pIsConst  = pIsConst  . rpolRepr
    ldeg      = ldeg      . rpolRepr  
    deg       = deg       . rpolRepr
    pCoefs    = pCoefs    . rpolRepr
    pFreeCoef = pFreeCoef . rpolRepr
    pTail f   = ct f $ pTail $   rpolRepr f
    pCDiv f   = fmap (ct f) . pCDiv (rpolRepr f)

    pMapCoef mode f g = ct g $ pMapCoef mode f $ rpolRepr g
    pMapPP f g        = ct g $ pMapPP f        $ rpolRepr g

    degInVar for0 i = degInVar for0 i . rpolRepr

    varPs  a  f@(RPol g _ t _) =  
                            let cp                              = rvarsTermCp t
                                cp' (NRP u _ _ _) (NRP v _ _ _) = cp u v
                            in  map (ct f) $ sortBy (flip cp') $ varPs a g

    pDivRem (RPol f a t _) g = case divrem_ (zeroS a) (rvarsTermCp t) f (rpolRepr g)
                               of
                                 (q,r) -> (ct g q, ct g r)
    -- lpp, lm  skipped

  cToRPol :: RPolVarsTerm -> Domains1 a -> a -> RPol a   -- coefficient to RPol
  cToRPol    t               dm            a =  RPol (CRP a) a t dm
    
  varToRPol' :: AddSemigroup a => a -> RPolVar -> RPol' a
  varToRPol' a v = NRP v 1 (CRP a) $ CRP $ zeroS a
                                                    -- variable to RPol', RPol
                                                    --
  varToRPol :: AddSemigroup a => RPol a -> a -> RPolVar -> RPol a
                              -- sample
  varToRPol f a v = ct f $ varToRPol' a v
  
  add_ :: AddSemigroup a => a -> RPolVarComp -> RPol' a -> RPol' a -> RPol' a 
                          --zero
    -- Auxiliary for (+).  Sum of r'-polynomials.
    -- We give it as an example programming with of RPol:

  add_ z cp f g = ad f g
    where
    ad (CRP a)         (CRP b)             = CRP $ add a b
    ad (NRP v n c t)   (CRP a)             = NRP v n c $ ad t (CRP a)
    ad (CRP a)         (NRP v n c t)       = NRP v n c $ ad t (CRP a)
    ad f@(NRP v n c t) g@(NRP v' n' c' t') =
      case 
          (cp v v', compare n n', ad c c', ad t t')
      of
        (GT, _ , _ , _ ) -> NRP v  n  c  (ad t  g)
        (LT, _ , _ , _ ) -> NRP v' n' c' (ad t' f)
        (_ , GT, _ , _ ) -> NRP v  n  c  (ad t  g)
        (_ , LT, _ , _ ) -> NRP v' n' c' (ad t' f)
        (_ , _ , c1, t1) -> if c1==(CRP z) then t1  else NRP v n c1 t1


 


  rHeadVarPol :: Set a => Domains1 (RPol a) -> RPol a -> UPol (RPol a)
                         -- rdom               r         rU
\end{verbatim}
\normalsize
Convert non-constant r-polynomial {\tt r} from $R$ to
univariate polynomial from $R[u]$, \ $u$ \ the leading variable of 
{\tt r}\\
({\tt rdom} \ can be set before, for example, via {\tt up..Ring}).
  
{\bf Caution:} \ coefficients of {\tt rU} have the same variable set as  
in {\tt r}.

\footnotesize
\begin{verbatim}
  rFromHeadVarPol :: AddSemigroup a => RPolVar -> UPol (RPol a) -> RPol a
                                       -- v     
\end{verbatim}
\normalsize
Inverse to {\tt rHeadVarPol}.

The leading variable is given in argument --- in order not to convert 
it from string nor to search in {\tt ranges}.

\footnotesize
\begin{verbatim}
  fromRPol :: CommutativeRing a => PPOrdTerm -> RPol a -> Pol a
                                   -- ord       rf
\end{verbatim}
\normalsize
Convert r-polynomial {\tt rf} to polynomial {\tt f}, \ 
{\tt f} \ is under the given pp ordering \ {\tt ord}.

The variable set for {\tt f} is described by \ {\tt rpolVTerm rf} :
  
{\tt vars =} 
[ $prefix_{i_1',\ldots,i_n'} \ | \ [i_1,\ldots,i_n] \in ranges$ ], \ \  
$i_k'$ = {\tt show} $i_k$.
  
The order in  {\tt vars}  is put so that last index in a multiindex \ 
[$i_1,\dots,i_n$] \ changes first.

{\bf Example:} \\  
if  \ \verb#rpolVTerm rf = (_, "u", [(0,2),(0,1)])#, \ \ then \ \
{\tt fromRPol rf} \ yields {\tt f} with the variable list \ \
\verb#["u_0_0", "u_0_1", "u_1_0", "u_1_1", "u_2_0", "u_2_1"]#.

{\bf Caution:} \ think before applying \ {\tt fromRPol} !
\\
This variable index expansion to the (dense) power product may be 
expensive.

\footnotesize
\begin{verbatim}
  toRPol' :: CommutativeRing a =>  Char -> [RPolVar] -> Pol a -> RPol' a
                                -- mode    rvars        f
\end{verbatim}
\normalsize
Convert a polynomial \ {\tt f } from \ $a[x_1,\ldots,x_n]$ \ to  
r-pol' {\tt rf}, \ with respect to the given bijective variable 
correspondence \ \ 
{\tt rvars =} $ [v_1,\ldots,v_n] \ \longleftrightarrow \ [x_1,\ldots,x_n] $
\ \ {\tt = pVars f},
\\
the variable order preserves.

{\tt mode = 'l'} \ \ means the pp order in {\tt f} is {\tt lexComp}, \ 
       in this case the computation is simpler, 

    other letter \ adds the cost of initial reordering of {\tt f}.

\footnotesize
\begin{verbatim}
  toRPol :: CommutativeRing a => Char -> RPolVarsTerm -> [RPolVar] -> Pol a -> RPol a
                                 -- mode vt              rvars        f        
\end{verbatim}
\normalsize
Convert a polynomial \ {\tt f} from \ $a[x_1,\ldots,x_n]$ \ to  
r-polynomial \ {\tt rf} \ with respect to the given r-variable set 
description {\tt vt} and the variable correspondence 
\\
{\tt rvars =} 
$ [v_1,ldots,v_n] \ \longleftrightarrow \ [x_1,ldots,x_n] $ \ 
{\tt = pVars f},

{\tt rvars} \ is the subset of \ {\tt set(vt)}.

{\bf Required:} \ $ v_1 > \ldots > v_n$ \ by the comparison from {\tt vt}.
  
{\tt mode = 'l'} \ means the pp order in {\tt f} is {\tt lexComp},  
                   in this case the computation is more direct, \ \
          other letter causes the initial reordering of {\tt f}.
\bigskip


\footnotesize
\begin{verbatim}
  substValsInRPol :: CommutativeRing a => Char -> [(RPolVar,a)] -> RPol a -> RPol a
                                        --mode    pairs            f
\end{verbatim}
\normalsize
Substitute \ $(v_1 = a_1), \dots, (v_n = a_n)$ \ into r-polynomial {\tt f}.

{\bf Required:} \ $v_1 > \ldots > v_n$ \ in the comparison from {\tt f}.

{\tt mode = 'l'} \ means linear {\tt f}, in this case the substitution 
                   is simpler.
  
{\bf Example:} \ {\tt subst 'l' [(y,2),(z,4)] (x + 3*y + 1) --> \ x + 7}


\footnotesize
\begin{verbatim}
  instance CommutativeRing a => Show (RPol a)
    where
    showsPrec _ f = showsSPPol' zr unm ord pref . rpol'ToSPPol' $ rpolRepr f
                         where
                         (pref, zr) = (rpolVPrefix f, zeroS $ sample f)
                         unm        = Just $ unity zr
                         ord        = isOrderedRing $ snd $ baseRing zr $ dom f
                  --
                  -- rpol'ToSPPol'  converts to polynomial with sparse exponent
                  -- (the one to be developed in future)
\end{verbatim}
\normalsize



\newpage
\section{ Constructor class Residue }
% -----------------------------------
\label{sec-res}  

It joins the residue ring and residue group constructors 
\begin{center}
                     {\tt ResidueE, ResidueG, ResidueI}.
\end{center}
All the residue items are exported by the module \ {\tt Residue},\\
implemented in  \ \verb#residue/*.hs#
\medskip

\underbar{Residue model choice}

For a residue ring \ {\tt a/I}, \ choose the \ {\tt ResidueE} \ model, 
if you know that \ {\tt a} \ is Euclidean.
This will make computations simpler and help to get more definite 
attributes for the residue.

\footnotesize
\begin{verbatim}
  class Residue r
    where
    resRepr   :: r a -> a                        -- extract representation
    resPIdeal :: r a -> PIRChinIdeal a   -- ideal the Euclidean residue is taken by
    resGDom :: r a -> (Subgroup a, Domains1 a)
                              -- - for the quotient group  a/gH.
                              -- It returns  (gH, dH),  gH a normal subgroup,
                              -- dH  domain bundle for gH (it contains gH too).

    resIDom :: r a -> (Ideal a, Domains1 a)      -- for generic residue ring
\end{verbatim}
\normalsize
%
Each of the latter three operations either has to be skipped or to 
yield the error break when applied to the residue of improper kind. 

{\bf Example:} \ \ 
for the residue class \ {\tt r} \ of \ 2 \ in \ {\tt Z/iI},  
\footnotesize
\begin{verbatim}
  resRepr r --> 2,  resPIdeal r --> iI,    resGDom r, resIDom r --> error ...


  ----------------------------------------------- extracting parts of residue
  resSubgroup :: Residue r => r a -> Subgroup a
  resSubgroup = fst . resGDom

  resSSDom :: Residue r => r a -> Domains1 a
  resSSDom =  snd . resGDom

  resIdeal :: Residue r => r a -> Ideal a
  resIdeal =  fst . resIDom

  resIIDom :: Residue r => r a -> Domains1 a
  resIIDom =  snd . resIDom
  ------------------------------------------------------------------
  instance (Residue r, Show a) => Show (r a) where  showsPrec _ = shows . resRepr
  instance (Residue r, Eq a) => Eq (r a) where  x==y = (resRepr x)==(resRepr y)
                             --
                             -- this relies on that  x  is canonically reduced
\end{verbatim}
\normalsize


\newpage
\subsection{ Preface to residue group, residue ring }
% ---------------------------------------------------
\label{sec-res.p} 


\underbar{Quotient group {\tt a/H}}
\\
is represented by the constructor \ {\tt ResidueG}. 
DoCon understands it only in the case of commutative additive 
group.
And the subgroup description for \ {\tt H}  has to contain a canonical  map
by  \ {\tt H}.
With this, the operations in  \ {\tt a/H} \  (type \ {\tt ResidueG a})
are defined in an evident way. See Section~\ref{sec-rsg}.

The quotient group is almost dummy in DoCon.
So far, it is provided only to show that  a  quotient  group  it  is
possible.
\bigskip

\underbar{Generic residue ring \ {\tt a/I}}
\\
is represented by  \ {\tt ResidueI}.
It needs a gx-ring ({\tt LinSolvRing}) \ {\tt a} \ and the ideal 
description \ {\tt iI. \ iI} \ has to contain a gx-basis \ {\tt gs}.
The operations in  \ {\tt a/I} \ are defined via the method like 
Gr\"obner basis. See (Section~\ref{sec-prp.alm} Residue ring), 
`Ideal', Sections \ref{sec-rsi}, \ref{sec-gx.r}.
\bigskip

\underbar{Special Euclidean residue ring \ {\tt a/I}}
\\
is represented by \ {\tt ResidueE}.
It needs the special \ {\tt PIRChinIdeal} \  representation for \ {\tt I}.
The access to the residue attributes are simpler than for \ {\tt ResidueI}.
This all brings more efficiency to this important special case.
Also ResidueE has it special instances for  \ {\tt Z/I, \ k[x]/I}.  
See Section~\ref{sec-rse}.
The principle of computation with \ {\tt ResidueE} \ is similar to the 
generic case. The Euclidean remainder is exploited similarly as the 
Gr\"obner normal form or \ {\tt moduloBasis}.  
Extended GCD --- as  the Gr\"obner basis with the transformation 
accumulation.





\section{ Residue ring of Euclidean ring }
% ----------------------------------------
\label{sec-rse}  


\subsection{ Preface }
% --------------------
\label{sec-rse.p} 

The \ {\tt ResidueE} \ items are exported from the module \ {\tt Residue}, 
\\ 
implemented in \ \verb#residue/ResEuc*_.hs, RsePol_.hs#.

The first example with \ {\tt ResidueE}  appears in this manual in\\
(Section \ref{sec-start.2} Fragment "arithmetics in R = Z/(b)"),
the manual contains many other examples with \ {\tt ResidueE},
as well as  \verb#demotest/T_*.hs#.

See first Section~\ref{sec-il.e} on \ {\tt PIRChinIdeal}, 
Section~\ref{sec-res} on the class \ {\tt Residue}.

The constructor for an Euclidean residue is
\begin{center}
           {\tt data ResidueE a = Rse a (PIRChinIdeal a) (Domains1 a)}  
\end{center}

{\tt Rse x iI aD} \ \ 
  denotes the residue in \ {\tt a/I} \ for an Euclidean ring \ {\tt a}.

Its components are as follows.

{\tt aD} \ \ is the bundle describing the base domain \ {\tt a}.

{\tt x} \ \ is a representative for a residue class by \ {\tt I}.

{\tt I} \ \ is given by its term \ {\tt iI}. 

      It contains the ideal base \ {\tt b = pirCIBase iI}.
\medskip

{\bf Required:} \ \ 
{\tt x} \ should be reduced canonically by \ {\tt b} : \ 
                                   {\tt x == (remEuc 'c' x b)}.

Usually, \ {\tt iI} \ is built by applying the function \ 
{\tt eucIdeal}.

\footnotesize
\begin{verbatim}
  instance EuclideanRing a => Cast (ResidueE a) a
    where
    cast 'r' (Rse _ iI d) a = Rse (remEuc 'c' a $ pirCIBase iI) iI d
    cast _   (Rse _ iI d) a = Rse a iI d
\end{verbatim}
\normalsize
This implemants the casting \ {\tt a -> a/I}.
    
{\tt mode = 'r'} \ \ forces canonical reduction by the ideal.

  any other mode \ wraps the representative ``as it is''.
\medskip

{\bf Use} the \ {\tt cast} operation \ (and {\tt ct, ctr}) \ 
to obtain new residues by sample.

\footnotesize
\begin{verbatim}
  instance Residue ResidueE
    where  
    resRepr   (Rse x _  _) = x
    resPIdeal (Rse _ iI _) = iI
    resGDom   _            = error (..."resGDom (Rse..)\n")
    resIDom   _            = error (..."resIDom (Rse..)\n")

  instance Dom ResidueE where  dom (Rse _ _ d) = d
                               sample          = resRepr

  isCorrectRse :: (EuclideanRing a) => ResidueE a -> Bool
  isCorrectRse (Rse x i _) = case  pirCIBase i  
                             of
                               b -> x == (remEuc 'c' x b)

  ifCorrectRse x y z = if isCorrectRse x then z  else y
\end{verbatim}
\normalsize



\subsection{Main instances for {\tt ResidueE}}
% --------------------------------------------
\label{sec-rse.in} 

They are \ \ 
  {\tt Set \ldots \ AddGroup \ldots \ MulMonoid, LinSolvRing},

  {\tt GCDRing, FactorizationRing, EuclideanRing, Field}.
\medskip

The last four of these instances are correct 
(and defined trivially) only for a prime ideal \ {\tt I} 
(in this case \ {\tt a/I} \ is a field).

To form a residue domain \ {\tt a/I} \ with any of above instances, 
one needs 

  (1) a c-Euclidean base ring on \ {\tt a} \  
  (see Section~\ref{sec-euc} DivRemCan, Section~\ref{sec-gx.r}),
  {\tt a} \ not a field,
  
  (2) a non-zero and non-unity ideal \ {\tt I}.

In DoCon, the condition (1) for \ {\tt a} \ expresses as \\
{\tt (Euclidean, Yes), (DivRemCan, Yes), (IsField, No)}.
\medskip

Example of operation setting in \ {\tt a/I} :
\footnotesize
\begin{verbatim}
  instance EuclideanRing a => AddSemigroup (ResidueE a)
    where
    zero_m r = Just $ ct  r $ zeroS $ resRepr r
    neg_m  r = Just $ ctr r $   neg $ resRepr r
    add    r = ctr r . add (resRepr r) . resRepr
    ...
\end{verbatim}
\normalsize
Here, for example, \ {\tt add} \ sums the representatives to \ 
{\tt s} \ and casts \ {\tt s} \ to residue 
(with reduction via the canonical Euclidean remainder).

In  \ {\tt MulSemigroup}, \ the inverse of \ {\tt r} \ in \ {\tt a/I} \  
is found via the extended GCD for \\ 
{\tt resRepr r, pirCIBase iI}.

The attributes of \ {\tt a/I} \ semigroups, ring, and so on,  
depend greatly on the attributes of \ {\tt I}, \ mainly on the 
factorization of its base. For example, if  \ {\tt I} \ 
contains the factorization  \ \verb#ft = [(_,1)]#, \ 
then I is prime;  \ \verb#(_:_)# \ --- not prime,  \ 
{\tt []} \ --- unknown primality;  and so on.

See \ \verb#residue/ResEuc*_.hs# \ for the implementation details.
\bigskip


\underbar{{\tt Random ResidueE}}
\medskip

{\tt DoCon} declares
\footnotesize
\begin{verbatim}
  instance (EuclideanRing a, Random a) => Random (ResidueE a)
    where
    randomR (l,h) g = (ctr l a, g')  where 
                                     (a,g') = randomR (resRepr l, resRepr h) g
\end{verbatim}
\normalsize
This means to make a random {\it representative } and {\it project}
it to the residue ring. See Section~\ref{sec-rnd}.



\subsection{LinSolvRing instance for ResidueE}
% --------------------------------------------
\label{sec-rse.l} 

It has to implement \ {\tt gxBasis, moduloBasis, syzygyGens} \  
for \ {\tt a/(b)}.

The specific here is that \ {\tt gxBasis} \ in  \ {\tt a} \ and in \ 
{\tt a/I} \ is either \ {\tt []} \ or \ {\tt [g]}.

For  \ {\tt a/I},  \ {\tt moduloBasis} \ does not depend on the mode:  
it does the canonic reduction and needs intermediate implicit \ 
{\tt gxBasis} \ application.

{\tt gxBasis} for such a residue ring is defined as follows:
\footnotesize
\begin{verbatim}
  gxBasis [] = ([],[])
  gxBasis rs = let r            = head rs
                   b            = pirCIBase $ resPIdeal r
                   ([g], [row]) = gxBasis ((map resRepr rs)++[b])
               in
               if divides b g then ([],[])
               else                ([ctr r g], [map (ctr r) $ init row])
\end{verbatim}
\normalsize
Here \ {\tt gxBasis ((map resRepr rs)++[b])} \ is computed in an  
Euclidean \ {\tt a}. \ It is done there by the Gauss reduction of 
the \ $n \times 1$ \ matrix to the staircase form --- this is 
equivalent to the extended  gcd.

{\tt moduloBasis} for Euclidean residue:
\footnotesize
\begin{verbatim}
  moduloBasis _ [] r = (r, [])
  moduloBasis _ rs r = let (b, xs)  = (pirCIBase $ resPIdeal r, map resRepr rs)
                           (rm, qs) = moduloBasis "c" (xs++[b]) $ resRepr r
                       in  (ctr r rm, map (ctr r) $ init qs)

  syzygyGens _ rs = let r        = head rs
                        b        = pirCIBase $ resPIdeal r
                        zr       = zeroS b
                        canRem x = remEuc 'c' x b
                        rels'    = syzygyGens "" (b:(map resRepr rs))
                        rls'     = mapmap canRem rels'
                        rels''   = filter (not . all (== zr)) $ map tail rls'
                    in  mapmap (ct r) rels''
\end{verbatim}
\normalsize



\subsection{ Specialization to Z, k[x] }
% --------------------------------------
\label{sec-rse.s} 


{\tt DoCon} also provides special definitions for some instances for 
\\  
{\tt ResidueE Z} \ \ (for \ {\tt Z/I}), \ \ \ \
{\tt Field k => ResidueE (UPol k)} \ \ (for \ {\tt k[x]/I}).

They \ {\it overlap} with the generic instances. They help 
to obtain more definite domain attributes and sometimes define 
simpler operations. For example, the operation {\tt (+)} in \ 
{\tt k[x]/I} \ does not need the reduction by \ {\tt I} after 
summing representatives.




\section{ Quotient group ResidueG }
% ---------------------------------
\label{sec-rsg}  


So far, this is only for a \ {\it commutative additive group}.

A group residue (element of a quotient group \ {\tt a/H}) \ 
is represented as
\begin{center}     {\tt  Rsg x (gH,dH) dm \ :: ResidueG a }
\end{center}
This expression has sense if 

 (1) \ a subgroup term \ {\tt gH} \ contains a canonical map \ 
    {\tt canr} \ by \ {\tt gH} : 

    {\tt subgrCanonic gH --> Just canr},
\medskip

 (2) \ {\tt (canr x) == x}, \ 
       that is \ {\tt x} \ is reduced by the subgroup,
\medskip

 (3) \ {\tt dm} \ is the base domain description (bundle) for \ {\tt a} 

     and \ {\tt dH} \ is such bundle for the subgroup \ {\tt gH}. 
\medskip

The base set of the \ {\tt ResidueG a} \ sample is parameterized by the 
subgroup term \ {\tt gH} \ --- see the \ {\tt Set} instance below.
Thus, the subgroups \ \verb#gZ3 = (3*Z)# \ \ and \ 
\verb#gZ5 = (4*Z)# \ \ in \ {\tt Z} \ \ 
produce different base sets in \ {\tt ResidueG Z} :

  \verb#r1 = Rsg 2 (gZ3,_) _# \ \ and \ \ \verb#r2 = Rsg 2 (gZ4,_) _#,

have the same type \ {\tt ResidueG Z},  
but mathematically, belong to different domains.   

And {\tt DoCon} can discover that they have different base sets. 
For example,
\footnotesize
\begin{verbatim}
  let {s1 = snd $ baseSet r1 _;  s2 = snd $ baseSet r2 _}
  in  (osetCard s1, osetCard s2)
\end{verbatim}
\normalsize
yields \ {\tt (3, 4)}.

{\tt DoCon} is \ {\it not safe} \ against mixing the residues by different 
subgroups. Thus,\\
\verb#(Rsg 2 (gZ3,_) _) + (Rsg 2 (gZ4,_) _)# \ \
may cause an incorrect result.

\footnotesize
\begin{verbatim}
  data ResidueG a = Rsg a (Subgroup a, Domains1 a) (Domains1 a)

  isCorrectRsg :: AddGroup a => ResidueG a -> Bool
  isCorrectRsg                  r@(Rsg x d _) = 
    case subgrCanonic $ fst d 
    of
      Just can -> x==(can x)
      Nothing  -> error $ ("isCorrectRsg r,"++) $
                          showsWithDom r "r" "" ('\n':messgCanMap)
 
  messgCanMap = "\nCanonical map modulo subgroup not found\n"



  instance Cast (ResidueG a) a
    where
    cast mode (Rsg _ gdom d) a = case (mode=='r', subgrCanonic $ fst gdom) 
                                 of
                                   (False, _      ) -> Rsg a      gdom d
                                   (_    , Just cn) -> Rsg (cn a) gdom d
                                   _                -> error (...++messgCanMap)

  instance Dom ResidueG where  dom (Rsg _ _ d) = d
                               sample          = resRepr
  instance Residue ResidueG
    where
    resRepr   (Rsg x _ _) = x
    resGDom   (Rsg _ d _) = d
    resIDom   _           = error (..."resIDom (Rsg..)  is senseless")
    resPIdeal _           = error (..."resPIdeal (Rsg..)...         ")
\end{verbatim}
\normalsize
%
Then, the instances \ {\tt Set \ldots \ AddGroup} \ \  
are defined for \ {\tt A/H}, \ \ {\tt A} \ a base additive group,\\ 
{\tt H} \ a non-trivial subgroup in  \ {\tt A}.

See the implementation notes in \ \verb#residue/QuotGr_.hs#

The idea of computing in the quotient group  \ {\tt A/H} \ is simple.
For example, for \ {\tt x + y}, 

  (1) \ find \ {\tt z = (resRepr x)+(resRepr y)} \ in \ {\tt A}, 

  (2) \ reduce \ {\tt z} \ with the canonical reduction extracted 
      from  \ {\tt H}.

\footnotesize
\begin{verbatim}
  instance (AddGroup a, Random a) => Random (ResidueG a)
    where
    randomR (l,h) g = (ctr l a, g') where
                                    (a, g') = randomR (resRepr l, resRepr h) g
\end{verbatim}
\normalsize
--- make a random representative and project it to the quotient group. 

    


\newpage
\section{ Generic residue ring ResidueI }
% ---------------------------------------
\label{sec-rsi}  


\subsection{ Preface }
% --------------------
\label{sec-rsi.p} 

It is exported by the module \ {\tt Residue},\\
implemented in \ \verb#residue/ResRing*, ResPol_.hs#.

For the residues \ {\tt Rsi x (iI, d) dm \ :: ResidueI R}, \ \ 
\verb#R = baseRing x _#, 
\\
the instances up to \ {\tt LinSolvRing} \ require 

  a gx-ring \ {\tt R} \ \ ({\tt (IsGxRing, Yes)}) 

  and the generators for \ {\tt iI} \ possessing the property \ 
  {\tt (IsGxBasis, Yes)}.

And the instances of \ 
{\tt GCDRing, FactorizationRing, EuclideanRing, Field}
\\
are correct (and trivial) only for \ {\tt R/I} \ being a field,  
that is \ {\tt iI} \ possessing\\ 
{\tt (IsMaxIdeal, Yes)}.
\medskip

A generic residue data type is declared as
\begin{center}
   {\tt data ResidueI a = Rsi a (Ideal a, Domains1 a) (Domains1 a)} 
\end{center}
A residue element from \ {\tt a/I} \ for a gx-ring \ {\tt a} \ 
is 
\begin{center}    {\tt Rsi x (iI, iD) aD}
\end{center}
Here

  {\tt aD} \ \ is a bundle describing the base domain \ {\tt a},

  {\tt x} \ \ is a representative for a residue class by \ {\tt I},

  {\tt iD} \ \ is a bundle of sub-domain of the ideal \ {\tt I} \ in \ 
            {\tt a},

  {\tt iI} \ \ is the description of the ideal \ {\tt I}, 

     {\tt iI} \ contains its gx-generators \ 
                                  {\tt gs = fromJust \$ idealGens iI}.

{\bf Required:}\\
{\tt x} \ should be reduced canonically by \ {\tt gs} : \
                             {\tt x == (fst \$ moduloBasis "cg" gs x)}

Usually, the ideal description \ {\tt (iD,iI)} \ is built by appying 
the function \ {\tt gensToIdeal}.

Here follows the sketch for the beginning of implementation. 

\footnotesize
\begin{verbatim}
  ...
  instance Dom ResidueI where  dom (Rsi _ _ d) = d
                               sample          = resRepr

  instance Residue ResidueI
    where
    resRepr   (Rsi x _ _) = x
    resIDom   (Rsi _ d _) = d
    resGDom   _           = error (.."resGDom (Rsi..)   is senseless")
    resPIdeal _           = error (.."resPIdeal (Rsi..) ...         ")

  reduceCanG :: LinSolvRing a => [a] -> a -> a                -- LOCAL
  reduceCanG                     gs  =  fst . moduloBasis "cg" gs

  isCorrectRsi :: LinSolvRing a => ResidueI a -> Bool
  isCorrectRsi                     (Rsi x (iI, _) _) =
    case (idealGens iI, idealGenProps iI) 
    of  
      (Nothing, _    ) -> False
      (Just gs, props) -> case lookup IsGxBasis props of
                                               Just Yes -> x==(reduceCanG gs x)
                                               _        -> False

  instance LinSolvRing a => Cast (ResidueI a) a
    where
    cast mode (Rsi _ (iI, dg) d) a = case (mode=='r', idealGens iI) of

                  (False, _      ) -> Rsi a (iI, dg) d
                  (_    , Just gs) -> Rsi (reduceCanG gs a) (iI, dg) d
                  _                -> error (..."cast _ (Rsi..)" ...++msgNoBas)

  instance (LinSolvRing a, Random a) => Random (ResidueI a)
    where
    randomR (l,h) g = (ctr l a, g') where
                                    (a, g') = randomR (resRepr l, resRepr h) g
            -- make a random representative and project it to the residue ring
\end{verbatim}
\normalsize
%
The operations for \ \ {\tt ResidueI a} \ \ are defined similar as 
for \ \ {\tt ResidueE a}, \ \ only the reduction by gx-basis  
is applied instead of Euclidean remainder.

The operation 

  \verb#divide_m (Rsi x (iI,_) _) (Rsi y _ _)#, \ \ \ {\tt x, y :: a},
\\
requires a non-trivial interaction between \ {\tt gxBasis} \ 
and \ {\tt moduloBasis} \ in \ {\tt a}.
Here \ {\tt gxBasis} is used as the generalization of the extended 
gcd of Euclidean ring.
See Section~\ref{sec-gx}, and the module \ \verb#residue/ResRing*_.hs# \  
for details.



\subsection{ Specialization \ ResidueI . Pol }
% --------------------------------------------
\label{sec-rsi.s} 

{\tt DoCon} defines several special instances for the type
\begin{center}
               {\tt EuclideanRing a => ResidueI (Pol a)}
\end{center}
which {\it overlap} with the generic instances for \ \ 
{\tt LinSolvRing b => ResidueI b} \ \
and describe a residue ring \ {\tt Q = a[$x_1,\ldots,x_n$]/I} \ \
in the case of a c-Euclidean factorization ring \ {\tt a}.

This specialization concerns the instances \ {\tt Set \ldots \ Ring}.

The attributes for {\tt Q} are computed more definitely than in the 
generic case and --- following the below principles.
\medskip

\underbar{Theoretic Prelude}
\medskip

{\bf Denotations.}

{\tt rC} \ \ denotes the coefficient ring.

{\tt R = rC[$x_1,\ldots,x_n$]} \ \ polynomial ring over \ {\tt rC}.
\medskip

{\tt I = Ideal(gs)} \ \     
  a non-trivial ideal in \ {\tt R, \ \ gs} \ 
  a reduced Gr\"obner basis \cite{Mo}.

  And {\tt DoCon} builds  \ {\tt gs} \ so that it contains not more than one 
  constant polynomial, and if it contains such a constant \ {\tt g0},
  then \ {\tt g0} \ is in the head: \ \verb#gs = g0:_#.

  If  \ {\tt gs}  does not contain a constant, {\tt DoCon} puts \ {\tt g0 = 0}.
\medskip

{\tt Q = R/I} \ \ a polynomial residue ring --- the goal.

{\tt cI = Ideal(c0,rC)} \ \  
       restriction ideal of \ {\tt I} \ to \ {\tt rC, \ c0 = lc(g0)} \ 
      is not invertible.

{\tt rC' = rC/cI \ =isomorphic= \ rC/(c0)},
\medskip

{\bf Lemma:}\\ 
{\tt rC'} \ \ is a field \ $\Longleftrightarrow$ \ \ 
  ({\tt rC} is a field \ \& \ {\tt c0 = 0}) \ Or \ {\tt c0} is prime.
\medskip
  
{\tt rC'} \ embeds injectively and naturally into {\tt Q}, 
and {\tt Q} is naturally a module over \ {\tt rC'}.
\medskip

\verb#canRed = (\f -> moduloBasis "cg" gs f)# \ \   
         is a canonical reduction modulo \ {\tt I} \\ 
(mind that \ {\tt rC} is c-Euclidean),
it is extracted from the {\it quotient group}.
\medskip

`Under' power product \ is the one that is not multiple of any \ 
{\tt lpp(g), \ \ g} \ from \ {\tt gs}.

UPP = \ set of all `under' power products for \ {\tt gs}.

{\bf Lemma.} \\ 
UPP is finite \ if and only if 

  for each \ $x_i \in$ \ {\tt vars} \ there exists \  
  {\tt g $\in$ gs} \ such that \ 
  {\tt lpp g} = $x_i^k$, \ with some \ $k > 0$.
\medskip

For \ {\tt Q = rC[$x_1,\ldots,x_n$]/I}, \ 
the main {\tt DoCon} effort is to find the following attributes.

(Card) \ Cardinality.

(FldIn) \ Whether {\tt Q} contains a field inside.

(DimP) \ If {\tt Q} does contain a field, than what is \  
         {\tt DimOverPrimeField} \ for {\tt Q}.
\medskip

DoCon solves this boldly, as follows.
\medskip

{\bf Case (0)} \ \ {\tt c0 = 0, \ rC} \ is not a field.
\medskip

Example: \ $Z[x,y] / (x^2-1, y^2-x)$

{\tt Q} contains \ {\tt rC = Z} \ and is an algebra over \ 
{\tt rC. \ \ card(Q) = Infinity},\\ 
(DimP) \ not defined.
\medskip

{\bf Case (g0NP)} \ \ {\tt c0 $\neq$ 0} \ and not prime.
\medskip

Example: \ $Z[x,y] / (4, x^2+2, y^3+1)$

To solve the primality of \ {\tt c0}, \ {\tt DoCon} first sees \ 
\verb#(Prime, _)# \ for \ {\tt I}, \ then the factorization list 
--- if the latter presents in \ {\tt I}.  

Then, if it is still not defined, applies \ {\tt isPrime c0}.  \\
This  \ {\tt isPrime} \ is the only item from \ 
{\tt (FactorizationRing a)} \ which is really used.
\\
Here  \ \ {\tt Q = rC'[$x_1,\ldots,x_n$]/I', \ \ I' = Ideal(g's)},

$g_i$' \ is \ $g_i$ \ with the coefficients represented as the 
  residues modulo \ {\tt g0}.
%
\footnotesize
\begin{verbatim}
  card(Q) = if  infinite rC' Or infinite UPP  then  Infinity
            else                                    Nothing
  DimOverPrimeField =
    if  rC' contains a prime field  And  infinite DimOverPrimeField(rC')
         then  Infinity
    else       Nothing   
\end{verbatim}
\normalsize
%
More advanced solutions remain for the future.
\bigskip


{\bf Case (g0P)} \ \ {\tt c0} is prime  Or \ \ 
             ({\tt c0 = 0} \& \ {\tt rC} is a field)
\medskip

Examples: 

  $Z[x] / (5, x^2+2)$ \ =isomorphic= \ $GF(5)[x]/(x^2+2)$ \ 
                                        =isomorphic= \ $GF(25)$,

  $Rational[x,y] / (x^2-2, y^2+3)$.


Here \ {\tt rC'} is a field embedded into {\tt Q}.
\\
As before, \ {\tt Q = rC'[$x_1,\ldots,x_n$]/I', \ I'= Ideal(g's)},
\\
and here \ {\tt g's} \ is a Gr\"obner basis over the field \ {\tt rC'}.

{\tt Q} is an algebra over the field \ {\tt rC'}, \ \ 
UPP \ is its vector space basis,
\medskip

{\tt dim(Q, rC') = |UPP|}, \ \ \ \verb#card(Q) = card(rC')^|UPP|#

{\tt card(rC')} \ is determined by the \ {\tt ResidueE} \ constructor 
     applied to \ {\tt rC/(c0)}.

{\tt DimOverPrimeField(Q) = DimOverPrimeField(rC')*|UPP|} 




\subsection{ Application examples for generic residue ring }
% ----------------------------------------------------------
\label{sec-rsi.ex} 


\subsubsection{ Computing in algebraic extension of \ $i, \root 3 \of 2$}
\label{sec-rsi.ex.a} 


(1) \ Extend the rational number field \ {\tt Q} \ to the field \ 
{\tt K} \ generated by the \\
square root \ {\tt i} \ of \ {\tt -1} \ \ 
and cubic root \ {\tt r} \ of \ {\tt 2};
\\
(2) \ find \ {\tt qt = 1/(i+r)} \ in \ {\tt K};
\\
(3) \ form some matrix \ {\tt M} over \ {\tt K} and find its reverse \ 
{\tt M'};
\\
(4) \ test \ {\tt (i+r)*qt = 1, \ \ M*M' = unityMatrx};
\\
(5) \ print these results.
\medskip

This is done mainly by 

(1) introducing polynomials \ {\tt i', r'} \ from \ 
{\tt P = Q[i,r]}, 

(2) setting the equations \ {\tt eqs} \ for \ {\tt i',r'} \ 
--- square and cubic respectively,

(3) creating the residue \ \verb#Rsi _ iI dP# \ belonging to \ 
    {\tt K = P/Ideal(eqs)} :
\bigskip

{\footnotesize
\begin{verbatim}
  import qualified Data.Map as Map (empty)
  import DPrelude (PropValue(..), Z, ct)
  import Categs     
  import SetGroup (zeroS)
  import RingModule 
  import VecMatr  (Matrix(..), scalarMt)
  import LinAlg   (inverseMatr_euc     )
  import Fraction (Fraction(..)        )
  import Pol        
  import Residue    

  type Q = Fraction Z
  type P = Pol Q         -- for  P = Q[i,r]

  main =
    let q1            = 1:/1 :: Q
        dQ            = upField q1 Map.empty
        vars          = ["i", "r"]
        p1            = cToPol (lexPPO 2) vars dQ q1   -- 1        of P
        ([i',r'], p2) = (varPs q1 p1, fromi p1 2)      -- i, r, 2  in P
        dP            = upGCDLinSolvRing p1 Map.empty

        ---                                      forming description of ideal 
        eqs      = [i'^2 + p1, r'^3 - p2]               -- equations for i, r
        (iD,iI)  = gensToIdeal eqs [] propsGen propsI dP Map.empty
        propsGen = [(IsGxBasis, Yes)]
        propsI   = [(IsMaxIdeal,Yes)]
        ---
        k1       = Rsi p1 (iI,iD) dP      -- 1     of K
        [i,r]    = map (ct k1) [i',r']    -- i, r  in K
        qt       = k1 / (i+r)
        qtTest   = (i+r)*qt == k1
        mM       = [[i+r,    i-r^3],
                    [r^2-k1, i*r  ]]
        mM'      = inverseMatr_euc mM
        unityMt  = Mt (scalarMt mM k1 $ zeroS k1) Map.empty
        mTest    = (Mt mM Map.empty)*(Mt mM' Map.empty) == unityMt
    in
    putStr $ concat [shows qt "\n\n", 
                     shows (Mt mM' Map.empty) "\n\n", 
                     shows (qtTest, mTest) "\n"]
\end{verbatim}
}
%
The property value \ {\tt (IsMaxIdeal, Yes)} \ 
is an important hint for DoCon; it would then understand easily that \ 
{\tt K = P/I} \ is a field.

{\tt propsGen = [(IsGxBasis,Yes)]} 
\\  
is also necessary here, this tells to {\tt DoCon} that the generators are
ready to present canonical reduction by {\tt I}.
In our case, \ \ {\tt [i'$^2$ + p1, r'$^3$ - p2]} \ \ is, evidently, 
a Gr\"obner basis, hence, it is correct to set {\tt (IsGxBasis, Yes)}.

Without this information, we might have to apply the functions \ 
{\tt isGBasis, gxBasis}. 
      

  

\subsubsection{ Cyclic integers }
\label{sec-rsi.ex.c} 
 
The so-called cyclic integers were studied first in 19-th century by 
E.Kummer.
We may view them simply as residues of integer polynomials, 
the elements of domain \ $CI = Z[x]/(g)$,
$$
g = \sum_{i = 0}^{p'} x^i, \ \ \ \ p' = p-1, \ \ p \ {\mbox a \ prime}.
$$
As we see, \ \ $g = (x^p - 1)/(x-1)$, \ \ and it is also known that $g$ 
is irreducible.

Concerning the arithmetic in $CI$, the book (\cite{Ed} Section 4.2)
describes, for example, certain special division procedure. 

As to DoCon, it simply applies the constructor composition
\begin{center}
                {\tt ResidueI \$ UPol Z}, 
\end{center}
with its underlaying technique of Gr\"obner bases over an Euclidean
ring. Under these circumstances, \ {\tt gBasis} does not cost too much, 
it is almost like pseudodivision in $Z[x]$.

See the program in \ \verb#demotest/T_grbas2.hs#, \ and \ 
{\tt cyclInt} \ sub-function.
This demonstration computes some \ {\it norms} \ and quotients in this
integral domain \ $CI$.




\subsubsection{ Cardano cubic extension }
\label{sec-rsi.ex.ca} 
 
See first Section~\ref{sec-prp.ex}. Then, \ \verb#demotest/T_cubeext.hs#.
\\
The latter presents the function \ {\tt cubicExt} \ which forms a
residue ring \ {\tt B/I} \ by the ideal generated by Cardano radical
expressions.




\newpage
\section{ Symmetric function package }
% ------------------------------------
\label{sec-symmf}  


\subsection{ Introduction }
% -------------------------
\label{sec-symmf.i} 

The symmetric functions are implemented to the extent of the first
seven paragraphs of the widely known book \cite{Ma}.

The items related to symmetric functions are exported from the modules\\ 
{\tt Partition, AlgSymmF},
\\
implemented in \ {\tt Partition.hs, AlgSymmF.hs}, \verb#pol/symmfunc/*.hs#

First, a couple of the general notices concerning {\tt DoCon} approach to the 
subject. 

By a symmetric function we mean here something like a power series
of the infinite set of variables \ $x_1, x_2$, \ldots \ --- see 
\cite{Ma}. For example, the second elementary symmetric function \ 
$e_2$ \ is  
$$                  \sum_{i,j \geq 1} x_i x_j 
$$
Restricting it to any finite list of variables, we obtain really a
symmetric polynomial.

Since a symmetric polynomial contains usually many monomials that
are the permutations of each other, {\tt DoCon} introduces specially a \ 
Symmetric Polynomial\\ 
(sym-polynomial) \ data, \ with the \ {\tt SymPol} \ constructor).

This is done for the needs of efficiency and also for providing a
finite representation for symmetric function. Thus, the mentioned 
above \ $e_2$ \ is represented as the sym-polynomial \ 
$1 \cdot m_{1,1}$ \ (single sym-monomial).

A sym-polynomial is a linear combination of 
{\it monomial symmetric functions} \ (MSF) \ $m_{\lambda}$ \ 
--- see \cite{Ma}.  
It is some linear combination of \ {\it partitions} \ (Young diagrams).

Not only the elementary symmetric decomposition (to \ $e_{\lambda}$)
is presented, but generally, the $R$-module isomorphisms are given for 
the most usable linear bases 
$$  
 m_{\lambda}, \ p_{\lambda}, \ s_{\lambda}, \ e_{\lambda}, \ h_{\lambda} 
$$
in the symmetric function algebra ($SymA$) over a commutative ring \ 
$R$, \ as it is shown in \cite{Ma}. Here $\lambda$ denotes a partition.

This requires various operations for the {\it partitions}, they may
also occur useful by themself.

And the central point is auxiliary functions for computing of the 
Kostka numbers for the partitions and {\it irreducible characters}  
for the permutation group. To compute the Kostka numbers and the above 
characters we apply forming of the so-called {\it horizontal bands}  
and {\it skew hooks} \ (\cite{Ma}). 
For these data we also provide certain operational minimum.

The partitions in the sym-polynomial are ordered decreasingly by the
given {\it partition comparison function}; this latter is an attribute 
contained in a sym-polynomial data.

The conversion between \ {\tt Pol a} \ \ and \ \ {\tt SymPol a} \ \ 
depends on the comparison function for the power products and the
one for the partitions. 



\newpage
\subsection{ Partition }
% ----------------------
\label{sec-symmf.p} 

Its items are exported from the module \ {\tt Partition},
\\
implemented in \ \verb#Partition.hs, pol/symmfunc/HookBand_.hs, Partit_.hs#.


\subsubsection{ Prelude }
\label{sec-symmf.p.p} 

Following the denotations by \cite{Ma}, let  

  $\lambda, \ \mu$ \ \ denote the partitions of a natural number \ $k$,
  
  $\lambda'$ \ \ conjugation of partition \ $\lambda$,

  $m_{\lambda}$ \ \ symmetric monomial function 
                    (see above the example of $m_{1,1}$),

  $e_i$  \ \ i-th elementary symmetric function,

  $ e_{\lambda} \ = \ \prod_{i \in \lambda} e_i$.
\\
And assume similar as \ $e_i, e_{\lambda}$ \ denotations for other 
bases: \ \ $ s_i, s_{\lambda}, \ p_i, p_{\lambda}, $ \ldots
\medskip

In the programs and program commentaries, we often use the 
following denotations.
\medskip

$\lambda, \mu,$ \ldots \ \ (partitions) $\longleftrightarrow$ \ \ 
                            {\tt la, \ mu, \ pt, pt1, p, q} \ldots. 
\\
For example, \ {\tt la = [6,5,5,2]}
\medskip

$e_i, \ p_i, \ldots \ 
           \longleftrightarrow$ \ \verb#e(i), p(i), e_i, p_i, ei, pi}#,

$m_{\lambda}, e_{\lambda},$ \ldots \ 
                    $\longleftrightarrow$ \ {\tt m[la], \ e[la]} \ldots, 

Also we use here the following terminology 
\\
(as {\it we} translate it back from Russian translaion of \cite{Ma}):  
\medskip

A part of a partition may be also called a {\it row} or a {\it line}.

{\it Block} of a diagram \ $\lambda$ 
\\  
is a rectangular diagram corresponding to some pair \ 
$(i,m)$ \ denoting \ $i^m$ \ in \ $\lambda$.

{\it Skew diagram \ (shape)} 
\\
is the difference \ $\lambda - \mu$ \ \ of the Young diagrams,
for any $\mu$ inside $\lambda$.

{\it Skew Hook \ (s-hook, SHook)} 
\\ 
is a continuous skew diagram in which the neighbour rows overlap in 
exactly one box.

{\it s-w-hook} \ \ \ is an s-hook of weight \ $w$.

A {it hook} \ $(i,j)$ \ in a diagram 
\\  
is the box with the coordinates $(i,j)$; \ 
it has \ {\it length = arm + leg}.

{\it Horizontal band \ (h-band, HBand)} 
\\
is a skew diagram that contains not more than one box in each column.

{\it h-w-band} \ \ \ is an h-band of weight \ $w$.

What is a \ {\it tableau of shape} \ $\lambda$ \ and weight \ $\mu$, \ \ \   
see in \cite{Ma}.
\medskip

We represent a skew hook as integer quartet \ {\tt (w, b, r, b')}.\\
Its components are as follows.
   
{\tt w} \ is the weight of hook,

{\tt b} \ No of the block in \ $\lambda$ \ where this hook starts, 

{\tt r} \ No of the row in this block at the end of which this 
          hook starts,  

{\tt b'} \ No of the last block of the hook --- it has to terminate 
        at the last row of this block.\\
 {\tt b'} \ can be derived from \ {\tt w, b, r}, \ 
 but still let it be introduced. \\
 Though in principle, a skew hook can be determined by a single
 point in a diagram. 
\medskip

An \ h-band \ {\tt hb} \ in a diagram \ $\lambda$ \ is represented  
as an integer list \ {\tt [$b_1,\ldots,b_n$]}.

This means that for 
$$                   \lambda = [(i_1, m_1), \ldots, (i_n, m_n)],
$$
the so-called \ b-block of the \ $b_k$ \ boxes is marked in the 
lowest row of the k-th block of rows of \ $\lambda$ \ 
(this block corresponds to \ $(i_k, m_k)$) \ --- for 
$$ 
  1 \leq k \leq n, \ \ \sum_{\ldots} b_k = w, \ \
  n = length \ \lambda = length \ hb, \ \ 
  hb \ {\mbox may \ contain \ zeroes.}
$$
An \ h-band \ consists of the b-blocks, each b-block is several 
continuous boxes in the end of the lowest row of the block of \ 
$\lambda$. 

Neither two b-blocks have a common column.

The type 
\begin{center}       {\tt  type Partition = [(Z,Z)] }
\end{center}
is for a partition, the one known from combinatoric.\\
This is a representation for the Young (Ferrers) diagram.\\

We represent a partition as \ {\tt []} \ or as 
$$
\lambda = [(j_1,m_1), \ldots, (j_k,m_k)], \ \ \ j_1 > \ldots \ > j_k > 0, 
$$
which is traditionally denoted in mathematics as \  
$(j_1^{m_1}\ldots j_k^{m_k}), \ \ m_i$ \ the multiplicity of \ $j_i$ \ 
in a partition.

Below, we describe some functionality and implementation for the 
partitions. 
%
\footnotesize
\begin{verbatim}
  type EPartition = [Z]   -- expanded partition - obtained from Partition by
                          -- expanding each (j,m) to jj...j  (m-times).

  type PrttComp = Comparison Partition   -- SymPol a  uses  PrttComp Z  similarly as
                                         -- Pol a     uses  PPComp
  isPrtt :: Partition -> Bool                           -- test "is partition"
  isPrtt []                  = True
  isPrtt [(i,m)]             = i > 0 && m > 0
  isPrtt ((i,m):(j,k):pairs) = i > j && m > 0 && isPrtt ((j,k):pairs)

  toEPrtt :: Partition -> EPartition
  toEPrtt = concat . (map (\ (j,m) -> genericReplicate m j))

  fromEPrtt :: EPartition -> Partition
  fromEPrtt []     = []
  fromEPrtt (j:js) = case span (==j) js  
                     of
                       (js', ks) -> (j, 1+(genericLength js')): (fromEPrtt ks)

  prttToPP :: Z -> Partition -> PowerProduct
                           -- Convert partition  la = [i1^m1 ... il^ml] 
                           -- into power product of given length  n >= l.
                           -- Example:  7 [5^2, 4, 2^3] --> Vec [0,3,0,1,2,0,0]
  ppToPrtt :: PowerProduct -> Partition
  ppToPrtt =  filter ((/=0) . snd) . reverse . zip [1 ..] . vecRepr

  prttWeight :: Partition -> Z                                 -- |pt|
  prttWeight [] = 0
  prttWeight pt = sum [j*m | (j,m) <- pt]

  prttLength :: Partition -> Z          -- l(pt) = height of Young diagram
  prttLength = sum . map snd            -- = number of "actual variables"

  conjPrtt  :: Partition -> Partition            -- conjugated partition pt'
  prttUnion :: Partition -> Partition -> Partition
                            -- repeated diagram lines 
                            -- are copied, say  [3,2,1] [3*2] -> [3*3, 2, 1]
  pLexComp :: PrttComp
               -- we call             pLexComp  
               -- what is called the  inverse lexicographical ordering  in [Ma]
 
  pLexComp' :: PrttComp          -- conjugated pLexComp comparison,
                                 -- in Macdonald's book [Ma] it is denoted  Ln'
  pLexComp' p q = pLexComp (conjPrtt q) (conjPrtt p)

  prttLessEq_natural :: Partition -> Partition -> Bool
    --   
    -- natural partial ordering on partitions:
    -- la <= mu  <=>  for each i > 0  sum(la,i) <= sum(mu,i),
    -- where  sum(la,i) = la(1)+..+la(i)  
    -- if we represent the partition without multiplicities

  minPrttOfWeight :: Z -> Partition    -- minimal partition of
  minPrttOfWeight    0 =  []           -- the given weight
  minPrttOfWeight    n =  [(1,n)]

  prevPrttOfN_lex :: Partition -> Maybe Partition
  
    -- Partition of k = |pt|  previous to  pt in the pLexComp order.
    -- Returns  Nothing  for the minimal partition
    -- and the minimum is here either  [(1,k)]  or  [].

  prttsOfW :: Partition -> [Partition]
                     -- pt -> [pt...minPt]  all partitions of  w = |pt|  
                     -- starting from  pt  listed in pLexComp -decreasing order
                     --
  prttsOfW pt = maybe [pt] ((pt:) . prttsOfW) (prevPrttOfN_lex pt)


  --------------------------------------------------------------------
  randomEPrtts ::  [Z] -> Z -> [EPartition]
                 --rands  w    pts
\end{verbatim}
\normalsize
--- infinite list  pts  of the {\it random expanded partitions} of \ 
{\tt w} \ produced out of the infinite list  \ {\tt rands} \  
of the random integers \ {\tt n}, \ such that \ 
{\tt 0 $\leq$ n $\leq$ w}.
  
{\tt rands} \ may be obtained by, say \ {\tt Random.random (0,w) s}
\medskip

{\bf Caution:} \ \ 
we are not sure that these partitions are ``very random''.


\footnotesize
\begin{verbatim}
  showsPrtt :: Partition -> String -> String

  type SHook = (Z, Z, Z, Z)

    -- Skew hook:  in  (w, hb, hr, hb')
    -- w   is the weight of the hook, 
    -- hb         No of the starting block, 
    -- hr         No of the row in this block where the hook starts,
    -- hb'        No of the last block of the hook.

  sHookHeight :: Partition -> SHook -> Z   -- numberOfRowsOccupied - 1
  sHookHeight    la           (_, b, r, b') = 
                               case genericTake (b'-b+1) (genericDrop (b-1) la)
                               of
                                 laOfHook -> (sum $ map snd laOfHook) - r

  subtrSHook :: Partition -> SHook -> Partition   -- subtract hook from partition 
  firstSWHook ::  Z -> Partition -> Maybe SHook
                --w    la
                -- first skew hook  la-mu  of weight  w  in the diagram  la  -
                -- the one with the highest possible head - if there exists any

  prevSWHook :: Partition -> SHook -> Maybe SHook
    --
    -- Previous  sw-hook  to the given  sw-hook.
    -- The ordering is so that the greater is the hook which head starts higher.
    -- prevSWHook la h  is obtained by taking the part  laT  of partition  la
    -- after the head row of the hook and applying  firstSWHook to laT ...
    -- We give it as Example of programming with partitions:

  prevSWHook [] _            = Nothing
  prevSWHook la (w, b, r, _) = 
    let 
      ((i,m):mu) = genericDrop (b-1) la
      laT        = if r==m then mu  else (i, m-r):mu
    in
    case firstSWHook w laT
    of 
      Nothing               -> Nothing
      Just (_, b', r', b'') -> (case (r==m, b')
                                of 
                                  (True, _) -> Just (w, b'+b  , r'  , b''+b  )
                                  (_   , 1) -> Just (w, b     , r'+r, b''+b-1)
                                  _         -> Just (w, b'+b-1, r'  , b''+b-1)
                               )
  type HBand = [Z]  
  subtrHBand :: Partition -> HBand -> Partition         -- partition \ h-band 

------------------------------------------------------------------------------
  maxHWBand :: Char -> Partition -> Z -> Maybe HBand
               --mode  la           w
\end{verbatim}
\normalsize
--- maximal h-w-band in a partition \ {\tt la}.
  
{\tt mode = 'l'} \ is so far the {\it only} valid value,
and it means that the `lex' ordering is used on the positions in a
diagram  \ {\tt la} : 

  \verb#(i,j) > (i',j') =  i < i' || (i==i' && j > j')#,
\\
where  \ {\tt i} \ is the number of the block of rows, \ 
{\tt j} \ number of the column.

Comparing bands means comparing lexicographically the sequences of 
their cell positions --- starting from the maximal position. 

We give the implementation as an example of programming bands:
%
\footnotesize
\begin{verbatim}
  maxHWBand mode la w =  
    if
      mode /= 'l' then
      error $ ("maxHWBand "++) $ (mode:) $ (' ':) $ shows la $ (' ':) $ shows w $
                          " :\nmode = \'l\'  is the only possible so far\n"
    else  mb la w
      where
      mb la         0 = Just $ map (const 0) la
      mb []         _ = Nothing
      mb [(i,_)]    w = if i < w then Nothing else Just [w]
      mb ((i,_):la) w = let {(j, _) = head la;  d = i-j;  w' = min d w}
                        in 
                        fmap (w':) (mb la (w-w'))

  prevHWBand :: Char -> Partition -> HBand -> Maybe HBand 
                                     -- Previous (to the given) h-w-band.
                                     -- Ordering, mode  are as in  maxHWBand.
\end{verbatim}
\normalsize




\subsubsection{ Kostka numbers }
\label{sec-symmf.p.kn} 

For the partitions \ \ $\lambda, \ \mu$ \ \ of weight \ $w$, \ \ 
the Kostka number \ \ $K(\lambda, \mu)$ 
\\
is the number of {\it tableaux of the shape} \ $\lambda$ \ 
and weight \ $\mu$ \ (\cite{Ma}).

From \cite{Ma} we study the folloing:
\medskip

{\bf 1.} \ The integer upper uni-triangular matrix \ $K(\lambda,\mu)$ \ 
presents the {\tt Z}-module isomorphism from the basis \ 
$\{ s_{\lambda} \}$ \ of the Schur functions to the basis \ 
$\{ m_{\mu} \}$ \ of the symmetric monomial functions.

{\bf 2.} \ $ K(\lambda, \lambda) = 1, \ \ K([n], \mu) = 1, $

if \ $ not \ (\lambda \geq \mu)$ \ in the natural (partial) ordering,
then \ $K(\lambda, \mu) = 0$, 

$K(\lambda, \ [1^w])$ = \ number of Standard tableaux \ = \ 
           $ w! \ / \ (\prod_{h \in hooks(\lambda)} length(h)) $
\medskip

Finding the Kostka numbers \ $K(\lambda,\mu)$ \ looks like a 
hard combinatoric task.
In the generic case, the number of tableaux can be found by 
reversing of the expanded \ $\mu$ \ and forming of all the  
h-$m_i$-bands in \ $\lambda$, subtracting these bands and 
applying the recursion.

And this, in fact, is implemented in DoCon. 

The only optimization is usage of a {\it table} (binary tree)  to
store the pairs \ \ $(\lambda, v)$, \ \ $v = K(\lambda, i_{mu})$ 
\ \
for some previously encountered \ $\lambda$ \ and the initials \ 
$i_{\mu}$ \ of the weight \ $\mu$.

This accelerates considerably the current and future computations of
the Kostka numbers --- even if one gives  \ {\tt Map.empty} \ 
in the argument.
This is because the tableaux often repeat in the above process of 
the \ $K(\lambda,\mu)$ \ computation.

The tables are supported by the \ {\tt Map.Map} \ item from 
the \ {\tt data} \ library
(a balanced binary tree programmed in {\tt Haskell}). 
It preserves the functionality.

Maybe, there exists more efficient way to compute Kostka numbers, 
the one basing on some law for the remainder tableaux repetitions.
So far, we do not know of such a method. 

So, the format is 


\newpage
\begin{center}  {\tt  kostkaNumber table la mu --> (newTable, value) }
\end{center}

{\footnotesize
\begin{verbatim}
  kostkaNumber :: Map.Map Partition Z -> Partition -> Partition ->
                  -- table               la           mu   
                                                      (FiniteMap Partition Z, Z)
                                                       -- newTable            value
\end{verbatim}
}
Number of tableaux of the shape \ {\tt la} \ and weight \ {\tt mu}, \ 
--- for \ {\tt |la| = |mu|}.

{\tt table = tab(ro)} \ \ 
is a \ {\tt Map.Map} (binary table) serving to store the pairs \ 
\verb#(la, v)#,\\  
\verb#v = K(la, i_mu),# \ \ for some previously encountered \ {\tt la} \ 
and the initials \ \verb#i_mu# \ of weight \ {\tt mu}.

\ \verb#i_mu# \ are not stored, for they are defined uniquely by \ 
{\tt la}.

Each time the argument \ {\tt la, mu} \ is non-trivial and not 
contained in the table, the value is found by the below method and 
added to table.
Accumulating  this  table  accelerates  the   current   and   future
computation  of  the  Kostka  numbers  that  use   the   previously 
accumulated table --- even if \ {\tt Map.empty} \ is initiated in the 
argument. 

But the table needs memory. The programmer can prevent further 
growth of the table by giving to the next \ {\tt kostkaNumber} \ 
invocation the argument \ {\tt table = Map.empty}.

See the examples for this presented by the functions \ 
{\tt kostkaColumn, \ kostkaTMinor}.
\bigskip
\medskip

\underbar{Repeated computation with Kostka numbers}
\medskip

The below two function also illustrate an application of \ 
{\tt kostkaNumber}. 

The \ {\tt kostkaColumn} \ script introduces the local variable \ 
{\tt tab} \ for the table, initiating it with the empty value. \ 
{\tt kostkaColumn} \  spends more space in order to increase the 
performance.

And \ {\tt kostkaTMinor} \ `maps' \ {\tt kostkaColumn} \ 
to the list of partitions, it does not carry the table between 
the  \ {\tt kostkaColumn} \ invocations.

Accumulating \ {\tt tab} \ all through the matrix \ {\tt K(la,mu)} \  
causes too much memory expense.

The same approach applies to the {\it irreducible character} matrix 
(see below).

\footnotesize
\begin{verbatim}
  kostkaColumn :: Partition -> [Partition] -> (Map.Map Partition Z, [Z])
                  -- mu        la_s            tab                  col
\end{verbatim}
\normalsize
yields the list \ \ \verb#col = [K(la, mu) |  la <- la_s]# \ \ 
of the Kostka numbers, \ {\tt la, mu} \ the partitions of the same 
positive weight, and the table of the accumulated values \
\verb#K(la~, i_mu)# \ produced by the repeated application of \ 
\verb#(tab', v) = kostkaNumber tab _ _#
  
In particular, setting \ \ \verb#la_s = allPartitions(w)# \ \  
we obtain the whole column of \ {\tt mu} \ of the Kostka matrix.

\footnotesize
\begin{verbatim}
  kostkaColumn mu la_s =
    if
       null mu then  error $ showString "kostkaColumn [] la_s \n\n" $ msg "\n"
    else             (tab, reverse col)
      where
      (tab, col)          = foldl addKNum (Map.empty,[]) la_s
      addKNum (tab,vs) la = case kostkaNumber tab la mu of (tab',v) -> (tab',v:vs)
      msg  = ("length la_s = "++) . shows ... . msg'
      msg' = ... ("head la_s = "++) . shows la  ...

  kostkaTMinor :: [Partition]-> [Partition]-> [[Z]]
  kostkaTMinor la_s mu_s = [snd $ kostkaColumn la mu_s | la <- la_s]
\end{verbatim}
\normalsize
--- transposed minor of the matrix of the Kostka numbers.

\verb#la_s, mu_s# \ should be the partitions of same positive weight \ 
{\tt w}. \ 
They define respectively the rows and the columns of transposed minor. 

In particular, setting \ \ \verb#la_s = mu_s = all_partitions(w)# \ \
yields the whole transposed Kostka matrix.

Certain {\bf property:}\\
it is known \cite{Ma} that \ {\tt K} \ is strongly upper uni-triangular  
and has $1$ -s in the first row.
So, the result is strongly lower uni-triangular.

{\bf Remark}.\\
In practical computation with the symmetric functions, there often 
appear quite large Kostka matrices.

And we are lucky that the columns of a Kostka  matrix  are  computed  
independently.  The positions in a Kostka matrix are indexed by  the 
partitions. This gives the effect of a sparse matrix represented as
the map of type 
\begin{center}   {\tt  [Partition] -> [Partition] -> [[Z]] }
\end{center}
The same is with the character matrix (see below).
\bigskip

\begin{center}     {\tt  hookLengths :: Partition -> [[Z]] }
\end{center}   
The matrix \ {\tt \{h(i,j)\}}, \ \ 
{\tt h(i,j)} is the length of the hook of the point \ {\tt (i,j)} 
in the given Young diagram \ {\tt la}.

The result (a list of lists of integers) has the form of 
{\it expanded partition} for \ {\tt la} 
(and the lists may differ in length), each  \ {\tt h(i,j)} 
being put in the corresponding cell of the diagram.

\begin{center}  {\tt numOfStandardTableaux :: Partition -> Z}
\end{center}   
Number of standard tableaux \ = \ 
$ weight(\lambda)! \ / \ (\prod_{h \in hooks(\lambda)} length(h)) $

The program tries to keep the intermediate products possibly small.
 


\newpage
\subsubsection{ Irreducible characters for \ $S(n)$ }
\label{sec-symmf.p.ch} 

The group representation theory (\cite{La}, Chapter 18) asserts the 
following.

{\bf 1.} \ 
A character \ $\chi$ \ of a group \ $G$ \ is a map \ 
$g \ |\rightarrow \ Trace(F(g))$, \ \
where $F$ is any representation of $G$ by the linear operators on 
some vector space $V$.

{\bf 2.} \ 
The character values \ $\chi(g)(h)$ \ depend only on the conjugacy
classes of \ $g, h$ \ in \ $G$. \  
For the permutation group \ $S(n)$, \ these implies that \ 
$\chi(g)(h)$ \ is defined by the cyclic types of the permutations \ 
$g, h$ \ --- and these types can be represented as the partitions of \ 
$n$. \ So, we write \ $ \chi(\lambda)(\mu), \ \ \lambda, \ \mu $ \ 
the partitions of \ $n$.

{\bf 3.} \ 
Irreducible representations and their characters are important.\\
For a finite group, the irreducible characters form an orthogonal
basis.

For our program, this means that the matrix \ $C$ \ of irreducible 
character values has the reciprocally orthogonal rows --- in usual 
meaning of the scalar product of rows.

In the case of symmetric functions, the group is \ $S(n)$, \ 
and the character matrix  \ $C$ \ presents the isomorphism from 
the basis \ $ \{ p_{\lambda} \} $ \ to \ $ \{ s_{\lambda} \} $ \ \ 
--- see \cite{Ma}.  

$C(\lambda, \rho)$ \ can be computed by the Murnaghan-Nakayama rule 
\cite{Ma}, and {\tt DoCon} does this

(like with the Kostka numbers, there might exist more efficient way
to compute these character values).

{\tt DoCon} achieves certain optimization by  using  of  the  intermediate
binary table --- similarly as with the Kostka numbers.


{\footnotesize
\begin{verbatim}
  permGroupCharValue :: Map.Map Partition Z -> Partition -> Partition ->
                        -- table               la           ro 
 
                                               ( FiniteMap Partition Z,  Z )
                                                 -- newTable           chi(la,ro)
\end{verbatim}
}
Irreducible character value for the permutation group $S(n)$.\\
It is known \cite{Ma} that any such character \ {\tt chi} \ 
is defined by some partition \ {\tt la} \ of \ $n$, \ and \ {\tt chi} \  
can be expressed as certain determinant of the unit characters of the 
groups \ $S${\tt (la(i))}.

{\tt table = tab(ro)} \ \
is a  \ {\tt Map.Map} \ (binary table --- made functionally) 
serving to store the pairs \ \verb#(mu, chi(mu, i_ro))# \ 
for some previously encountered \ {\tt mu} and the initials \ 
\verb#i_ro# \ of \ {\tt ro}.

\verb#i_ro# \ are not stored, for they are defined uniquely by \ {\tt mu}.

Even if \ {\tt table = Map.empty}, \ it still accumulates so that it
accelerates on average the computation of current and further
\ {\tt chi(la, ro)} \ (for the same ro), see, for example, the 
function \ {\tt permGroupCharMatrix}.

{\bf Method:}\\
Murnaghan-Nakayama rule \ + \ storing/searching in table.

The tabulation applies for the similar reason as in \ {\tt kostkaNumber}.


\newpage
\footnotesize
\begin{verbatim}
  permGroupCharColumn :: Partition -> [Partition] -> (Map.Map Partition Z, [Z])
                         -- ro        la_s            tab                  col
\end{verbatim}
\normalsize
This yields

(1) \ the list \ \ \verb#col = [cha(la,ro) | la <- la_s]# \ \ 
of the character values obtained from \ {\tt permGroupCharValue}, \ \
{\tt la, ro} \ the partitions of the same positive weight,

(2) \ the table of accumulated values \ \verb#cha(la~,i_ro)# \ 
produced by the intermediate applications of \ 
\verb#(tab',v) = permGroupCharValue tab _ _#
  
In particular, setting \ \verb#la_s =# all partitions, \ \ 
we obtain the whole column of irreducible character matrix for $S(w)$.

\footnotesize
\begin{verbatim}
  permGroupCharTMinor :: [Partition] -> [Partition] -> [[Z]]
  permGroupCharTMinor ro_s la_s = [snd $ permGroupCharColumn ro la_s | ro<- ro_s]
\end{verbatim}
\normalsize
Transposed minor \ {\tt tC} \ of the matrix of values of 
irreducible characters \ {\tt cha(w)(la,ro)} \ 
for the permutation group  $S(w)$.

\verb#ro_s, la_s# \ should be the partitions of same positive weight.
They define respectively the rows and columns of transposed minor. 

In particular, setting \ \ \verb#ro_s = la_s = all_partitions(w)# \ \ 
yields the whole transposed character matrix \ {\tt tC}.
\medskip
  
One of possible tests: \ \ {\tt tC * (transp tC)} \ \ 
should be diagonal; this is due to orthogonality of irreducible 
characters.




\subsection{ Sym-polynomial }
% ---------------------------
\label{sec-symmf.sp} 


\subsubsection{ Preface }
\label{sec-symmf.sp.p} 

Its items are exported from the module \ {\tt AlgSymmF},\\
implemented in \ \verb#AlgSymmF.hs,  pol/symmfunc/Sympol_.hs#

A sym-polynomial is a linear combination of the monomial sym-functions 
\ $m(\lambda)$, \ that is a linear combination of partitions. 
DoCon represents it similarly as a polynomial over $R$, but with 
the following differences:

(1) \ it contains partitions instead of the power products,

(2) it contains  \ {\tt pcp :: PrttComp} \ instead of \ {\tt PPComp} \ 
(see Section~\ref{sec-symmf.p.p}),

(3) \ it does not contain the variable list.
\medskip

The sym-monomials in \ {\tt SymPol} \ should be ordered decreasingly
by \ {\tt pcp}.

For a {\it polynomial} data, the variables (algebraic indeterminates)
indicate the {\it domain}.  
For example, \ {\tt f} \ may belong to \ $Z[x]$ \ or to \ $Z[x,y]$, \ 
depending on the list \ {\tt vars = pVars f}.

A sym-polynomial \ {\tt f} \ does not refer to the variables,  
because {\tt DoCon} presumes \ {\tt f} \ to relate to the infinite 
variable list \ $x_1, x_2$, \ldots \ (may be, renamed).
Say  \ $p_2 = x_1^2 + x_2^2 +$ \ldots \ \ 
can be represented as \ \ \verb#SymPol [1*m[2]] 0 pLexComp _#
\medskip

The operations with the sym-polynomials require a
\medskip

  {\it coefficient domain $R$ being a commutative ring with unity}.
\medskip

Here are the descriptions of some main items related to the 
sym-polynomials.

Note that \ {\tt SymPol} \ is one more model for the \ 
{\tt class PolLike}.



\subsubsection{ Initial definitions }
\label{sec-symmf.sp.i} 

\footnotesize
\begin{verbatim}
  type SymMon a = (a, Partition)   -- like  Mon a, Pol a,
                                   -- only with partition instead of power product
  data SymPol a = SymPol [SymMon a] a PrttComp (Domains1 a)

  instance Dom SymPol where  sample (SymPol _ a _ _) = a
                             dom    (SymPol _ _ _ d) = d
                                               
  symPolMons     :: SymPol a -> [SymMon a]
  symPolPrttComp :: SymPol a -> PrttComp

  symPolMons     (SymPol m _ _  _) = m
  symPolPrttComp (SymPol _ _ cp _) = cp
                                        
  symLm :: CommutativeRing a => SymPol a -> SymMon a    -- leading sym-monomial
  symLm f = case symPolMons f of m:_ -> m
                                 _   -> error$ ("symLm 0 \nin"++)$ showsDomOf f "\n"
  symLdPrtt :: CommutativeRing a => SymPol a -> Partition
  symLdPrtt =  snd . symLm

  instance Eq a => Eq (SymPol a) where  f==g = (symPolMons f)==(symPolMons g)

  instance AddGroup a => Cast (SymPol a) (SymMon a)  --sym-monomial to sym-polynomial
    where
    cast mode (SymPol _ c cp dm) (a,p) = SymPol mons c cp dm
                          where
                          mons = if mode=='r' && isZero a then []  else [(a,p)]

  instance AddGroup a => Cast (SymPol a) [SymMon a]       -- from sym-mon list
    where
    cast mode (SymPol _ c cp dm) mons = SymPol ms c cp dm
      where                                                -- order NOT checked
      ms = if mode /= 'r' then mons  else filter ((/= z) . fst) mons
      z  = zeroS c

  instance Ring a => Cast (SymPol a) a           -- from coefficient
    where
    cast mode (SymPol _ _ cp dm) a = case mode of 'r' -> cToSymPol cp dm a
                                                  _   -> SymPol [(a,[])] a cp dm
  --------------------------------------------------------------------
  instance PolLike SymPol
    where
    pIsConst f = case symPolMons f of (_, p): _ -> null p
                                      _         -> True
    pCoefs  = map fst . symPolMons

    pTail f = case symPolMons f of
                             _: ms -> ct f ms
                             _     -> error$ ("pTail 0  \nin"++) $ showsDomOf f "\n"
    pFreeCoef (SymPol mons a _ _) = case (last mons, zeroS a)
                                    of
                                    ((a, p) ,z) -> if null p then a else z

    ldeg f = case symPolMons f of (_, p): _ -> prttWeight p
                                  _         -> error ("ldeg 0" ...)
 
    deg f = case map (prttWeight . snd) $ symPolMons f of  [] -> error ("deg 0"...)
                                                           ds -> maximum ds
    pCDiv f c         = ... similar to Pol
    pMapCoef mode f g = cast mode g [(f a, p) | (a, p) <- symPolMons g]

    -- Skipped: 
    -- pMapPP, pPPO, pVars, lm, lpp, pDeriv, degInVar, varPs, pDivRem, pValue
  --------------------------------------------------------------------
  cToSymMon :: a -> SymMon a    -- correctness condition:  c /= 0
  cToSymMon    a =  (a, [])

  cToSymPol :: AddGroup a => PrttComp -> Domains1 a -> a -> SymPol a
  cToSymPol cp dm a = if
                        isZero a then  SymPol []            a cp dm
                      else             SymPol [cToSymMon a] a cp dm

  instance Show a => Show (SymPol a)
    where
    showsPrec _ f = ("(SymPol "++). 
                   (foldr (\mon f-> showsMon mon .f) (" )  "++) $ symPolMons f)
                     where  
                     showsMon (c,la) = shows c . ('*':) . showsPrtt la . (' ':)

  reordSymPol :: PrttComp -> SymPol a -> SymPol a      -- bring to new ordering
  reordSymPol    cp (SymPol mons c _ dm) =    
                            SymPol (reverse $ sortBy (compBy snd) mons) c cp dm

  monToSymMon :: Mon a -> SymMon a 
  monToSymMon (a, Vec js) = (a, gather $ reverse $ sort$ filter (/= 0) $ js)
    where
    gather []     = []
    gather (j:js) = case span (==j) js 
                    of
                    (js', js'') -> (j, 1 + (genericLength js')) : (gather js'')


--------------------------------------------------------------------
  symPolHomogForms :: AddGroup a => SymPol a -> [SymPol a]
\end{verbatim}
\normalsize
The list  \ {\tt hs} \ of the homogeneous parts of \ {\tt f}.\\
{\tt hs(f)} \ is empty for zero \ {\tt f},\\
otherwise, \ {\tt h(1)} \ is the homogeneous form of \ {\tt lm f}, \ \ 
{\tt h(2)} \ of \ \ {\tt lm (f-h(1)}, \ \ and so on.




\subsubsection{ Main instances }
\label{sec-symmf.sp.mi} 

The algebraic category instances are defined naturally for \ {\tt SymPol}
--- from \ {\tt Set} \ up to \ {\tt AddGroup}.

For the instance \ \ {\tt \ldots Num SymPol \ldots}, \ \ 
the operations \ {\tt negate, (+), (-)} \ are defined,  
and \verb#(*)# is skipped, as we do not know so far how to define it.



\subsubsection{ Conversion Pol - SymPol }
\label{sec-symmf.sp.cv} 

\footnotesize
\begin{verbatim}
  toSymPol :: Eq a => PrttComp -> Pol a -> Maybe (SymPol a)
                      -- pcp      f               symF
\end{verbatim}
\normalsize
Given a polynomial \ {\tt f},  symmetric under the permutations of its
variables, \ partition comparison  \ {\tt pcp},\\
produce the sym-polynomial \ {\tt symF} by collecting each monomial orbit
into corresponding sym-monomial.

Yields \ \ {\tt Just symF} \ \ for symmetric polynomial, \ {\tt f}, \ \ 
otherwise, yields \ {\tt Nothing}
\footnotesize
\begin{verbatim}
  symmetrizePol :: CommutativeRing a => PrttComp -> Pol a -> Maybe (SymPol a)  
  symmetrizePol pcp f =
                     case fromi (sample f) $ factorial $ genericLength $ polVars f
                     of
                       nFactorial -> pCDiv (symmSumPol pcp f) nFactorial
\end{verbatim}
\normalsize
(see  \ {\tt symmSumPol}, as somehow more generic)

converts polynomial \ {\tt f} to symmetric form polynomial under the given
partition ordering \ {\tt pcp}.

It sums up the symmetric orbit and divides by \ $n!, \ n = length(vars)$.

{\bf Required:} \ \ $n!$ \ should not be zero in a ring \ {\tt a}.
\\
Also if the above quotient by \ $n!$ \ does not exist, the result is \
{\tt Nothing}.

{\bf Examples.}\\
(1) For a field \ {\tt a} \ with \ {\tt char > n}, \  
the result is of kind \ {\tt Just sf} \ ;

(2) For \ {\tt a = Z/4, \ \ n = 3}, \ \ symmetric \ {\tt f}, \ 
it is  \ {\tt Just sf}, 

for non-symmetric \ {\tt f}, \ it may be \ {\tt Nothing}.
\medskip


\footnotesize
\begin{verbatim}
  symmSumPol :: CommutativeRing a => PrttComp -> Pol a -> SymPol a
                                     -- pcp      f        symF
\end{verbatim}
\normalsize
{\tt symF = n!*(symmetrizePol f), \ \ n = length vars}, \\ 
{\tt symF} \ is under the given partition ordering {\tt pcp}.

{\bf Method}.\\
Convert the power products {\tt pp} to partitions \ {\tt [i,j,\ldots]}.
Gather the pp-s of same orbit, that is of same partition.
Each \ {\tt orbit(i,j,\ldots)} \ sum is \ 
{\tt c(i,j,\ldots)*m[i,j,\ldots]}, \ with appropriate coefficient \ 
{\tt c(i,j,\ldots) =} stabilizator order of pp \ {\tt (i,j,\ldots)} \ 
in the group \ $S(n)$.
\medskip


\footnotesize
\begin{verbatim}
  fromSymPol :: CommutativeRing a => Pol a -> Domains1 (Pol a) -> SymPol a -> Pol a
                                     -- smp   dP                  f
\end{verbatim}
\normalsize
Expand sym-polynomial to polynomial of the given sample \ {\tt smp}.

{\bf Method:}\\
{\tt f} converts to \ $h(e_1, e_2, \ldots)$, \ \   
$e_i$ the elementary symmetrics; 
 
then, the expressions \ $e_i(vars)$ \ are substituted in \ $h$.\\
Here it is set \ $e_i = 0$ \ for \ $i > n = |vars|$.

{\bf Caution:} \ this may be very expensive, think before applying it.



\subsubsection{ Example }
\label{sec-symmf.sp.e} 

Form the elementary symmetric polynomials \ [$e_1,\ldots,e_n$] \ 
in \ \ {\tt P = $Z[x_1,\ldots,x_n], \ n = 4$}, \ \ 
and find the sym-pol form of \ $e_2 + e_3$.
%
\footnotesize
\begin{verbatim}
  import DPrelude (Z)
  ...
  main = let  vars              = ["x1","x2","x3","x4"]
              samplePol         = cToPol (lexPPO 4) vars dZ 1  :: Pol Z
              dP                = upRing samplePol Map.empty
              elems@(_:e2:e3:_) = elemSymPols samplePol dP
         in
         fromMaybe (error "f is not symmetric\n") $ toSymPol pLexComp (e2+e3)
\end{verbatim}
\normalsize
{\tt show} has to print the result as \ \verb#"(SymPol 1*[1*3] 1*[1*2] )"#
\\
--- here the expanded partitions are \ \ {\tt [1,1,1], [1,1]}.




\subsection{ Symmetric bases transformations }
% --------------------------------------------
\label{sec-symmf.t} 

They are exported from the module \ {\tt AlgSymmF},\\
implemented in  \ \verb#AlgSymmF, pol/symmfunc/SymmFn*_#.


\subsubsection{ Preface }
\label{sec-symmf.t.p} 

A symmetric functions is often considered as something that  may  be
decomposed into the polynomial of elementary symmetric functions. 
But it is known a more systematic approach to the transformations of
such kind --- see \cite{Ma}. Following this book, DoCon implements
the transformations that are the $R$-module isomorphisms  
\begin{center}
                          {\tt M(u,v)}  
\end{center}
for the commutative coefficient ring $R$ of the symmetric function 
algebra, where
\begin{center}    {\tt u, v = \ 'e', 'h', 'm', 'p', 's' }
\end{center}
For example, \ {\tt M(m,e)} \ presents the decomposition to the 
elementary symmetrics.

The {\tt DoCon} view of the subject is as follows.
The generic transformation format is
\begin{verbatim}
        to_<v>      msgMode basisId tab   f ->  (tab, h)          (T1)

        to_<v>_pol  msgMode basisId tab o f ->  (tab, h)          (T2)
\end{verbatim}
{\tt basisId = u: t}, \ \ \ {\tt u}, \ \verb#<v># = \ 
{\tt 'e', 'h', 'm', 'p', 's'} \ \ \ are the basis names.  

{\tt 'e'} \ means the elementary symmetrics \ $e_i, \ e_{\lambda}$,

{\tt 'h'} \ full homogeneous functions \ $h_i, \ h_{\lambda}$,

{\tt 'm'} \ symmetric monomials \ $m_{\lambda}$,

{\tt 'p'} \ power sums \ $p_i, \ p_{\lambda}$,

{\tt 's'} \ Schur functions \ $s_i, \ s_{\lambda}$.

{\tt (T1), (T2)} \ mean the symmetric function basis transformation 
from \ \verb#<u># \ to \ \verb#<v>#.

The format {\tt (T2)} differ from {\tt (T1)} in that it converts the 
result to the {\it polynomial} --- in the given pp-ordering \ {\tt o} \ 
and variables \ [\verb#<v>#$_1$,\verb#<v>#$_2$,\ldots,\verb#<v>#$_n$], 
\ \ 
$n = max(1, weight(f))$.
\medskip

{\tt msgMode :: SymmDecMessageMode} \ 
specifies how to issue intermediate messages. Because as some 
sym-monomials take long to decompose to another basis, it may be 
convenient to issue intermediate messages about which partition is 
being currently decomposed.
\medskip


\underbar{Coefficient ring:}
\medskip

\verb#to_p# \ \ requires a field of zero characteristic,\\
others --- any commutative ring $R$ with unity.



\newpage
{\tt basisId}
\\
is a string \ \ {\tt u: t} \ \ of one or two letters,

{\tt u <- ['e','h','m','p','s']} \ \ is the name of basis,

{\tt t} \ \ is either \ {\tt []} \ or \ {\tt "n"}, \ \    
we call it a proper mode.

So far, \ {\tt "n"} \ may be used \ {\it only} \ in the case of \ 
\verb#to_e(_pol) msgMode "mn"#.

{\tt t = "" | "n"} \ \ chooses between the two computation methods.
\\
We shall return to this subject later.
\medskip

{\tt tab}
\\
can be set as \ {\tt Map.empty}.\\
Those who do not want to care for \ {\tt tab}, may set the program like 
this:
\begin{center}
     \verb#let (_, h) = to_s msgMode "m" Map.empty f  in  what_is_needed h#
\end{center}
(and for {\tt msgMode}, the simplest choice is {\tt NoSymmDecMessages}).

This table \ {\tt tab} \ (see \ {\tt `type SymFTransTab = \ldots'})
contains the pairs 
\begin{center}       {\tt  (w, (pts, tC, tK)),  }
\end{center}

{\tt w} \ the integer weight,

{\tt pts} \ partitions of {\tt w} listed decreasingly by {\tt pLexComp},

{\tt tC} \ transposed irreducible character ptp-matrix for $S(n)$,

{\tt tK} \ transposed Kostka ptp-matrix --- see {\tt SymFTransTab}.

These matrices are for the weight  {\tt w}. 
And they are the  ptp-matrices, that is the tables of type   
\begin{center}   
                  {\tt  Map.Map Partition [Integer], }
\end{center}
the row being looked up by the partition index.

{\tt tab} \ accumulates automatically and is returned in the result. 
\\
This is arranged so because {\tt DoCon} commonly uses the matrices \ 
$C, K$ \ for the above transformation, the elements of \ $C, K$ \ are 
expensive to to evaluate and are often re-used.
Each transformation uses and updates only certain part of \ {\tt tab}. 
Thus, \ \verb#m_to_p# \ ignores the table at all.

Again, each matrix from \ {\tt tab} \ is `lazy', it unfolds its  
rows only when needed. It depends on the sequence of transformations  
and their data which parts of {\tt tab} will actually work.

{\bf Example:} \ \ \verb#to_e _ "m" Map.empty f  --> (tab, h)#

  means the {\tt M(m,e)} transformation (from `m' to `e').
\medskip

\verb#to_<v> msgMode (u: t)# \ \ means the conversion of \ 
$ f = \sum_{\lambda \ldots} c_{\lambda} u_{\lambda} $ 
\ \
to \ \ $ h = \sum_{\mu \ldots} a_{\mu} v_{\mu} $, 
\\  
$\lambda, \mu$ \ the partitions \cite{Ma}.

For \ $ \lambda = [\lambda_1,\ldots,\lambda_l], $
\\
\verb#<u>#$_{\lambda} \ =_{def}$ \  
symmetric monomial \ $m_{\lambda},$ \ if \ \verb#<u># = {\tt 'm'},
\ \ otherwise, it is \ $\prod_{i = 1}^l$ \verb#<u>#$_{\lambda_i}$ 
\medskip

For example, \ $ p_{5,3,3,1} = \ p_5 p_3 p_3 p_1 = \ p_5 p_3^2 p_1, $ \ \ \ 
               $ m_{5,3,3,1} =$ \ symmetric orbit of \ $x_5 x_3^2 x_1$ 
\medskip

{\bf Ordering:}\\
the sym-monomials in {\tt f} may be ordered arbitrarily.\\
But the ones of \ {\tt h} \ are in the  \ {\tt pLexComp} \ ordering only
--- apply \ {\tt reordSymPol} \ if needed.
\medskip

Another example:  \ \ \verb#to_e msgMode "mn" Map.empty f# 
\medskip


In {\tt basisId}, \ \ {\tt t = "n"} \ \ means to convert from \ 
\verb#<u># \ to \ \verb#<v>#, \ applying the method \ {\tt `via-p'}.
It avoids the tables and matrices $K, C$ \ (in some examples this 
may save cost).
\medskip

{\bf About the \ \verb#to_e# \ conversion from {\tt 'm'} :}
\\
it performs as the composition \ \ 
                               {\tt 'm' --mToS-> 's' --sToE-> 'e'}. 
\\
--- from {\tt 'm'} to the Schur basis, and then, to {\tt 'e'}.

Here the step {\tt mToS} can perform in two ways. 
If {\tt basisId = "m"}, \ it converts by the inverse Kostka operator. 

If {\tt basisId = "mn"}, \ it avoids the Kostka operator and converts 
first to {\tt 'p'} by the Newton-Serret formulae, and converts further 
to 's' via the irreducible character matrix {\tt tC}.
\medskip

{\tt t = ""} \ \ may be particularly efficient when $K$ or $C$ is not 
large and there are many repeating monomial weights in \ {\tt f}.
\medskip

\underbar{Variable list}
\medskip

The result polynomial of \ \ \verb#to_<v>_pol# \ \ needs the variable list.
\\
DoCon sets it to be \ \ 
      [\verb#<v>#$_1$,\ldots,\verb#<v>#$_n$], \ \ $n = max(1, \ weight f)$, 
\\
they can be renamed easily if necessary. This is set so because it would 
suffice this many variables to print the result. For example, 
\begin{center}  
   \verb#show $ snd $ to_e_pol msgMode "m" tab o (SymPol [m[3]] _ _ _)# 
\end{center}
will look like \ \verb#"e1^3 - 3*e1*e2 + 3*e3"#  \ \ when printed; 
here \ $n = 3$.


\newpage
\subsubsection{ Summary }
\label{sec-symmf.t.s} 

\begin{verbatim}
      to_<v>      msgMode basisId tab   f ->  (tab, h)          (T1)

      to_<v>_pol  msgMode basisId tab o f ->  (tab, h)          (T2)
\end{verbatim}
mean to transform a symmetric function \ {\tt f} \   
from the basis \ \verb#<u># to \verb#<v># \ 
over a commutative coefficient ring.

\ {\tt basisId = u: t, \ \ \ u}, \verb#<v># = \ 
{\tt 'e', 'h', 'm', 'p', 's'} \ \ are the basis names.

{\tt t} \ \ is either \ {\tt []} \ or \ {\tt "n"}, 
  
{\tt "n"} \ may be used so far only in \ \verb#to_e(pol) "mn"# 

The table \ {\tt tab} \ (initiate it with \ {\tt Map.empty}) \ 
contains the pairs \ \ {\tt (w, (pts, tC, tK))}, 

  {\tt w} \ the weight, \ \ {\tt pts} the partitions of \ {\tt w},

  {\tt tC, tK} \ the ptp-matrices for the irreducible 
                         characters and Kostka numbers respectively.
\medskip

\verb#to_p(_pol)# \ requires a field of zero characteristic.

{\tt (T1)} \ converts to the sym-polynomial.

{\tt (T2)} \ --- to the polynomial in the given pp ordering \ {\tt o} \ 
and variables 

  [\verb#<v>#$_1$, \verb#<v>#$_2$, \ldots, \verb#<v>#$_n$], \ \ 
  $n = \max (1, \ weight(f))$.
\medskip

{\footnotesize
\begin{verbatim}
  type SymmDecBasisId = String

  data SymmDecMessageMode =  DoSymmDecMessages Integer | NoSymmDecMessages
                             deriving (Eq, Show)
\end{verbatim}
}
Here \ {\tt DoSymmDecMessages w} \ means to issue a short message about 
each current sym-monomial being processed --- if its partition weights 
not less than \ {\tt w}. 

{\footnotesize
\begin{verbatim}
  to_e, to_h, to_m, to_s ::

    CommutativeRing a
    =>
    SymmDecMessageMode -> SymmDecBasisId -> SymFTransTab -> SymPol a ->
                                                            (SymFTransTab, SymPol a)

  to_p :: 
    Field k   -- REQUIRED is  char(k) = 0
    =>
    SymmDecMessageMode -> SymmDecBasisId -> SymFTransTab -> SymPol k ->
                                                            (SymFTransTab, SymPol k)
\end{verbatim}

\newpage
\begin{verbatim}
  to_e_pol, to_h_pol, to_m_pol, to_s_pol ::

    CommutativeRing a
    =>
    SymmDecMessageMode -> SymmDecBasisId ->
    SymFTransTab       -> PPOrdTerm      -> SymPol a -> (SymFTransTab, Pol a)

  to_p_pol :: 

    Field k   -- REQUIRED is  char(k) = 0
    =>
    SymmDecMessageMode -> SymmDecBasisId ->
    SymFTransTab       -> PPOrdTerm      -> SymPol k -> (SymFTransTab, Pol k)
\end{verbatim}
}

The four \ \verb#to_<v>_pol# \ functions differ from \ \verb#to_<v># \ 
in that they return {\it polynomial} --- in the given \ 
pp ordering \ {\tt o}, \ \ and variables \ 
[\verb#<v>#$_1$,\verb#<v>#$_2$,\ldots,\verb#<v>#$_n$], \ \ 
$n = \max (1, \ \deg f)$.

{\bf Method.} \\
\verb#to_<v>_pol# \ consists mostly of \ \verb#to_<v>#.\\
Only in the end, it is applied  \ \verb#toDensePP_in_symPol o vars#, \ \
which converts each partition \ $\lambda$ \ from \ {\tt symPol} \ 
into the power product of the length \ $n$ \ by \ {\tt prttToPP}.

Then the polynomial is reordered by \ {\tt o}.
\medskip


\underbar{Method for transformations}

See the preface in the modle \ {\tt AlgSymmF.hs}, \\ 
comments in \ \verb#pol/symmfunc/SymmFn*_.hs#.



\subsubsection{ Other items }
\label{sec-symmf.t.i}  

\footnotesize
\begin{verbatim}
  type PrttParamMatrix a = Map.Map Partition [a]
                      --
                      -- a partition-parameterized matrix over `a' (ptp-matrix)
                      -- is a table of pairs (Partition,Row)

  type SymFTransTab = Map.Map Z ([Partition], PrttParamMatrix Z, PrttParamMatrix Z)
                                 -- pts       tC                 tK
                                                                -- see Preface
  ptpMatrRows :: PrttParamMatrix a -> [[a]] 
  ptpMatrRows tab =  map snd $ sortBy gtLex $ fmToList tab 
                                               where
                                               gtLex (p,_) (q,_) = pLexComp q p

  transpPtP :: PrttParamMatrix a -> PrttParamMatrix a
  transpPtP tab = listToFM $ zip pts $ transpose rows
                        where
                        (pts,rows)        = unzip $ sortBy gtLex $ fmToList tab
                        gtLex (p,_) (q,_) = pLexComp q p
\end{verbatim}
\normalsize
%
The construction of \ $p_i(x_1,\ldots,x_n), \ e_i(x_1,\ldots,x_n)$ \ \
is {\it not} used in the decomposition.
They serve for testing and other needs.

\footnotesize
\begin{verbatim}
  elemSymPols :: CommutativeRing a => Pol a -> Domains1 (Pol a) -> [Pol a]
                                      -- f     dP
\end{verbatim}
\normalsize
Elementary symmetric polynomials \ \ $[e_1,\ldots,e_n]$, \ \ 
$e_i$ from \ $P = R[x_1,\ldots,x_n]$,\\ 
built from given sample polynomial \ {\tt f}; \ 
{\tt dP} \ is the description for $P$.

{\bf Example:} \ \ \ \ \ \ \ \ \ \ \ \ \ {\tt elemSymPols f \$ upRing f Map.empty}
\medskip

builds certain small necessary part of description for $P$, and then, \ 
$[e_1,\ldots,e_n].$

{\bf Method:} \\ 
{\tt let \ g = $ \prod_{i = 1}^n (y+x_i) $ \ \ (of $P[y]$) \ in \ 
                                                 coefficients \$ pTail g
}
%
\footnotesize
\begin{verbatim} 
-----------------------------------------------------
  hPowerSums :: CommutativeRing a => Pol a -> [Pol a] 
\end{verbatim} 
\normalsize
Homogeneous power sums \ \ \ \ \ \ \ \ 
                  $ [p_1, p_2, \ldots], \ \ \ p_i = \prod_{k = 1}^n x_k^i, $
\\
built from given sample polynomial.
%
\footnotesize
\begin{verbatim}
-------------------------------
  h'to_p_coef :: Partition -> Z
  h'to_p_coef    []         = 1
  h'to_p_coef    ((i,m):la) = (factorial m)*(i^m)*(h'to_p_coef la)
  h'to_p_coef    ((i,m):la) = (factorial m)*(i^m)*(h'to_p_coef la)
\end{verbatim}
\normalsize
Coefficient \ $z_{\lambda}$ \ of partition $\lambda$ in the formula \ 
$ h_n = \sum_{|\lambda| = n} \ p_{\lambda}/z_{\lambda} $
\\
expressing the full homogeneous function as a linear combination of  
$p_{\lambda}$ over rational numbers --- 
see (\cite{Ma} 1.2 formula (2.14')).\\
Namely, \ \ \verb#h'to_p_coef# $[(i_1,m_1),\ldots,(i_l,m_l)]$ = 
\  
                     $ \prod_{1 \leq k \leq l} \ i_k^{m_k} m_k! $ 
\\  
This is more direct and nice than iterating the Newton formula.\\
And it is also used in the \ $ e_n \longrightarrow p_{\lambda} $ \ 
decomposition.

\footnotesize
\begin{verbatim}
intListToSymPol :: Ring a =>
                   Char -> SymPol a -> Partition -> [Partition] -> [Z] -> SymPol a
                -- mode    smp         bound        allPts         row
\end{verbatim}
\normalsize
converts integer list \ {\tt row} \ to sym-polynomial under \ 
{\tt pLexComp} ordering, considering \ {\tt row} as numeration of 
partitions.
  
 {\tt smp} \ is the sample sym-polynomial (maybe, not in {\tt pLexComp}).

 {\tt row} \ is an integer list representing a dense homogeneous
       sym-polynomial over {\tt Integer} of positive weight \ $w$: 
       \ \
       {\tt f =} $ \sum_{\lambda \in allPts} i(\lambda) \lambda $ \ \ 
       --- in \ {\tt pLexComp} ordering.
  
  {\tt allPts} \ is the full list of partitions of \ $w$ \  
   ordered decreasingly by \ {\tt pLexComp}.

  {\tt f}  converts to  sym-pol \ {\tt g} over \ {\tt a}, 
            mostly, by filtering out zero monomials.
\medskip
  
  {\tt mode = 'a'} \ \ 
          means to run through all the partitions ignoring `bound',

  {\tt 'u'} \ means the row is zero beyond the segment
                                 \ {\tt [maximal, bound]},

  {\tt 'l'} \ means the row is zero beyond the segment
                                 \ {\tt [bound, minimal]}.
\medskip

This is all used for the integer vectors  {\tt row} \ who are computed
`lazily'.




\subsection{ Examples on symmetric transformation }
% -------------------------------------------------
\label{sec-symmf.e} 


\subsubsection{ Finding discriminant polynomial }
\label{sec-symmf.e.d} 

{\bf Problem:}\\
for the polynomial scheme \ \ \ 
$ f = x^n + c_1 x^{n-1} + c_2 x^{n-2} + c_n, $
\\
derive the algebraic condition on \ $c_i$ \ for \ $f$ \ to have a multiple 
root.

Usually, the algebra guides solve this task as follows.
The searched condition expresses as
$$ 
  0 = d(x_1,\ldots,x_n) = \ (\prod_{1 \leq i < j \leq n} (x_i-x_j))^2,
$$
where  $x_i$  denote the roots of $f$ in some extension field.\\
$d \in \ Z[x_1,\ldots,x_n]$ \ is symmetric, hence it decomposes to \ 
$d = h(e_1,\ldots)$, \ \ 
$h \in \ Z[e_1,\ldots], \ \ e_i$ \ the elementary symmetrics.
And \ $e_i = \ c_i$ \ or \ $-c_i$ \ because of the Viete's formula for \ 
$c_i(x_1,\ldots,x_n)$. \ Hence, decomposing $d$ to $h(e_i)$ with \ 
\verb#to_e_pol# \ gives the needed coefficients of the discriminant 
polynomial. \ Let us program this.
\bigskip

$n$ \ is given. \ $d = discr(n) = d(x_1,\ldots,x_n)$ \ \ 
computes as the element of $Z[x_1,\ldots,x_n]$,  
converts to the sym-pol form \ {\tt discrS} and decomposes to 
{\tt h} $\in \ Z[e_1,\ldots,e_w]$ \ in elementary symmetrics by \ 
\verb#to_e_pol#. \ The result is \ {\tt (discrS, h)}.
\bigskip

{\footnotesize
\begin{verbatim}
--------------------------------------------------------------------------------
import qualified Data.Map as Map (empty)
import DPrelude  (product1)
import SetGroup  (sub)
import Z         (dZ)
import Pol       (PolLike(..), Pol(..),  lexPPO, cToPol)
import Partition (pLexComp)
import AlgSymmF  (SymPol(..), SymmDecMessageMode(..), SymmDecBasisId,
                  toSymPol, to_e_pol
                 )

discrimToE :: SymmDecBasisId -> Integer -> (SymPol Integer, Pol Integer)
discrimToE    basisId           n       =

  let pcp  = pLexComp
      vars = map (('x':) . show) [1..n]      -- ["x1"..."x<n>"]
      o    = lexPPO n
      unP  = cToPol o vars dZ 1              -- 1 of P = Z[x1...xn]
      listDiscr fs = (product1 $ diffs fs)^2
                                 where
                                 diffs [_]    = []
                                 diffs (f:fs) = (map (sub f) fs) ++ (diffs fs)
                                 --
                                 -- example: [a,b,c] -> (a-b)^2*(a-c)^2*(b-c)^2

      xPols       = varPs 1 unP          -- x_i  as polynomials
      discr       = listDiscr xPols
      Just discrS = toSymPol pcp discr
      w           = deg discrS
      messageMode = NoSymmDecMessages
  in
  (discrS,  snd $ to_e_pol messageMode basisId Map.empty (lexPPO w) discrS)

main = let n           = 2                        -- edit this
           basisId     = "mn"                     -- alternative: "m"
           (discrS, h) =  discrimToE basisId n
       in
       putStr $ concat ["discrS =\n", shows discrS "\n\n",
                        "h =\n",      shows h "\n"
                       ]
\end{verbatim}
}
%
Now, run it for \ {\tt n = 2, 3, 4, 5}.
The result size seems to grow exponentially in {\tt n}.

In {\tt DoCon-2.11}, the {\tt "mn"} way occurs in this example {\tt n} 
times faster than {\tt "m"} \ \ --- for \ {\tt n = 2, 3, 4, 5}.

\footnotesize{
\begin{verbatim}
  n = 2.  discrS = SymPol [(1, [(2,1)]), (-2, [(1,2)])] _ _ _# 
                                              -- does not depend on  vars
  h = e1^2 - 4*e2
  --------------------------------------------------------------------
  n = 3.  discrS = SymPol [(1, [(4,1),(2,1)]), (-2, [(4,1),(1,2)] ), 
                           (-2,[(3,2)]),      (2, [(3,1),(2,1),(1,1)]),
                           (-6,[(2,3)])
                          ] _ _ _
  h = -4*e1^3*e3 + e1^2*e2^2 - 8*e1^2*e4 + 18*e1*e2*e3 - 4*e2^3 
        + 24*e2*e4 - 27*e3^2
  --------------------------------------------------------------------
  n = 4.  discrS = SymPol [(1,  [(6,1),(4,1),(2,1)]),
                           (-2, [(6,1),(4,1),(1,2)]) ... (24, [(3,4)])
                          ] _ _ _
  h = 24*e1^4*e3*e5 - 27*e1^4*e4^2 - 8*e1^3*e2^2*e5 + 
      ...
      + 200*e2*e5^2 - 27*e3^4 + 216*e3^2*e6 - 480*e3*e4*e5 + 256*e4^3
  --------------------------------------------------------------------
  (SymPol 1*[8,6,4,2] -2*[8,6,4,1*2] -2*[8,6,3*2] 2*[8,6,3,2,1]
    -6*[8,6,2*3] -2*[8,5*2,2] 4*[8,5*2,1*2] 2*[8,5,4,3] -2*[8,5,4,2,1]
    ...
    -12*[5*3,3,2] 12*[5*2,4*2,2] 12*[5*2,4,3*2] -24*[5,4*3,3] 120*[4*5]
  )
  h = -192*e1^5*e3*e5*e7 + 200*e1^5*e3*e6^2 + 216*e1^5*e4^2*e7 -
      480*e1^5*e4*e5*e6 + 256*e1^5*e5^3 + 72*e1^4*e2^2*e5*e7 -
      75*e1^4*e2^2*e6^2 - 168*e1^4*e2*e3*e4*e7 ...
      ...
      + 5600*e4^2*e5*e7 + 2880*e4^2*e6^2 - 9000*e4*e5^2*e6 + 3125*e5^4
\end{verbatim}
}



\subsubsection{ Other examples }
\label{sec-symmf.e.o} 

\verb#demotest/T_symfunc.hs# \ 
contains the examples with the Kostka and permutation character 
matrices, and others.






\newpage
\section{ Non-commutative polynomials }
% -------------------------------------
\label{sec-noncompol} 


DoCon provides some support for a {\emph free associative algebra over
a commutative ring} \ ({\bf FAA}). 
That is for non-commutative polynomials over a commutative ring. 

For example, for the non-commutative polynomials in \ {\tt x, y} \ 
over {\tt Integer}
\begin{center}
\verb# f = 2*x*3*y = 6*x*y;   g = 3*y*2*x = 6*y*x;   f == g = False#
\end{center}

The corresponding items are re-exported from the module \ {\tt Pol} \
(together with the items for commutative polynomials), \ 
and they are defined in the modules 
\begin{center}
               \verb# FreeMonoid, FAA0_, FAANF_ # 
\end{center}

The aim was some Gr\"obner basis analogue for FAA: 
although such an algorithm may not terminate in non-commutative case, it 
still can be useful.

But we stopped, so far, at defining some arithmetics for FAA and 
reduction to the normal form ({\tt polNF} analogue).




\subsection{ FreeMonoid }
% -----------------------
\label{sec-noncompol.pp} 

The power products for non-commutative polynomials form a free 
(non-commutative) monoid.

See the comments below:


\footnotesize{
\begin{verbatim}
-----------------------------------------------------------------
module FreeMonoid
  (
   FreeMonoid(..), FreeMOrdTerm, 
   freeMN, freeMRepr,  freeMOId, freeMOComp, freeMWeightLexComp,
   freeMGCD
   --
   -- , instance Cast FreeMonoid [(Z,Z)], 
   --   instances  Show .. MulMonoid    for  FreeMonoid
  )
where
...


data FreeMonoid = FreeM (Maybe Z) [(Z,Z)]  deriving (Show, Eq)

-- Free monoid generated by anonymous generators.
--
-- (FreeM (Just n) _)  means the generator set   {No 1, No 2...No n}
-- (FreeM Nothing  _)  means infinite generator set:  {No 1 ...} 
-- 
-- Example:  
-- (non-commutative) monomial  x1*x3^2*x6^5  <- R<x1..x11>
-- can be represented as       FreeM (Just 11) [(1,1),(3,2),(6,5)]

freeMN :: FreeMonoid -> Maybe Z
freeMN  (FreeM mn _) =  mn

freeMRepr :: FreeMonoid -> [(Z,Z)] 
freeMRepr  (FreeM _ ps) =  ps 

instance Cast FreeMonoid [(Z,Z)] 
  where
  cast _ (FreeM nm _) ps = FreeM nm ps            -- without check 

--------------------------------------------------------------------
instance Set FreeMonoid 
  where
  showsDomOf (FreeM mn _) = case mn of
                                 Just n -> ("FreeMonoid_of(g_1,...,g_"++) . shows n
                                 _      -> ("FreeMonoid_of[g_1,g_2,...]"++) 

  baseSet (FreeM mn _) dm =  dummy ....
  compare_m _ _ = 
          error "compare_m  is not defined for FreeMonoid, so far\n"
  fromExpr _ = 
          error "fromExpr  is not defined for FreeMonoid, so far\n"


--------------------------------------------------------------------
instance MulSemigroup FreeMonoid 
  where
  baseMulSemigroup _ = 
               error "baseMulSemigroup (FreeM..):   dummy, so far\n"

  unity_m f = Just $ ct f ([] :: [(Z,Z)])

  mul (FreeM mn ps) (FreeM mn' ps') =  ...   
    --
    -- multiplication of non-commutative power products

  inv_m f = if f == (unity f) then Just f else Nothing

  power_m = SetGroup.powerbin        -- binary method for powering

  root _ (FreeM _ _) = error "root n (FreeM..):   skipped\n"

  divide_m f g = fmap (ct f) $ dv (freeMRepr f) (freeMRepr g)
          --
          -- q = f/g  means that  q*g = f :  g is a suffix word of f
          -- Examples:  (x*y, y) -> Just x;  (y*x, y) -> Nothing

  divide_m2 f g = (divide_m f g, divR f g, biDiv f g)
       where
       divR f g = fmap (ct f) $ divRRepr (freeMRepr f) (freeMRepr g)
...


biDiv :: FreeMonoid -> FreeMonoid -> Maybe (FreeMonoid, FreeMonoid)
  --
  -- LOCAL.
  -- biDiv f g = Just (l,r),  if f= l*g*r  (any such pair returned),
  --             Nothing,     if there does not exist such pair.
...


--------------------------------------------------------------------
instance MulMonoid FreeMonoid
 
freeMGCD :: FreeMonoid -> FreeMonoid -> (FreeMonoid, FreeMonoid)

  -- freeMGCD f g = (gcdl f g, gcdr f g),  
  -- where  
  -- gcdl  is the greatest left  factor in  f  which is a right 
  --       factor in  g,
  -- gcdr  is the greatest right factor in  f  which is a left  
  --       factor in  g.


-- Grading, comparison on FreeMonoid  ------------------------------

type FreeMOrdTerm = (PPOId, Comparison FreeMonoid)

freeMOId   :: FreeMOrdTerm -> PPOId
freeMOComp :: FreeMOrdTerm -> Comparison FreeMonoid
freeMOId   = fst
freeMOComp = snd


-- usable comparisons ----------------------------------------------

freeMWeightLexComp ::
                   (Z -> Z) -> FreeMonoid -> FreeMonoid -> CompValue
                   -- weight
  -- Compare non-commutative pp by  totalWeight  first, then, 
  -- if equal, compare lexicographically by  xi.
  -- totalWeight  is defined as below by the given map 
  --                                                  \x -> weight x 

freeMWeightLexComp weight pp pp' = 
  (case 
       (compare (totalWeight ps) (totalWeight qs), lcomp ps qs)
   of 
     (EQ, v) -> v  
     (v,  _) -> v
  )
  where
  (ps, qs)    = (freeMRepr pp, freeMRepr pp')
  totalWeight = sum . map (\ (x,e) -> (weight x)*e)

  lcomp []         []           = EQ
  lcomp []         _            = LT
  lcomp _          []           = GT
  lcomp ((x,e):ps) ((x',e'):qs) = case (compare x x', compare e e')
                                  of 
                                    (LT, _ ) -> GT
                                    (GT, _ ) -> LT
                                    (_,  EQ) -> lcomp ps qs
                                    (_,  v ) -> v
\end{verbatim}
}






\subsection{ Free associative algebra: arithmetics }
% --------------------------------------------------
\label{sec-noncompol.faaarith} 


\footnotesize{
\begin{verbatim}
--------------------------------------------------------------------
module FAA0_    
  (
   module FreeMonoid,

   FAA(..), FAAMon, FAAVarDescr,
   faaMons, faaFreeMOrd, faaVarDescr, faaN, faaVMaps, faaFreeMOId,
   faaFreeMOComp, faaLM, faaLeastMon, faaLPP, reordFAA ,
   faaMonMul, faaMonFAAMul, cToFAA, faaToHomogForms

   -- instances for FAA :
   --   Dom, Eq, Show,  Cast (FAA a) (FAAMon a), 
   --                   Cast (FAA a) [FAAMon a], Cast (FAA a) a,
   --   PolLike FAA,    Set .. Ring, Fractional
  )
where
...

--------------------------------------------------------------------
type FAAMon a = (a, FreeMonoid)                      -- FAA monomial

type FAAVarDescr = (Maybe Z, (Z -> Maybe PolVar, PolVar -> Maybe Z))
  --                mn        toStr              fromStr     
  --
  -- mn       is as in FreeMonoid.
  -- variable indices range in   iRange = [1 .. upp],  
  -- upp = n  (case mn = Just n)  or  infinity  (case mn = Nothing).
  -- toStr    shows variable as string, it is defined on iRange  and 
  --          produces  Just str  for some (showable) indices.  
  -- fromStr  is the reverse to  toStr,  it produces  Just index
  --          for a variable name which corresponds to some index
  --          in iRange. 


data FAA a = FAA [FAAMon a] a FreeMOrdTerm FAAVarDescr (Domains1 a)
--
-- (element of) Free associative algebra 
-- - non-commutative polynomial.
-- The monomials are ordered similar as in polynomials.
-- The below  Show  and  Set  instances for FAA allow to print a
-- non-commutative polynomial displaying it is a given variable 
-- system  and  reading it from expression in this variable system.


instance Dom FAA where  dom    (FAA _ _ _ _ d) = d
                        sample (FAA _ c _ _ _) = c

faaMons         :: FAA a -> [FAAMon a]
faaFreeMOrd     :: FAA a -> FreeMOrdTerm
faaVarDescr     :: FAA a -> FAAVarDescr
faaN            :: FAA a -> Maybe Z
faaVMaps        :: FAA a -> (Z -> Maybe PolVar, PolVar -> Maybe Z)
faaFreeMOId     :: FAA a -> PPOId
faaFreeMOComp   :: FAA a -> Comparison FreeMonoid

faaMons     (FAA ms _ _ _  _) = ms
faaFreeMOrd (FAA _  _ o _  _) = o
faaVarDescr (FAA _  _ _ vd _) = vd
faaN                          = fst . faaVarDescr 
faaVMaps                      = snd . faaVarDescr 

faaFreeMOId   = freeMOId   . faaFreeMOrd
faaFreeMOComp = freeMOComp . faaFreeMOrd

faaLM, faaLeastMon :: (Set a) => FAA a -> FAAMon a

faaLM f = case faaMons f of  m:_ -> m
                             _   -> error ...

faaLeastMon f = case faaMons f of  m:ms -> last (m:ms)
                                   _    -> error ...

faaLPP :: Set a => FAA a -> FreeMonoid
faaLPP             f     =  case faaMons f of (_,p):_ -> p
                                              _       -> error ...

instance (Eq a) => Eq (FAA a) where  f==g = (faaMons f)==(faaMons g)

reordFAA :: FreeMOrdTerm -> FAA a -> FAA a   -- bring to given ordering
                                             --
reordFAA o (FAA ms c _ vd dom) = FAA (sortBy cmp ms) c o vd dom
                                      where
                                      cmp (_,p) (_,q) = cp q p
                                      cp              = freeMOComp o


--------------------------------------------------------------------
instance (AddGroup a) => Cast (FAA a) (FAAMon a)
  where
  cast mode (FAA _ c o vd d) (a,p) = FAA mons c o vd d
             where
             mons = if  mode=='r' && isZero a  then []  else [(a,p)]

instance (AddGroup a) => Cast (FAA a) [FAAMon a]
  where
  cast mode (FAA _ c o vd d) mons =  FAA ms c o vd d
    where                                       -- order NOT checked
    ms = if  mode /= 'r'  then  mons
         else                   filter ((/= z) . fst) mons
    z  = zeroS c


instance (AddGroup a) => Cast (FAA a) [(a, [(Z,Z)])]
  where
  cast mode f preMons = cast mode f 
                        [(a, FreeM (faaN f) ps) | (a,ps) <- preMons]

instance (Ring a) => Cast (FAA a) a
  where
  cast mode (FAA _ _ o vd d) a =  case (mode, isZero a) of

                ('r', True) -> FAA []                       a o vd d
                _           -> FAA [(a, FreeM (fst vd) [])] a o vd d

--------------------------------------------------------------------
instance PolLike FAA
  where
  pPPO     _   = error "pPPO (FAA _):   use  faaNCPPO  instead\n"
  lm       _   = error "lm (FAA _):   use  faaLM  instead\n"
  lpp      _   = error "lpp (FAA _):  use  faaLPP  instead\n"
  pCoef    _ _ = error "pCoef  is not defined for  FAA R\n"
  pFromVec _ _ = error "pFromVec  is not defined for  FAA R\n"
  pToVec   _ _ = error "pToVec  is not defined for  FAA R\n"
  pDeriv   _   = error ("pDeriv (FAA _):   derivative skipped, so "
                        ++"far, for non-commutative polynomial\n"
                     )
  pMapPP  _ _ = error "pMapPP f (FAA _):  not defined\n"
  pDivRem _ _ = error "pDivRem  is not defined so far for  FAA R\n"
  pValue  _ _ = error "pValue   is not defined so far for  FAA R\n"

  pIsConst f = case faaMons f of (_, p):_ -> p == unity p
                                 _        -> True

  pVars f = catMaybes $ map toStr js  
                        where 
                        (mn, (toStr,_)) = faaVarDescr f
                        js           = case mn of Just n -> [1 .. n]
                                                  _      -> [1 ..  ]
  pCoefs  = map fst . faaMons

  pTail f = case faaMons f of _:ms -> ct f ms
                              _    -> error ...

  pFreeCoef (FAA mons c _ _ _) =
                let  { z = zeroS c;  (a,p) = last mons }
                in
                if  null mons  then  z
                else                 if p == (unity p) then a else z

  ldeg f = case faaMons f of (_,p):_ -> sum $ map snd $ freeMRepr p
                             _       -> error ...

  deg f = case  map (sum . map snd . freeMRepr . snd) $ faaMons f
          of
            d:ds -> maximum (d:ds)
            _    -> error ...

  degInVar for0 i f =
    --
    -- Put degree of i-th variable in monomial to be the sum of
    -- degrees of its occurences. 
    -- Example:   if    faaMons f = [(1,1),(2,2),(5,3),(2,6)] 
    --            then  degInVar _ 2 f = 8
    (case  
         (i >= 0, faaMons f)
     of
      (False, _ ) -> error $ msg "\n\nPositive i needed\n"
      (_,     []) -> for0
      (_,     ms) -> maximum $ map (degInMon i . freeMRepr . snd) ms
    )
    where
    degInMon i = sum . map snd . filter ((== i) . fst)

    msg = ("degInVar for0 i f,  \ni = "++) . shows i .
          ("\nf <- FAA R,  R = "++) . showsDomOf (sample f) 


  pCDiv f c =  ...  

  pMapCoef mode f g = cast mode g [(f a, pp) | (a,pp) <- faaMons g]
 
  varPs a f = [ctr f [(a, FreeM mn [(i,1)])] | i <- range]
                               where
                               mn    = faaN f
                               range = case mn of Just n -> [1 .. n]
                                                  _      -> [1 ..  ]

--------------------------------------------------------------------
faaMonMul :: (Ring a) =>  a -> FAAMon a -> FAAMon a -> [FAAMon a]
                        --zero
                                                        -- product of monomials
faaMonMul z (a,p) (b,q) = let c = a*b in  if  c==z  then  []
                                          else        [(c, mul p q)]


faaMonFAAMul :: (Ring a) => FAAMon a -> FAA a -> (FAA a, FAA a)
  --
  -- multiply FAA element f by FAA monomial m forming the pair 
  -- (m*f, f*m)
  --
faaMonFAAMul (a,p) f = (ctr f [(a*b, mul p q) | (b,q) <- faaMons f],
                        ctr f [(b*a, mul q p) | (b,q) <- faaMons f]
                       )

                                               -- coefficient to FAA
cToFAA :: (Ring a) => 
          FreeMOrdTerm -> FAAVarDescr -> Domains1 a -> a -> FAA a
cToFAA    ord             varDescr       dom           a =
                                         FAA mons a ord varDescr dom
      where 
      mons = if isZero a then [] else [(a, FreeM (fst varDescr) [])]
                       

faaToHomogForms ::
         (AddGroup a, Eq b) => (FreeMonoid -> b) -> FAA a -> [FAA a]
                               -- weight map
faaToHomogForms w f =
  map 
     (ct f) $ partitionN (\ (_,p) (_,q) -> (w p)==(w q)) $ faaMons f
       --
       -- (non-ordered) list of homogeneous forms of non-commutative 
       -- polynomial over `a'  with respect to 
       -- weight :: PowerProduct -> b


instance (Ring a) => Show (FAA a) 
  where 
  showsPrec _ (FAA mons c _ varDescr dom) =  ...
  --
  -- If  a  is and Ordered ring, then the mode `ord'  is set which
  -- writes ..- m  instead of ..+(-m) for the negative coefficient
  -- monomials.
  -- If  a  has unity  then unity coefficient images  are skipped.


--------------------------------------------------------------------
instance (CommutativeRing a) => Set (FAA a)
  where
  compare_m    = compareTrivially
  fromExpr     = fromexpr_
  showsDomOf f = ("FAA("++) . shows (faaN f) . (',':) . 
                 showsDomOf (sample f) . (')':)

  baseSet _ _ = error "baseSet (FAA..):  dummy, so far \n"


--------------------------------------------------------------------
instance (CommutativeRing a) => AddSemigroup (FAA a)
  where
  add       = add_
  zero_m f  = Just $ ctr f $ zeroS $ sample f
  neg_m     = Just . neg_
  times_m f = Just . (times_ times f)

  baseAddSemigroup _ _ = error "baseAddSemigroup (FAA..):  dummy, so far\n"

instance (CommutativeRing a) => AddMonoid (FAA a)

instance (CommutativeRing a) => AddGroup (FAA a)
  where
  baseAddGroup _ _ = error "baseAddGroup (FAA..):  dummy, so far\n"
                

instance (CommutativeRing a) => MulSemigroup (FAA a)
  where
  unity_m f = fmap (ct f) $ unity_m $ sample f

  mul f g = case faaMons f of 
                       []  -> zeroS f
                       m:_ -> (fst $ faaMonFAAMul m g) + (pTail f)*g

  inv_m f = if  isZero f || not (pIsConst f)  then  Nothing
            else                          fmap (ct f) $ inv_m $ lc f

  divide_m f g =
    let
       zeroP = zeroS f
    in
    case (f == zeroP, g == zeroP)
    of
      (True, _   ) -> Just zeroP
      (_   , True) -> Nothing
      _            -> let (q,r) = pDivRem f g
                      in  if isZero r then Just q  else Nothing

  divide_m2 _ _ = error "divide_m2  is not defined for ..=> FAA a  so far\n"
  root _ _      = error "root  is not defined for ..=> FAA a  so far\n"

  -- power  is the default

  baseMulSemigroup _ _ = error "baseMulSemigroup (FAA..):  dummy, so far\n"


instance (CommutativeRing a, MulMonoid a) => MulMonoid (FAA a)

instance (CommutativeRing a) => Num (FAA a)  
  where 
  negate = neg
  (+)    = add
  (-)    = sub
  (*)    = mul
  signum _      = error "signum  is not defined for ..=> FAA a  ... "
  abs    _      = error ("abs  is not defined for ..=> FAA a  ..."
  fromInteger _ = error "fromInteger  to (FAA _):  use  fromi, fromi_m\n"

instance (CommutativeRing a) => Fractional (FAA a) 
  where
  (/) = divide
  fromRational _ = error ("fromRational  to (FAA _):  \n"++
                          "use  fromi, fromi_m  combined with  divide_m\n"
                         )

instance (CommutativeRing a) => Ring (FAA a)
  where
  fromi_m f    = fmap (ctr f) . fromi_m (sample f)
  baseRing _ _ = error "baseRing (FAA..):  dummy, so far\n"
\end{verbatim}
}




\subsection{ Free associative algebra: reduction }
% ------------------------------------------------
\label{sec-noncompol.reduc} 


\footnotesize{
\begin{verbatim}
--------------------------------------------------------------------
module FAANF_ (faaNF)   

-- Reduction to Groebner Normal Form of non-commutative polynomial
-- over a Commutative Ring.
-- Its main difference from  polNF  is in that it bases on different
-- kind of division on power products (in free monoid).
...

faaNF :: (EuclideanRing a) => String -> [FAA a] -> FAA a ->
                              -- mode   gs         f        

 ((FAA a,[FAA a]), (FAA a,[FAA a]), (FAA a,[[(FAAMon a,FAAMon a)]]))
 -- lrem lqs        rrem  rqs        biRem biQs

  -- Non-commutative analogue for  polNF.
  -- mode   is as in polNF.
  --
  -- (lrem,lqs)   is the reduction result for  LeftIdeal(gs): 
  --                                                 f - q1*g1 -...,
  -- (rrem,rqs)   -- for RightIdeal(gs):             f - g1*q1 -...,
  --
  -- biRem        -- remainder for DoubleSidedIdeal(gs): 
  --                                      biRem = f - m1*g1*m1' -...
  --   For  gs = [g_1..g_k] 
  --   each qq_i <- biQs is  [(m_i_1,m_i_1')..(m_i_l(i),m_i_l(i)')],
  --   and it represents a linear combination 
  --           comb_i = m_i_1*g_i*m_i_1' +..+ m_i_l(i)*g_i*m_i_l(i)'
  --   to substract from f.
  --
  -- To understand the below program, read first the commutative 
  -- case: polNF.
\end{verbatim}
}




 
\newpage
\section{ Parsing. More details }
% -------------------------------
\label{sec-pars} 

See Section~\ref{sec-prp.pars}.\\
The items for parsing are exported from the module \ {\tt DPrelude},\\
implemented in \ \verb#parse/Iparse_.hs, parse/OpTab_.hs#

{\tt (fromExpr sample e)} \ \
interprets algebraically the expression \ {\tt e} \ 
according to {\tt sample}. \ 
This \ {\tt e} \ is a data organized into a \ {\it tree}, 
and it often has to be parsed from the \ {\tt String}.  
This parsing is performed by the \ {\tt infixParse} \ function 
described below.
The techique of the below infix operation parsing bases on the well 
known finite automaton principle. 

Certain new details, like the arbitrary left-hand and right-hand
arities and priorities, were taken from the design of the {\tt FLAC} 
functional programming system where it was developed by A.P.Ne\-my\-tykh 
and S.V.Chmu\-tov.

\footnotesize
\begin{verbatim}
  data Expression a =  L a | E (Expression a) [Expression a] [Expression a]
                       deriving (Eq, Show, Read)
\end{verbatim}
\normalsize
{\tt a} \ is a type of lexeme, \ \ {\tt L} \ a tag of a lexeme expression,
\\
{\tt E} \ a tag of a non-lexeme expression.

{\tt (E op ls rs)} \ \ 
denotes an expression which is an application of an 
{\it operation expression} \ {\tt op}; \
the left-hand argument list for {\tt op} is \ {\tt ls}, \ 
the right-hand argument list is \ {\tt rs}.

Usually, \ {\tt op} \ is a lexeme. For example \ {\tt (L "++")}.

{\bf Example:}\\ 
if \ {\tt a = String}, \ then \ \verb#"(1+ 22)*- 3a "# \ 
may parse to the expression
\footnotesize
\begin{verbatim}
                 (E  (L "*")  [ (E (L "+") [L "1"] [L "22"]) ]
                              [ (E (L "-") []      [L "3a"]) ]  
                 )

--------------------------------------------------------------------
lexLots :: String -> [Expression String]

  -- Break string to the list of lexemes - according to standard
  -- {\tt Haskell} set of delimiters.
  -- Example:  (lexLots  " {2+ 33}*3 " )  ->
  --           [ L "{", L "2", L "+", L "33", L "}", L "*", L "3" ]

lexLots xs = case lex xs of [("", _  )] -> []
                            [(lx, xs')] -> (L lx):(lexLots xs')
                            _           -> []
 
showsExpr :: Show a => Expression a -> String -> String  --pretty printing expression

-- Infix Operation Table  ------------------------------------------

type OpDescr = (Z, Z, Z, Z)
               -- (left arity, right arity, left precedence, right precedence)

type OpGroupDescr a = (a, (Maybe OpDescr, Maybe OpDescr, Maybe OpDescr))
                           -- 0r_class    l0_class       lr_class
\end{verbatim}
\normalsize
{\tt a} \ is a type of \ {\it operation name}.  
For example, \ \verb#"+."# \ may be an operation name --- if\\ 
{\tt a = String}.
  
Each operation name corresponds to some {\it group} of the three 
possible operations of class

 {\tt (0,r)} --- prefix  operation of arity {\tt r}, \ say \ {\tt -x},

 {\tt (l,0)} --- postfix operation of arity {\tt l}, \ say \ {\tt n!},

 {\tt (l,r)} --- general infix operation of arities {\tt l, r}, \ 
                 say, \ {\tt x+y}.
\medskip
    
\verb#ij_class = Nothing# \ \ 
means that the given operation name cannot denote an operation of 
class {\tt (i,j)}.
\medskip

{\bf Example 1:}
         
{\tt ("+", \ (Just (0,1,210,190), Just (1,1,100,100), Nothing) )}
\\  
describes the group \ {\tt "+"} \ which may denote either a prefix
operation of arity 1, or a mixed operation of arities 1, 1.
\medskip

{\bf Example 2:}

{\tt  (":", \ (Nothing, Just (1,1,60,50), Nothing)) }
\\
contained in the standard {\tt DoCon} table describes the binary
operation symbol which usually denote the \ {\tt List} \ constructor. 
\\
Similar is the pair constructor \ {\tt ","}. Thus, \ \  
\verb#"(1:2-3:nil, a+1)"# \ \ would parse to
\footnotesize
\begin{verbatim}
       (,  [:  [1]  [: [- [2] [3]] [nil]]  ]
           [, [+ [a] [1]] ]
       )                       -- we omit here the double quotes and ().
\end{verbatim}
\normalsize
Study the module \ \verb#OpTab_.hs# \ \ to get a more definite idea of 
how to set the standard infix operations and how to define the new ones.

\footnotesize
\begin{verbatim}
  type OpTable a = [OpGroupDescr a]       -- this contains all the operations
                                          -- that are processed by `infix'
  getOp :: Eq a => OpTable a -> a -> Maybe (OpGroupDescr a)
                                              -- get operation group from table
  getOp xs x = case dropWhile ((/= x) . fst) xs of []    -> Nothing
                                                   (y:_) -> Just y
  type ParenTable a = [(a,a)]
\end{verbatim}
\normalsize
A \ {\it parenthesis} \ may be any lexeme from \ {\tt a}.

{\tt ParenTable} \ lists all the allowed parentheses pairs.

{\tt parenTable} \ 
is the standard {\tt DoCon} parenthesis list: see \ \verb#OpTab_.hs#

So, \ \ {\tt lookup x parenTab} \ \ returs either \ {\tt Nothing} \ \ or 
\\
\verb#Just oppositeTo_x_parenthesisLexeme#

\footnotesize
\begin{verbatim}
  infixParse :: (Eq a, Read a, Show a) => 
                ParenTable a-> OpTable a-> [Expression a]-> ([Expression a], String)
                -- pT          oT          xs
\end{verbatim}
\normalsize
Parsed is a list \ {\tt xs} \ of expressions some of which may be 
lexemes, say \ {\tt (L "x1")}.

Parenthesis or an infix operation sign should be a lexeme, say
\ {\tt (L "\{"), (L "+")}.
The lexeme expression list can be parsed by \ \verb#lexLots <string>#.

The infix parser "sets the parentheses" in \ {\tt xs} \ 
according to the tables \ {\tt parenTable, opTable}.

It returns \ \verb#(expression_list, message)#. \ \ Here

{\tt message == ""} \ \ when the parse succeeds.
                       In this case \ \verb#expression_list == [e]#.

  Otherwise, \ {\tt message} \ 
  is non-empty and tells what is wrong in the input syntax.
\medskip



\underbar{Examples}

\footnotesize
\begin{verbatim}
  Let  pT = parenTable;  opT = opTable.

  (infixParse pT opT (lexLots  " x-  ab*20" ))  -->

                 ( [E  (L "-")  [L "x"]  [E (L "*") [L "ab"] [L "20"]] ],  "" )

  (infixParse pT opT (lexLots  "0--2" ))   -->
                     ( [E  (L "-")   [L "0"]  [E (L "-") [] [L "2"]]  ],  "" )

  (infixParse pT opT (lexLots  "* 2"           )) -->  ([], "wrong arity for *")
  (infixParse pT opT (lexLots  "- 2)"          )) -->  ([], "no left ( for )"  )
  (infixParse pT opT (lexLots  " (x+1)^2:nil " )) -->
                 ( [E  (L ":")
                          [ E  (L "^")   [E (L "+") [L "x"] [L "1"]]  [L "2"] ]
                       [L "nil"]
                   ],
                   ""
                 )
\end{verbatim}
\normalsize
See \ \verb#parse/princip.txt# \ for the illustration of the method.


\newpage
\section{ Language extension proposal }
% -------------------------------------
\label{sec-lne}  

We think, the following language features will make {\tt Haskell} 
fit better the needs of programming mathematics:
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt (dtp)}   \ dependent types,
\item {\tt (der)}   \ more `deriving' abilities,
\item {\tt (overl)} \ extended polymorphism for values and instance overlap,
\item {\tt (dc)}     \ automatic conversion between types (domains), 
\item {\tt (recat)} \ reorganising standard algebraic categories,
\item {\tt (es)}    \ equational simplifier annotations.
\end{itemize}



\subsection{ Dependent types }
% ----------------------------
\label{sec-lne.dtp} 

The example of computing in  $Z/(m)$, \ \cite{Me2} \ sets a question of
the {\tt Haskell} type system fitness for programming mathematics.
A domain depending on a value parameter cannot be expressed as an  
{\tt Haskell} type. So, {\tt DoCon} applies the SA approach.
But it looks that the dependent types language extension should be 
the most adequate approach.  
See, for example, the {\tt Aldor} \cite{Al} and {\tt Cayenne} \cite{Au}
languages.
   


\subsection{ More `deriving' abilities }
% --------------------------------------
\label{sec-lne.der} 

Imagine the program with the instances 
\footnotesize
\begin{verbatim}
                instance <C1 a> => D1 (T a) where ...
                instance <C2 a> => D2 (T a) where ...
                instance <C3 a> => D3 (T a) where ...
                instance <C4 a> => D4 (T a) where ...
\end{verbatim}
\normalsize
for the type constructor \ {\tt T}. \ And for another type 
\begin{flushright}
                       {\tt data D a = D a    \hspace{70mm}  (1)}
\end{flushright}
we define explicitly the functions, the reciprocally inverse 
bijections: 
\begin{center}  
    {\tt  b :: D a -> T a, \ \ b' :: T a -> D a, \ \ b . b' = b' . b = id}
\end{center}
Then, it should be clear what we might mean by declaring
\footnotesize
\begin{verbatim}
               data D a = D a  derivingBy(T, b, b', D1, D2, D3)            (1')
               instance ... => D4 (D a) where ...
\end{verbatim}
\normalsize
This means that \ {\tt D$_1$, D$_2$, D$_3$} \ are `copied' from \ 
{\tt (T a)} \ to \ {\tt (D a)} \ according to the maps\\ 
{\tt b, b'}, \ while \ {\tt D4 (D a)} \ is defined specially.

That is each operation \ {\tt op} \ of the class \ {\tt D$_i$} 
is defined for \ {\tt (D a)} by mapping necessary arguments to \ 
{\tt (T a)}, applying \ {\tt op} \ and mapping the result 
(if necessary) back to \ {\tt (D a)}.


\newpage
{\bf Examples.}

1. Binary operation  \ \ {\tt op :: T a -> T a -> T a}  \ \ 
   induces \ {\tt op} \ for \ {\tt D a}:

   {\tt op (D x) (D y) = \ b' (op (b (D x)) (b (D y)))}
\medskip

2. The \ {\tt Ring} operation of integer image  
                              \ {\tt fromi :: T a -> Integer -> T a}
\\
induces \ {\tt fromi} \ for \ {\tt D a} : \ \ 
                      {\tt fromi (D x) n = b' (fromi (b (D x)) n)}
\medskip

3. The set cardinality \ {\tt card :: T a -> Integer} 
\\ 
might induce  \ \ {\tt card (D x) = card (b (D x))}
\medskip

Maybe, the investigation \cite{HJ} will have its practical result in  
the language development and help to solve the above problem.
The implementation by \cite{GH} announces some tool for this.



\subsection{ Extended polymorphism for values and instance overlap }
% ------------------------------------------------------------------
\label{sec-lne.overl} 

Consider the example of the matrix determinant programming.
We would like to program it like this:
\footnotesize
\begin{verbatim}
  det :: CommutativeRing a => [[a]] -> a
  det                         mM    =    ... expand_by_row method

  det :: Field a => [[a]] -> a
  det               mM    =    ... Gauss method
\end{verbatim}
\normalsize
The former method is more generic, the latter method is more 
efficient --- while both should be called \ {\tt det} \ in the interface. 
Because \ {\tt det} \ is a classic name in mathematics.
This is a common situation.

{\tt Haskell-98} rejects this as the double definition for \ {\tt det}.
Therefore {\tt DoCon} provides the functions \ \verb#det_euc, det# \ \ 
of the corresponding types.
And this is a bad style: the same maps (values) have better to be
called the same.
Neither would help making \ {\tt det} \ an operation of a class, say 
\ {\tt WithDet}.
Because {\tt Haskell-2-pre} does not resolve such kind of the instance
overlaps --- with the different type contexts.

Instead, this is how it should be:
since  \ {\tt CommutativeRing a} \ \ is a superclass of \ 
{\tt Field a}, \ the compiler has to substitute the latter definition  
of \ {\tt det} \ everywhere in the program where it derives \ 
{\tt Field a}, \ \ and the former definition --- in other places, 
where only \ {\tt CommutativeRing a} \ was checked.

For the more complex overlaps, the programmer might set \ 
\verb#{instanceOrder n}#  \ in some of the function type declarations.
{\tt instanceOrder} \ is the suggested reserved word.
This means the {\it ad hoc} resolution.
When the data belongs to several types for different definitions of
a function \ {\tt f}, the compiler chooses the definition of \ 
{\tt f} \ with the smaller \ {\tt n :: Integer}.
Skipping \ {\tt instanceOrder} has to set the default value for \ 
{\tt n}.
\medskip

\underbar{Instance overlaps}
\medskip

Similarly, the extended instance overlaps can be resolved --- which is 
as important as for ordinary values. For example, the definitions
\footnotesize
\begin{verbatim}
  instance Ring a     => LeftModule a       a where  cMul = (*)
  instance AddGroup a => LeftModule Integer a where  cMul = flip times
\end{verbatim}
\normalsize
look quite natural mathematically. But these instances overlap at \ \  
{\tt a = Integer}, \ \ and {\tt Haskell-2-pre} cannot resolve this
overlap.
This has to be improved in the same manner as above with \ {\tt det}.



\subsection{ Automatic conversion between types (domains) }
% ---------------------------------------------------------
\label{sec-lne.dc} 

Consider the task of computation of
\footnotesize
\begin{verbatim}
                     a = 1 + 1:%2
                     f = (2*x + 3*y)*(4*x^2 + 5*y^2)
                     g = (1:%2) * x,
\end{verbatim}
\normalsize
where \ {\tt x} \ is the integer polynomial in variable \ {\tt "x"} \ 
(belongs to $Z[x]$),
   
{\tt y} \ polynomial in \ {\tt "y"} with coefficients from $Z[x]$.

We also presume that the program has to prepare once some
`environment' values before starting to compute many expressions 
like \ {\tt a, f, g}.

According to mathematical common sense, the domains of these values 
have to be respectively
\footnotesize
\begin{verbatim}
               Q  = Fraction Z, 
               PP = (Z[x])[y]        (UPol (UPol Z)    ),
               QX = Q[x]             (UPol (Fraction Z))
\end{verbatim}
\normalsize
With {\tt Haskell-2-pre}, the problem is here in the need of 
explicit and implicit value conversion between the domains.
In DoCon, the \ {\tt cast} \ operation does half of this job.
First, it has to generalize to the \ {\tt Convertible a b} \ 
class, to be able to force several constructor levels.
But this possibility is reduced by the restriction on overlapping 
instances --- see Section~\ref{sec-lne.overl}.

Second, the implicit conversion is needed too. For example, 
the above expression\\ 
\verb#(1:%2) * x# \ \
might be converted automatically by the compiler to \ \ 
\verb#(ctr x (1:/2)) * x#, \ \ 
and only then --- compiled as usual. 
Though, this has to occur only in a program scope marked with some
appropriate reserved word.
Here  \ {\tt ctr} \ is the casting by sample 
(Section~\ref{sec-prp.ske} CS).




\newpage
\subsection{ Reorganising standard algebraic categories }
% -------------------------------------------------------
\label{sec-lne.recat} 

  
{\tt Haskell-98} declares the algebraic categories like  

   {\tt Num, Fractional, Integral} \ with the operations  
\ \verb#+, *, /# \ \ldots 

And their definitions do not agree with what a mathematician would
expect. Though {\tt DoCon} coexists peacefully with these classes, with the
{\tt Haskell-98} Prelude, it is still better to reformulate the  
standard {\tt Haskell} algebraic categories as it is suggested in 
\cite{Me2}.



\subsection{ Equational simplifier annotations }
% ----------------------------------------------
\label{sec-lne.es} 

The compiler developers are considering the optimizations like
\\
{\tt  map f . map g --> map (f . g) }
\ \
to be performed at the compilation stage.
Similarly, many optimizations are possible, like say 
\begin{center}  
{\tt forall x :: Ring a => a \ \ x - x \ --> 0, \ \ \ 
                                                  2*x+2*y --> 2*(x+y)},
\end{center}
and such. The programmer may set the rewrite rules --- or better to 
call them `equations', like
\footnotesize
\begin{verbatim}
  {equations  
   { map f .map g === map (f.g) }

   {x,y,z :: RingWithUnity a => a, (defined x,y,z) ==>

    "df"      (defined  zero, unity, neg x, x*y),
    "assoc+"  x+(y+z)   === (x+y)+z
    ...
    "distr"   x*(y+z)   === x*y + x*z
   }
}
\end{verbatim}
\normalsize
The compiler applies them as rewrite rules to algebraic expressions 
\cite{BL}.
It depends on the programmer-defined {\it strategy}, which equations  
to apply first, and whether it applies the equation from left to right, 
or from right to left.

Example: \ 
changing the term ordering for \ \verb#+, -, *# \ would cause the
distributivity equation applied differently, say \ \ 
{\tt (x+y)*(x-y) --> x*x - y*y} \ \ or the reverse.

The main part of the {\it strategy} is the ordering \ {\tt (<')} \ 
defined on the expressions.
We hope, the methods from \cite{BL,Md} would help to develop the needed
equational simplifier for {\tt Haskell}.

The proposed simplification has to take place at the compile-time,
apply only to the parts inside the \ {\tt \{ eqScope \ldots \} } \ 
marks and may cost differently (for the compilation process), 
depending on the strategy defined by the programmer.

The programs avoiding the word `equations' would remain with the old
{\tt Haskell} treating of expressions.
\medskip

\underbar{Question 1:}
\\
the programmer hardly ever writes directly \ {\tt x-x}. \
How can it appear?

After defining, say \ \ {\tt f x y =} \ldots, \ \ 
the program often applies \ {\tt f} \ differently: 
                
{\tt f b b, \ \ map (f x) [y1,y2,y3], \ \ f . f . g}, \ \ \ and so on.
\\
Evidently, the expressions like \ {\tt x - x} \ often appear this  
way and should be optimized automatically.
\medskip

\underbar{Question 2:}
\\
may the above equations simplify, for example, \ {\tt 1/0 - 1/0 --> 0} \ 
?\\
If yes, then this is incorrect.
Because this changes the program into one not precisely equivalent.
This is the  so-called `undefined' or `bottom' problem in programming.

The matter is that the condition \ {\tt `defined x ==>'} \  
is set in the `equations'.  This condition would not let, for example, 
\ {\tt x - x :: Integer} \ to simplify to \ {\tt 0}.
\\
But, maybe, to \ \ {\tt if x==0 then 0 else 0}. 

Proving `defined' for the variable occurrences, the compiler could
apply correctly the simplifier to various parts of a program.




\newpage
\section{ On gx-rings. Some theory }
% ----------------------------------
\label{sec-gx} 


See first Section~\ref{sec-linr}.

In this section the word `ring' means an
\medskip

   {\it algorithmic Noetherian commutative ring with unity}.

\medskip
A gx-ring is a ring with solvable linear equations
(notion from 20-th century computer algebra), 
and with certain additional properties for canonical remainders.

This describes the situation in which {\tt DoCon} is able to define the 
canonical form and arithmetic algorithms for the residue ring.

The Euclidean ring structure and Gr\"obner basis, with its 
related functions \cite{Bu}, are imporatant special cases of the 
gx-ring, gx-basis notion.

The property names ruling gx-operations are 
\begin{verbatim}
      IsGxRing, IsGxBasis,
      ModuloBasisDetaching, ModuloBasisCanonic,   WithSyzygyGens
\end{verbatim}
And we have to explain here what does it mean \ {\tt IsGxRing}.

Below \ {\tt [A]} \ denotes a set of finite sequences over the set 
\ {\tt A} --- this corresponds to the type \ {\tt [a]} \ in an
{\tt Haskell} program.

Consider a ring \ {\tt A} \ supplied with the operations
\medskip

{\bf (gxSig)}:
\begin{verbatim}
  gxBasis   : [A] -> [A] x Matrix(A),  
  modBasisG : [A] x A -> A x [A],     
  syzGens   : [A] -> [[A]]
\end{verbatim}
And introduce the denotation for projections of the first two
of above operations:

  {\tt $gxBasis_g$ \ \ \ = fst . gxBasis \ \ : [A] -> [A]} \ --- gx-basis, 


  {\tt $gxBasis_m$ \ \   = snd . gxBasis \ \ : [A] -> Matrix[A]} \ --- 
                                                transformation matrix,


  {\tt $modBasisG_r$     = fst . modBasisG \ \ : [A] -> A -> A}
                     
  \verb#                                         #
                                      --- normal form, remainder by basis, 


  {\tt $modBasisG_q$ = snd . modBasisG \ \ : [A] -> A -> [A]} 

  \verb#                                         #
                                            --- `quotient' for normal form.
\medskip

{\bf Definition.} \ \
A map \ $f : A \longrightarrow A$ \ is canonical modulo ideal $I$ 
in $A$\\
when \ $f(0) = 0$ \ and for each  \ $x, y$ \ from $A$ there hold

  $ f(x)-x \in I, \ \ (x-y \in I \Longleftrightarrow f(x) = f(y)) $

That is $f$ chooses a unique representative in each class \ $x+I$ \ 
and chooses $0$ from \ $0+I$.

Below, we denote with \ {\tt xs, ys, gs}, \ldots, $xs, \ ys, \ gs,$ \ldots 
\ \ the lists --- elements of a domain \ {\tt [A]}.  
\medskip

{\bf Definition.} \ \
For a ring $A$ with the operations {\bf (gxSig)}, \ $gs$ \ is called a
gx-basis (of $I = Ideal(gs)$) \\
if it does not contain zeroes and \ \ $(modBasisG_r \ gs)$ \ \
is a canonical map modulo \ $Ideal(gs)$.
\medskip

{\bf Definition.} \ \ An ideal basis $xs$ for $I$ is minimal (by inclusion), 
if\\ 
$ Ideal(xs \setminus \{x\}) \neq Ideal(xs) $ \ \ for any $x$ from $xs$.
\medskip

Let us also put that empty basis presents zero ideal.
\bigskip

{\bf Definition.}\\
A ring \ {\tt A} \ with algorithmically given operations {\bf (gxSig)}
is called a \ gx-ring \ if the following conditions are satisfied:
%
\begin{itemize}
\setlength\itemsep{0pt}
\item[(GxS)] 
  for each \ {\tt xs \ \ (syzGens xs)} \ is some generator list \\
  for the {\tt A}-module of linear relations beween \ {\tt xs}

\item[(GxM)] for each \ $xs \ \ \ \ (gxBasis_g \ xs)$ \ \ is a gx-basis

\item[(GxGT)] for each $xs \ \ \ M = gxBasis_m \ xs$ 
  \ \ 
  is the transformation matrix over \ {\tt A}\\ 
  for \ $(gxBasis_g \ xs)$: \ \ \  
  $ M * xs^\rightarrow == (gxBasis_g \ xs)^\rightarrow, $
  \\
  where the upper index arrow means the vector -column made from the 
  given list.

\item[(GxMQ)] for each gx-basis \ $gs$ \ \ \
           $ q = modBasisG_q \ gs \ a = [q_1,\ldots,q_n] $
  \\
  is the quotient vector of \ $a$ \ by \ $gs$, \ that is
  
  $ a = g_1 q_1 + \ldots + g_n q_n + (modBasisG_r \ gs \ a) $
\end{itemize}

In the {\tt DoCon} program, the counterparts for the operatins {\bf (gxSig)} 
are
\begin{verbatim}
  gxBasis            :: [a]    -> ([a], [[a]])
  (moduloBasis "cg") :: [a]    -> a   -> (a, [a])
  syzygyGens         :: String -> [a] -> [[a]]
\end{verbatim}

{\bf Remarks.}
\medskip

{\bf 1.} \ 
{\tt DoCon} defines \ $(modBasis_r \ xs)$ \ so that \ 
$Ideal(xs)$ \ maps to zero, and other elements to possibly `small'
elements.
\medskip

{\bf 2.} \ 
$gxBasis_g \ xs$ \ is not necessarily a minimal basis. \\
For example, \ {\tt [2, 2]} \ is a gx-basis in {\tt Integer}.
\medskip

{\bf 3.} \ 
Usually, the ideal has many minimal gx-bases.
And it often occurs that \ $Ideal(xs) = Ideal(ys)$ \ and \  
$(gxBasis_g \ xs) \neq (gxBasis_g \ ys)$. \ 
Different gx-bases in ideal $I$ may present different canonical 
projections \ $(modBasisG_r \ gs)$ \ modulo $I$.
\medskip

{\bf 4.} \ 
For any list \ {\tt xs}, \ not necessarily a gx-basis, 
the composition of\\ 
{\tt gs = gxBasis xs} \ and \ {\tt (modBasisG gs)} \ \ gives a 
canonical map modulo {\tt Ideal(xs)}.
We call the corresponding maps
\\
  \verb#                       #
                            {\tt modBasis}, \ $modBasis_r, \ modBasis_q$;
\\
their g-counterparts are \ \ \ \ \ 
                           {\tt modBasisG}, \ $modBasisG_r, \ modBasisG_q$.
\medskip

{\bf 5.} \ 
{\tt DoCon} uses the property \ {\tt IsGxBasis} \ related to the above 
definition of gx-basis for the needs of optimization.  
If the description of an ideal \ {\tt I} \ contains 
{\tt (IsGxBasis, Yes)} in the attributes of generators, then the  
reduction modulo {\it I} may skip applying \ {\tt gxBasis} without 
breaking the result correctness.

The also concerns, for example, finding syzygis for the polynomials
over a field. 
\medskip

{\bf 6.} \ 
{\tt DoCon} does not provide a function to detect ``is a gx-basis''.\\
Sometimes, {\tt DoCon} defines its value automatically, and often it has 
to be set by the programmer.  And when it is not set to {\tt Yes},
this may cause extra \ {\tt gxBasis} \ computation.
\medskip

{\bf 7.} \ 
The conditions (GxS) --- (GxMQ) are much weaker than the Gr\"obner
basis structure conditions, dnd they have few in common with grading.
Why do we need them? \\
They serve for defining in an universal way the arithmetics of 
residue domains for the gx-rings like \ \
(1) c-Euclidean ring, \ \ (2) polynomail ring over a c-Euclidean ring,

(3) direct sum of gx-rings, \ \ (4) maybe, some other constructs \ \
(see below).
\bigskip



\underbar{Examples of gx-rings}
\medskip

{\bf c-Euclidean ring.}
\medskip

{\bf Definition.} \ \
A \ c-Euclidean ring \ is an Euclidean ring with the property of the
canonical division remainder 
(see Section~\ref{sec-euc}, {\tt DivRemCan} property).

For a c-Euclidean ring, {\tt DoCon} puts

  {\tt syzGens =} \ algorithm {\tt solveLinear} for general 
                    linear system over an Euclidean ring.
\medskip

  {\tt gxBasis xs = ([g], [qs])},

  where \ {\tt (g,qs) = gcdE xs} \ \ is the extended GCD method.
\medskip

  {\tt modBasisG [b] a = (r, [q])}, \ \
                                where \ {\tt (q,r) = divRem 'c' a b}
      
  --- see above the c-Euclidean ring definition.
\medskip

And it occurs here that for any non-zero \ {\tt b} \ \ {\tt [b]} \ 
is a gx-basis.
\medskip

{\bf Proof:} \ \ an evident consequence of a c-Euclidean ring
definition.
\bigskip


{\bf Polynomial ring \ $P = k[x_1,\ldots,x_n]$ \ over a field $k$.}
\medskip

{\tt DoCon} defines a gx-ring structure for $P$ by putting

{\tt gxBasis =} \ extended Gr\"obner basis algorithm (\cite{Bu} extGB),

{\tt modBasisG =} \
Gr\"obner normal form algorithm, with complete reduction of the 
tail and with accumulation of quotient vector (\cite{Bu} Section 2),

{\tt syzGens =} \ 
syzygy generator list algorithm for polynomials (\cite{Bu} Section 7),
via finding of Gr\"obner basis and reducing of S-polynomials.
\medskip

\cite{Bu} contains certain theory from which it follows easily 
that the above definition makes $P$ a gx-ring.
\medskip

Furher, for many composed domains {\tt DoCon} defines automatically the  
gx-operations by construction. This is done as follows.



\subsection{ Polynomials over a c-Euclidean ring }
% ------------------------------------------------
\label{sec-gx.p} 

For an Euclidean ring \ $A, \ \ P = A[x_1,\ldots,x_n]$ \ \
is supplied with gx-operations via the weak reduced Gr\"obner 
basis method \cite{Mo}.


\subsection{ Direct sum }
% -----------------------
\label{sec-gx.ds} 


The Gr\"obner basis notion for the ring \ $C = A \oplus B$ \ 
is senseless. Neither $C$ is Euclidean.
Nevertheless, $C$ is naturally a gx-ring if $A$ and $B$ are.
Any ideal $I$ in $C$ is represented uniquely as the direct sum of
ideals: \ $I = I_1 \oplus I_2$.

Therefore, the gx-operations are defined for $C$ in an evident way,
which description we skip.



\subsection{ Residue ring }
% -------------------------
\label{sec-gx.r} 

{\tt DoCon} defines a residue ring \ $B = A/I$ \   
only for a gx-ring $A$, and ideal $I$ given by its gx-basis {\tt gs}.
Applying {\tt gxBasis} in $A$ always reduces the task to this case.

We have first to define the equality, canonical representation and
arithmetic in $B$.

{\tt DoCon} denotes by \ \ {\tt Rsi x iI dA} \ \ the residue element modulo $I$.
But for this section, let us denote it 
\begin{center}
                    {\tt Rs x gs},
\end{center}
{\tt gs} \ a gx-basis of $I$.

It is essential that {\tt DoCon} requires \ {\tt x} \ to be canonically 
reduced modulo \ {\tt gs} \ {\it ab initio}.
It is the same as if we replaced \ \ {\tt Rs x gs} \ \ with \ \ 
{\tt Rs ($modBasisG_r$ gs x) gs} \ \  
each time before computing anything with residues.

Hence the equality in B is `derived': \ \verb#(Rs x gs)==(Rs y _) = x==y#

Arithmetic: 
\footnotesize
\begin{verbatim}
  (Rs x gs)+(Rs y _) = Rs (modBasisG_r gs (x+y)) gs,
  (Rs x gs)*(Rs y _) = Rs (modBasisG_r gs (x*y)) gs,   
\end{verbatim}
\normalsize
and so on.

Consider now the division.
\medskip

\underbar{What is division} \\
A quotient of division is {\it any} solution of a linear equation \ \ 
$a \cdot x = b$. \ \ It may not have a solution, may have a unique 
solution (say in a field case), or many solutions. 

And {\tt DoCon} provides {\it any} solution, if such exists. 
Together with other gx-operations, this provides a convenient complete 
solution for the division.

Let us consider the inversion in \ {\tt B = A/I} \ 
(division is similar):
\footnotesize
\begin{verbatim}
  inv_m (Rs a gs) = let (r, q0:_) = modBasis (a:gs) 1
                    in
                    if r==0 then  Just $ Rs (modBasisG_r gs q0) gs
                    else          Nothing
\end{verbatim}
\normalsize
{\bf Proof} of its correctness:\\
{\tt (Rs a gs)} is invertible  \ $\Leftrightarrow$ \ 
$ 1 \in$ \ {\tt I = Ideal(gxBasis$_g$ (a:gs))}. \ 
Due to gx-ring laws, this is equivalent to \ 
{\tt (modBasisG$_r$ (gxBasis$_g$ (a:gs)) 1) == 0}, \ and this latter is 
equivalent to the condition \ {\tt r == 0} \ in the considered program.
Hence, according to the {\tt modBasis} definition,
{\tt 1 = q0 $\cdot$ a} $+ \sum_{i = 1}^n q_i \cdot g_i$, \ \  where 
\ \
{\tt [q0,$q_1,\ldots,q_n$]} \ is the quotient vector returned by \ 
{\tt modBasis (a:gs) 1}.

Therefore, {\tt q0} is the inverse of \ {\tt a} \ in \ {\tt A/I}. 
\medskip

The gx-operations in a residue ring base on that the inclusion and 
equality of ideals \ $J$ \ in \ $B = A/I$ \ is isomorphic to ones of 
the set of ideals \ $I'$ in \ $A$ \ that contain \ $I$.
\medskip


\underbar{On computation cost for residue ring}
\\
Division and gx-operations in $A/I$ may be expensive, for they may 
cause extra {\tt gxBasis} computation.
Such is the nature of a residue ring.
But for the `simple' ideals, the operations in $A/I$ are cheap. 
Typical example: for the rational numbers field \ $\mathbb{Q}$, \
{\tt DoCon} represents its extension
\ $B = \mathbb{Q}( \sqrt[3]{2}, \ \sqrt{-3} )$ \
as the residue ring \ $\mathbb{Q}[x,y] / Ideal(x^3-2, \ y^2+3)$, \
and this leads to quite simple computations in $B$. 
For example the inversion in $B$ costs about as much as inversion
of a matrix of size 6 over $\mathbb{Q}$.




\subsection{ Ring description transformations }
% ---------------------------------------------
\label{sec-gx.t} 

The class of gx-rings extends wider that it appears from previous 
sections.
For examle, let \ \ $A = (Q \oplus Q)[x_1,\ldots,x_n]$ \ \
be a polynomial ring over the pairs of rationals.
We cannot directly use the Gr\"obner bases for $A$ because \ 
$Q \oplus Q$ \ has zero divisors, and {\tt DoCon} cannot the find a 
Gr\"obner basis for such coefficient ring.

But consider the computable isomorphism
$$       
  (B \oplus C)[x_1,\ldots,x_n] \ \longleftrightarrow \
  B[x_1,\ldots,x_n] \oplus C[x_1,\ldots,x_n]
$$
In our example, \ $B, C$, \ are fields, so, \ 
$B[x_1,\ldots,x_n], \ C[x_1,\ldots,x_n]$ \ are gx-rings according to 
the lemma for the polynomial constructor. Hence, \  
$B[x_1,\ldots,x_n] \oplus C[x_1,\ldots,x_n]$ \ 
is supplied with gx-operations according the direct sum rule.
Similar approach is valid for the constructions

{\bf (CC):}
\begin{eqnarray*}
 B[x_1,\ldots,x_n][y_1,\ldots,y_m],  &  (B/I)[x_1,\ldots,x_n] ,\\
 (C \oplus B)/I ,                    &  (B/I)/J,               \\
 \ldots
\end{eqnarray*}
--- let us call them \ g-constructions.
\medskip

\underbar{Constructor isomorphisms and {\tt Haskell} instances}
\medskip

Concerning such transformations, DoCon implements only one kind 
of them: the isomorphism \ 
$ a[x_1,\ldots,x_n][y] \ \longleftrightarrow \ a[y,x_1,\ldots,x_n] $ 
\
is applied for defining the operations \ {\tt gxBasis, moduloBasis} \  
for the domain \ $a[x_1,\ldots,x_n][y]$.
The corresponding instance is
\footnotesize
\begin{verbatim}
  instance (LinSolvRing (Pol a), CommutativeRing a) => LinSolvRing (UPol (Pol a))
    where ...
    -- see  Pol3_.hs.
\end{verbatim}
\normalsize
This is nice that {\tt Haskell} allows such recursion on the instances.
Note this\\ 
`{\tt LinSolvRing (Pol a)}' \ in the context.
It allows \ {\tt a} \ to specialize further to\\ 
{\tt a = b[$z_1,\ldots,z_m$]}. \ For an appropriate domain \ {\tt b}, \ 
say Euclidean, this whole instance would work too.

For example, `{\tt LinSolvRing a}' in the context is too weak, because
\ {\tt gxBasis} for \ {\tt (Pol a)} \ is applied.  
And `{\tt EuclideanRing a}' is too strong: in this case the recursion
would not work, for example, for \ {\tt a = Z[u,v]}.  

This {\tt DoCon} experiment with the domain \ $a[x_1,\ldots,x_n][y]$ \  
shows that the {\tt Haskell} instances fit to implement all the 
g-constructions in a recursive manner.



\newpage
\subsection{ gx operations in programs }
% --------------------------------------
\label{sec-gx.pr} 


\subsubsection{ moduloBasis }
\label{sec-gx.pr.m} 

The `theoretical' operation \ {\tt modBasis} \ introduced above 
corresponds to the {\tt DoCon} operation from the category 
{\tt LinSolvRing}:   
\footnotesize
\begin{verbatim}
  moduloBasis :: String -> [a] -> a -> (a, [a])
                 --mode    basis  x    rem quot

  mode = cMode++gMode,  cMode = "" | "c",   gMode = "" | "g"
\end{verbatim}
\normalsize

{\tt cMode = "c"} \ \ means the canonic reduction. 

 \verb#       # {\tt ""} \ 
 means only the reduction in which the zero modulo $I$ is detached.

{\bf Example.}\\
For the polynomials from \ $Q[x,y]$ \ and any monomial ordering with \ 
$y > x$, \ the map\\ 
{\tt fst . moduloBasis "g" [$x$]} \ \ remains the polynomials \ 
$y+x, \ y + 2 x$ \ unchanged,  

  while \ \ {\tt fst . moduloBasis "cg" [$x$]} \ \ maps them to \ $y$.
\medskip

{\tt gMode = "g"} \ means a gx-basis \ {\tt basis}.

Any other value means that nothing is known about \ {\tt basis}. 
In this case. it is applied the composition of \ {\tt gxBasis} \ and \ 
\verb#moduloBasis (_:'g')#.


\subsubsection{ syzygyGens }
\label{sec-gx.pr.s} 

The theoretical  \ {\tt syzGens} \ introduced above corresponds to 
the {\tt DoCon} operation from the category {\tt LinSolvRing}:   
\footnotesize
\begin{verbatim}
  syzygyGens :: String -> [a] -> [[a]]
                --mode    fs     
\end{verbatim}
\normalsize
{\tt mode = ""} \ means the generic case.

{\tt "g"} :

(1) for a polynomial ring \ $A = R[x_1,\ldots,x_n]$ \ over an 
Euclidean ring $R$, \ {\tt mode = "g"} \ means that \ {\tt fs} \ 
is a (weak) Gr\"obner basis (the evaluation will be simpler),

(2) for \ $A = B \oplus C$, \ \ {\tt mode = "g"} \ means \ 
    {\tt mode = "g"} \ for \ {\tt syzygyGens} \ for both 

    {\tt map fst fs} \ and \ {\tt map snd fs}.





\newpage
\section{ {\tt DoCon} module export lists }
% -----------------------------------
\label{sec-dme}  

When the module reexports something from other module, it is marked 
in the commentary. For example,
\footnotesize
\begin{verbatim}
                   module Pol ( f, g,
                                u, v  -- from Pol_
                              )
\end{verbatim}
\normalsize
means that \ {\tt Pol}  defines \ {\tt f, g} \ and exports them, 
and reexports \ {\tt u, v} \ defined in \ \verb#Pol_#.

Further, in {\tt Haskell}, exporting any data constructor causes
automatically the export of its related instances.
{\tt DoCon} sets this instance export as the commentary.

The following {\tt DoCon} `open' module export list informs the user where 
the needed items have to be imported from.

\footnotesize
\begin{verbatim}
module DExport   
            -- Joint export of DoCon and some libraries of GHC. 
            -- In *extra* case, `import DExport' imports everything.

  (module AlgSymmF,     module Categs,      module Z, 
   module DPair,        module DPrelude,    module Fraction, 
   module GBasis,       module LinAlg,      module Partition,
   module Permut,       module Pol,         module Residue, 
   module RingModule,   module SetGroup,    module VecMatr,
   
   module Prelude, module List, module Data.Map, module Ratio,
   module Random
  )
------------------------------------------------------------------------
module DPrelude                                         -- DoCon Prelude

  (sublists, listsOverList, smParse,

   -- from Prelude_:
   Cast(..), ct, ctr,
   PropValue(..), InfUnn(..), MMaybe, CompValue, Comparison,
   Z, toZ, fromZ,
   tuple31, tuple32, tuple33,  tuple41, tuple42, tuple43, tuple44,
   tuple51, tuple52, tuple53, tuple54, tuple55,
   zipRem, allMaybes, mapmap, mapfmap, fmapmap, fmapfmap,
   boolToPropV, propVToBool, not3, and3, or3,  compBy,  delBy, 
   takeAsMuch, dropAsMuch, separate, pairNeighbours, 
   removeFromAssocList, addToAssocList_C, addListToAssocList_C, 
   propVOverList, mbPropV, lookupProp, updateProps, addUnknowns, 
   foldlStrict, foldl1Strict, 
   antiComp,  minBy, maxBy, minimum, maximum, minAhead, maxAhead,

   -- from Iparse_:
   Expression(..), OpDescr, OpTable, ParenTable, lexLots, showsExpr,
   infixParse,                   

   parenTable, opTable,   -- from OpTab_ 

   module Char_,
   module List_,  -- cubeList_lex

   -- from Common_:
   partitionN, eqListsAsSets, del_n_th, halve, mulSign, invSign, 
   evenL, factorial, binomCoefs, isOrderedBy, mergeBy, mergeE, sort,
   sortBy, sortE,  sum1, product1, alteredSum, lexListComp, 
   minPartial, maxPartial, 

   -- from Set_:
   less_m, lessEq_m, greater_m, greaterEq_m, incomparable,
   showsWithDom
  ) 
--------------------------------------------------------------------
module Categs                                 -- domain descriptions

  (Dom(..),   Domain1(..), Domain2(..), Domains1, Domains2,
   CategoryName(..),  Factorization,
   Ideal(..), Properties_Ideal, Properties_IdealGen,
   Property_Ideal(..), Property_IdealGen(..),
   Construction_Ideal(..), Operations_Ideal, OpName_Ideal(..), 
   Operation_Ideal(..),
   Submodule(..), Properties_Submodule, Properties_SubmoduleGens,
   Operations_Submodule, Property_Submodule(..), 
   Property_SubmoduleGens(..), OpName_Submodule(..),
   Operation_Submodule(..), Construction_Submodule(..),
   LinSolvModuleTerm(..), Properties_LinSolvModule, 
   Property_LinSolvModule(..),

   -- from Categs_:
   Vector(..), vecRepr, PowerProduct, PPComp, 
   AddOrMul(..),
   OSet(..), Properties_OSet, Property_OSet(..), 
   Construction_OSet(..), Operations_OSet, OpName_OSet(..),
   Operation_OSet(..), 
   Subsemigroup(..), Properties_Subsemigroup,
   Property_Subsemigroup(..), Construction_Subsemigroup(..),
   Operations_Subsemigroup, OpName_Subsemigroup(..),
   Operation_Subsemigroup(..), 
   Subgroup(..), Properties_Subgroup, Property_Subgroup(..), 
   Construction_Subgroup(..), Operations_Subgroup, 
   OpName_Subgroup(..), Operation_Subgroup(..),

   Subring(..), Properties_Subring, Property_Subring(..), 
   Construction_Subring(..), Operations_Subring, 
   OpName_Subring(..), Operation_Subring(..),

   GCDRingTerm(..), Properties_GCDRing, Property_GCDRing(..),

   FactrRingTerm(..), Properties_FactrRing, 
   Property_FactrRing(..), 
   LinSolvRingTerm(..), Properties_LinSolvRing, 
   Property_LinSolvRing(..), 
   EucRingTerm(..), Properties_EucRing, Property_EucRing(..)
  )
-------------------------------------------------------------------------------
module SetGroup             -- Set, Semigroup ... Group   categories
  (              
   AddGroup(..), OrderedAddGroup(..), 
   isOrderedGroup, absValue, trivialSubgroup, isoGroup, 
   isoConstruction_Subgroup,
   MulSemigroup(..), MulMonoid(..), OrderedMulSemigroup(..), 
   OrderedMulMonoid(..), MulGroup(..), OrderedMulGroup(..),
   upAddGroup, upMulSemigroup, upMulGroup,  unity, inv, divide, 
   invertible, divides, power, powerbin,
   unfactor, isPrimeFactrz, isPrimaryFactrz, isSquareFreeFactrz,
   factrzDif, eqFactrz, gatherFactrz, rootOfNatural, 
   minRootOfNatural, 
   -- instances for Integer: 
   -- MulSemigroup, MulMonoid, AddGroup, OrderedAddGroup, 

   -- from Set_
   Set(..), OrderedSet(..), compareTrivially, isFiniteSet, 
   isBaseSet, intervalFromSet, card, ofFiniteSet, isoOSet, 
   props_set_full_trivOrd, listToSubset,

   -- from Semigr_  
   AddSemigroup(..),  OrderedAddSemigroup(..), AddMonoid(..),
   OrderedAddMonoid(..), 
   upAddSemigroup, isGroup, isCommutativeSmg, isoSemigroup, 
   trivialSubsemigroup, isoConstruction_Subsemigroup, 
   zeroS, isZero, neg, sub, times
   -- ,instances for Integer:  Set .. OrderedAddMonoid
  )
\end{verbatim}

\newpage
\begin{verbatim}
module RingModule
              
  -- Ring..GCDRing..Field, LeftModule, LinSolvLModule  categories

  (LeftModule(..), LinSolvLModule(..),
   isGxModule, isoModule, isoLinSolvModule,isoDomain22,isoDomains22,
   numOfNPrimesOverFin,
     -- instance Ring a          => LeftModule a a,
     -- instance Ring a          => LeftModule a (Vector a),
     -- instance EuclideanRing a => LinSolvLModule a (Vector a),

   -- from Ring0_:
     Ring(..), CommutativeRing(..), OrderedRing(..), GCDRing(..), 
   FactorizationRing(..), LinSolvRing(..), EuclideanRing(..), 
   Field(..), RealField(..), OrderedField(..), 
     isFactorizOfPrime, isFactorizOfPrimary,
     property_Subring_list, fromi, char, props_Subring_zero,
   zeroSubring, dimOverPrimeField, isField, isPrimeIfField, 
     isOrderedRing, rankFromIdeal, isMaxIdeal, isPrimeIdeal,
     isPrimaryIdeal, 
   genFactorizationsFromIdeal, zeroIdeal, unityIdeal,
     isGCDRing, isRingWithFactor, isGxRing, isEucRing, isCEucRing,
     upRing, upGCDRing, upFactorizationRing, upLinSolvRing, 
   upEucRing, upGCDLinSolvRing, upFactrLinSolvRing, 
   upEucFactrRing, upField, 

   -- from Ring_:
   eucGCDE, powersOfOne, logInt, diffRatios,  
   isoRing, isoGCDRingTerm, isoFactrRingTerm, 
   isoLinSolvRingTerm, isoEucRingTerm,  PIRChinIdeal(..), eucIdeal, 
   isoDomain1, isoDomains1,

   -- from Ring1_:
   quotEuc, remEuc, multiplicity, isPowerOfNonInv, 
   gxBasisInEuc, moduloBasisInEuc, syzygyGensInEuc,
   moduloBasis_test, gxBasis_test, syzygyGens_test, gcd_test
  )
--------------------------------------------------------------------
module Z                                   -- items for  Z = Integer

  (dZ,

   -- from SetGroup
   rootOfNatural, minRootOfNatural
   -- , instances for Integer: 
   -- Set, OrderedSet, AddSemigroup, OrderedAddSemigroup, AddMonoid,
   -- OrderedAddMonoid, MulSemigroup, MulMonoid, AddGroup, 
   -- OrderedAddGroup
   
   -- from Ring_
   -- instances for Integer:
   -- Fractional, Ring, CommutativeRing, OrderedRing,

   -- from Ring1_
   -- instances for Integer:  LinSolvRing, EuclideanRing
  )
--------------------------------------------------------------------
module DPair
             -- category instances for Direct Product of two domains
  (
   -- instances for (,):
   -- Set,AddSemigroup,AddMonoid,AddGroup,MulSemigroup,MulMonoid,
   -- MulGroup,Ring,CommutativeRing,LinSolvRing

   module DPair_
   -- directProduct_set, directProduct_semigroup,
   -- directProduct_group, directProduct_ring
  )
--------------------------------------------------------------------
module Fraction   

  (Fraction(..),                           -- from Ring0_
   num, denom, zeroFr, unityFr, canFr      -- from Fract_

   -- ,instances for Fraction a: 
   -- Functor, Dom, ... OrderedSet ... RealField, OrderedField
   -- --- some of them imported from Fract_, Ring0_
   --
   -- Specializations for some instances for  Fraction Z.
  )
--------------------------------------------------------------------
module VecMatr
            -- Vector,Matrix operations and their category instances

  (Vector(..), vecRepr,  {- Eq Vector, -}   -- from Categs
   Matrix(..), matrRows,                    -- from Ring0_

   -- from Vec0_
   allMaybesVec, vecSize, vecHead, vecTail, constVec, scalProduct,
   -- instance Functor

   -- from Vec1_  
   vecBaseSet, vecBaseAddSemigroup, vecBaseAddGroup, 
   vecBaseMulSemigroup, vecBaseMulGroup, vecBaseRing,

   module Vec_,    
   -- instances for Vector:
   -- Show,Set,OrderedSet,AddSemigroup,AddMonoid,OrderedAddSemigroup,
   -- OrderedAddMonoid,AddGroup,OrderedAddGroup,MulSemigroup,
   -- OrderedMulSemigroup,MulMonoid,MulGroup,Ring,CommutativeRing,
   -- OrderedRing,Num,Fractional,
 
   -- from Matr0_:
   SquareMatrix(..),  toSqMt, fromSqMt, matrHeight, matrWidth,
   mtHeight, mtWidth, mtHead, isZeroMt, sqMatrSize, matrHead, 
   matrTail, mapMt, mapSqMt, transp, constMatr, constSqMatr,
   rowMatrMul, scalarMt, mainMtDiag, isDiagMt, isStaircaseMt,
   isLowTriangMt, vandermondeMt, resultantMt,

   -- from Matr1_:
   matrBaseSet, matrBaseAddSemigroup, matrBaseAddGroup, 
   sqMatrBaseSet, sqMatrBaseAddSemigroup, sqMatrBaseAddGroup, 
   sqMatrBaseMulSemigroup, sqMatrBaseRing
  )
--------------------------------------------------------------------
module Permut                                   -- permutation group

  (Permutation(..), EPermut, toEPermut, fromEPermut, permutRepr,
   isPermut, permutSign, isEvenPermut, applyPermut, invEPermut, 
   addEPermut, ePermutCycles, permutECycles, permutCycles, 
   transpsOfNeighb, allPermuts, nextPermut, test_allPermuts, 
   gensToSemigroupList
   -- ,instances for  Permutation:
   -- Eq, Show, Ord, Num, Set, MulSemigroup, MulMonoid, MulGroup
  )
--------------------------------------------------------------------
module LinAlg                                      -- linear algebra

  (diagMatrKernel, solveLinearTriangular, solveLinear_euc, 
   test_solveLinear_euc,

   -- from Stairc_:
   reduceVec_euc, toStairMatr_euc, rank_euc, inverseMatr_euc,     
   linBasInList_euc, test_toStairMatr_euc, test_inverseMatr_euc,

   det, det_euc, maxMinor, delColumn,      -- from Det_
   toDiagMatr_euc, test_toDiagMatr_euc     -- from Todiag_
  )
--------------------------------------------------------------------
module Pol                                       -- polynomial items
  (
   UMon, PowerProduct, PPComp,   -- from  Categs

   -- from PP_
   isMonicPP, ppLcm, ppComplement, vecMax, ppMutPrime, ppDivides, 
   lexComp, lexFromEnd, degLex, degRevLex, ppComp_blockwise,

   -- from UPol_
   PolLike(..), PolVar, Mon, UPol(..), PPOrdTerm, PPOId, 
   Multiindex, ppoId, ppoComp, ppoWeights, lexPPO, varP, deg0, lc0,
   pHeadVar, lc, cPMul, pCont, numOfPVars, upolMons, lmU, umonMul, 
   mUPolMul, umonLcm, leastUPolMon, cToUPol, upolPseudoRem, 
   monicUPols_overFin,
   -- instance (PolLike p...) => LeftModule a (p a),
   -- instances for UPol:        Dom, Eq, Cast, PolLike,

   resultant_1_euc, upolSubst, upolInterpol,          -- from UPol0_
   -- instances for UPol
   --  Show, Set, AddSemigroup, AddMonoid, AddGroup, MulSemigroup,
   --  MulMonoid, Num, Fractional, Ring, CommutativeRing

   -- from Pol_:
   Pol(..), PolPol, polMons, cToPol, reordPol, leastMon, monMul, 
   mPolMul, monLcm, headVarPol, fromHeadVarPol, polToHomogForms, 
   addVarsPol, toUPol,fromUPol, coefsToPol, polDegs, polPermuteVars,
   -- instances for Pol:  Show, Eq, Dom, Cast, PolLike,

   PVecP, sPol, mPVecPMul, sPVecP,                    -- from  Pol__
   RPolVar, showsRPolVar, SPProduct, SPMon, SPPol', showsSPPol',

   polSubst,                                          -- from  Pol1_
   -- instances for Pol:  Show, Set .. CommutativeRing,

   module Pgcd_,   -- GCDRing instances for UPol, Pol

   module Pol2_,
   -- toOverHeadVar, fromOverHeadVar, 
   -- LinSolvRing, EuclideanRing  instances for  UPol,
   -- LinSolvRing                                Pol,
   -- instance..=> LinSolvLModule (Pol  a) (EPol a),
   --              LinSolvLModule (Pol  a) (Vector (Pol  a)),
   --              LinSolvLModule (UPol a) (Vector (UPol a)),

   -- from Pol3_:
   VecPol(..), vpRepr, vpEPPOTerm, vpECp, vpToV,
   -- instances for VecPol up to LinSolvLModule (Pol a) (VecPol a),

   -- from RPol_:
   RPol(..), RPol'(..), RPolVarComp, RPolVarsTerm,
   rpolRepr, rpolVComp, rpolVTerm, rvarsTermCp, rvarsTermPref,
   rvarsTermRanges, rpolVPrefix, rpolVRanges, rvarsVolum, 
   showsRVarsTerm, rvarsOfRanges, rp'HeadVar, rpolHeadVar, 
   rp'Vars, rpolVars, cToRPol, varToRPol', varToRPol, rHeadVarPol, 
   rFromHeadVarPol, toRPol, toRPol', fromRPol, substValsInRPol,
   -- instances for RPol', RPol:  Show, Eq, Functor, Dom, PolLike,

   -- from RPol0_
   -- instances for RPol:
   -- Set, AddSemigroup, AddMonoid, AddGroup, MulSemigroup, 
   -- MulMonoid, Num, Fractional, Ring, CommutativeRing, GCDRing,

   vecLDeg, henselLift, testFactorUPol_finField,     -- from Pfact0_

   extendFieldToDeg, det_upol_finField, resultant_1_upol_finField,
                                                     -- from Pfact1_

   module Pfact__,
   -- RseUPol, RseUPolRse, toFromCanFinField, factorUPol_finField,
   -- instance of  FactorizationRing  for  k[x],  k  a finite field

   module Pfact3_,  
                 -- FactorizationRing instances for  k[x][y], k[x,y]
 
   -- from EPol_:
   EPP, EPPComp, EPPOTerm, EMon, EPol(..),
   eppoECp, eppoMode, eppoWeights, eppoCp,
   epolMons, epolPol, epolEPPOTerm, epolECp, epolPPCp, eLm, eLpp,
   epolLCoord, leastEMon, reordEPol, cToEMon, cToEPol, zeroEPol,
   polToEPol, epolToPol, ecpTOP_weights, ecpPOT_weights, ecpTOP0,
   EPVecP, emonMul, mEPolMul, polEPolMul, epolToVecPol,
   vecPolToEPol, sEPol, mEPVecPMul, sEPVecP,
   -- instances for EPol:
   --             Dom, Cast, PolLike, Show, Eq, Set .. AddGroup, Num

   -- from RdLatP_:
   reduceLattice_UPolField, reduceLattice_UPolField_special,

   -- from FAA0_               items for non-commutative polynomials
   FreeMonoid(..), FreeMOrdTerm,
   freeMN, freeMRepr,  freeMOId, freeMOComp, freeMWeightLexComp,
   -- instances for FreeMonoid:
   --                  Cast FreeMonoid [(Z,Z)],  Show .. MulMonoid,
   --   
   FAA(..), FAAMon, FAAVarDescr,
   faaMons, faaFreeMOrd, faaVarDescr, faaN, faaVMaps, faaFreeMOId,
   faaFreeMOComp, faaLM, faaLeastMon, faaLPP, reordFAA,
   faaMonMul, faaMonFAAMul, cToFAA, faaToHomogForms,
   -- instances for FAA :
   --   Dom, Eq, Show,  Cast (FAA a) (FAAMon a),
   --                   Cast (FAA a) [FAAMon a], Cast (FAA a) a,
   --   PolLike FAA,    Set .. Ring, Fractional,

   faaNF, faaNF_test    -- from FAANF_
  )
--------------------------------------------------------------------
module Residue                       -- quotient group, residue ring

  (ResidueE(..),    -- from Categs

   module QuotGr_,
   -- ResidueG(..), isCorrectRsg,                
   -- instances  Show, Eq, Cast, Residue, Dom, Set .. AddGroup
   
   gensToIdeal,   -- from IdealSyz_

   module ResEuc0_,
   -- class Residue(..),  ResidueE(..), 
   -- resSubgroup, resSSDom, resIdeal, resIIDom, isCorrectRse,
   -- ifCorrectRse,
   -- instances for Residue class:          Show, Eq,
   --           for constructor  ResidueE:  Dom, Cast, Residue
 
   module ResEuc_,
   -- instances for  ResidueE:
   -- Set,AddSemigroup,AddMonoid,AddGroup,MulSemigroup,MulMonoid,
   -- Ring,CommutativeRing,LinSolvRing,GCDRing, FactorizationRing,
   -- EuclideanRing, Field, 
   -- specialization for  ResidueE Z  for the instances  
   --   Set, AddSemigroup, AddGroup, MulSemigroup, Ring,

   module RsePol_,
   -- specialization of  ResidueE  to  Field k => ResidueE (UPol k):
   -- instances up to  Ring
 
   module ResRing_,
   -- ResidueI(..), isCorrectRsi,
   -- instances for  .. => ResidueI a: 
   --                    Dom, Residue, Cast, Set .. Num, Fractional,

   module ResRing__,   -- continuation:  instances  Ring .. Field,
    
   module ResPol_
   -- instances Set,AddSemigroup,Ring  for  ..=> ResidueI (Pol a)
  )
--------------------------------------------------------------------
module GBasis                     -- items related to Gr\"obner basis 

  (polNF, polNF_v, polNF_e, polNF_ev, test_polNF, underPPs, 
                                                     -- from PolNF_
   gBasis, gBasis_e, isGBasis, isGBasis_e,           -- from GBas_
   polRelGens, polRelGens_e, algRelsPols             -- from Polrel_
  )  
--------------------------------------------------------------------
module Partition  
       -- items related to Partitions (Young diagrams), bands, hooks

  (isPrtt, subtrSHook_test, kostkaNumber, kostkaColumn, 
   kostkaTMinor, hookLengths, numOfStandardTableaux,
   permGroupCharValue, permGroupCharColumn, permGroupCharTMinor,

   -- from Partit_:
   Partition, EPartition, PrttComp,
   toEPrtt, fromEPrtt, prttToPP, ppToPrtt, prttWeight, prttLength,
   conjPrtt, prttUnion, pLexComp, pLexComp', prttLessEq_natural,
   minPrttOfWeight, prevPrttOfN_lex, prttsOfW, randomEPrtts, 
   showsPrtt,

   -- from HookBand_:
   SHook, HBand, sHookHeight, subtrSHook, firstSWHook, prevSWHook,
   subtrHBand, maxHWBand, prevHWBand
  )
--------------------------------------------------------------------
module AlgSymmF                -- symmetric function transformations

  (toSymPol, symmSumPol, symmetrizePol, fromSymPol,
   to_e, to_e_pol,  to_h, to_h_pol,  to_m, to_m_pol, 
   to_p, to_p_pol,  to_s, to_s_pol,   
   
   -- from Sympol_
   SymPol(..), SymMon, symPolMons, symPolPrttComp, symLm, symLdPrtt,
   cToSymPol, reordSymPol, monToSymMon, symPolHomogForms, 
   -- , instances for SymPol:
   -- Show, Eq, Dom, Cast, PolLike, Set .. AddGroup, Num,
  
   -- from SymmFn_
   PrttParamMatrix(..), SymFTransTab(..), ptpMatrRows, transpPtP,
   h'to_p_coef, elemSymPols, hPowerSums, toDensePP_in_symPol, 
   fromDensePP_in_pol, intListToSymPol
  )
\end{verbatim}
\normalsize





\newpage
\section{ Performance comparison }
% --------------------------------
\label{sec-pe} 
 
We differ between the two ways to compare the performance:
``fixed algorithm'', and ``non-fixed algorithm''.
The former is to program the same (as possible) algorithm for the given
task in two programming systems and see the timing for several 
example data.

The latter means that the algorithm programmed in our system 
({\tt DoCon- Haskell}) is known, and the algorithm implemented in 
another system is not known. Such comparison also may be useful.

We describe here only the latter, non-fixed algorithm comparison
to the popular CA programs  
\begin{center}              {\tt Axiom, \ MuPAD}
\end{center}
--- see \cite{Je,Mu}.
The below benchmarks were prepared and run in
\begin{center} 
               March 20 - April 10, \ 2002 
\end{center}
on the same machine \ {\tt laudomia4} \ of the CA centre 
\begin{center} 
             MEDICIS: Unit\'{e} Mixte de Service, CNRS/Polytechnique
             \\
             \verb#<http//www.medicis.polytechnique.fr>#
\end{center}
The machine parameters are \ \ Intel (i-688, Pentium II, 400 MHz),
\\
and it was run under the \ Linux \ operation system.
\medskip

The program versions are:
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Axiom-2.2   \ \ \ \ (= Axiom)}, 

\item {\tt MuPAD-1.4.2 \ \ \ \ (= MuPAD)},  

\item {\tt DoCon}
      \\
      running under \ ghc-5.02.2 \ \cite{GH}, \ \  
      the library compiled with the optimization key {\tt -O},
      the head test program either interpreted or compiled with
      -Onot 
\end{itemize}
\bigskip


\underbar{{\bf Memory space:}}
\medskip

In the below tests, \ {\tt DoCon}  \ was given
\\ 
50 Mbyte \ for factoring in \ $GF(p)[x,y]$, \ \ 24 Mbyte \ for other tasks
\\
(running option \verb#+RTS -MXXm -HXXm -RTS# \ with {\tt XX = 50, 24}).

The author had not studied yet how to specify the memory bound in 
{\tt Axiom} and {\tt MuPAD} systems. 
But the process mesurements by means of the Unix \ {\tt top} \ command show 
that on these examples 

  {\tt Axiom} \ uses less that \ 45 Mb, \ and sometimes uses at least \ 30 Mb,

  {\tt MuPAD} \ uses less than \ 12 Mb.

Though, in most of the below examples, all the three programs can do 
the task in smaller memory space, maybe, with additional expencies for
the ``garbage collection''.

Generally, {\tt MuPAD} looks to win in these examples about 3 times 
in space in comparison to {\tt DoCon}  \ and about 2 times in comparison to 
{\tt Axiom}.
\medskip

The comparison was done only for the \ {\tt speed}. And we keep in mind 
that the space expenses always cause the corresponding time expenses
(at least, proportional).
\bigskip


\underbar{{\bf On compared tools}}
\medskip

All the three programs are ``high level'': have categories and 
domain constructors, and so on.
\\
{\tt DoCon} \ is written in {\tt Haskell}, is functional and `lazy'. \\
{\tt Axiom} \ is more close to {\tt DoCon}  than \ {\tt MuPAD}. \\
{\tt Axiom} and {\tt MuPAD} are the strict evaluators. \\
{\tt DoCon}  is more functional than \ {\tt Axiom}. \\
{\tt MuPAD} \ is not functional at all.

So, the below test gives certain impression of the performance 
ability of a `lazy' and functional programming tool.  
It is measured at the complex enough practical applications.

Though, the set of examples is rather small.
\medskip

{\bf Detail of {\tt Axiom} timing:} \ we use the commands

{\footnotesize
\begin{verbatim} 
  ... )set message time on; ... Running:  time axiom;  )r a.input  ...
\end{verbatim} 
}
But tabled here is the timing shown by interpreter-dialogue
(it is smaller).
The lines from `Running:' are for those who do not remember how to
run Axiom; and they provide some additional check: include the time
for the library loading, etc.
\medskip

\underbar{{\bf Task choice}}
\medskip

We choose the real-world computer algebra tasks, and the popular 
ones. They are programmed in {\tt Haskell} for the needs of 
mathematical practice, {\it not} chosen to promote any particular 
language or implementation.

On these tasks a pure functional, `lazy' tool {\tt Haskell}, 
--- in its  \ ghc-5.02.2 \ implementation, ---  
occurs efficient enough in comparison to \ {\tt Axiom}, {\tt MuPAD}.

The tasks are
%
\begin{itemize}
\setlength\itemsep{0pt}
\item powering \verb#(^)# \ in \ {\tt Z[x,y,z], Rational[x,y]} 
      \\ 
      --- polynomial arithmetic: \verb#+, *#

\item gcd \ in \ $Z[x,y,z]$     
 
\item Gr\"obner basis in \ $Rational[x_1,\ldots,x_n]$
 
\item factoring in \ {\tt (Z/(p))[x]} \ \ 
      --- involves polynomial arithmetics,
      gcd, large linear system solution over {\tt Z/(p)} \ldots

\item factoring in \ {\tt (Z/(p))[x,y]} \ \     
      --- involves (in DoCon) factoring in \ $GF(p^m)[x]$,\\
      large sparse linear system solution over {\tt Z/(p)} and
      other things.
\end{itemize}
%
We only run the executable programs of {\tt Axiom} and {\tt MuPAD} 
and do not know how the algorithms applied and how the above tasks 
are implemented in these systems.
\bigskip


\underbar{{\bf On programs}}
\medskip

We specify the complete programs for the tests, together with the 
instructions of how to prepare them for running and how to run them.

{\tt Haskell -DoCon}  programs are more lengthy. 
This is mainly due to that they include additional correctness tests 
(made so that they do not bring essential cost overhead).
\\
and also because they are designed to use in interactive interpreter 
mode as well as by running the compiled executable from the command
line.

We do not write such expanded programs in {\tt Axiom} and {\tt MuPAD} 
because we do not know these systems in enough detail.




\newpage
\subsection{ Powering polynomial }
% --------------------------------
\label{sec-pe.p}  


\underbar{{\tt Z[z,y,x]}}
\medskip

Find \ \verb# f^n,   f = 2*y*z + z + y*x + 3*y + 1   from  Z[z,y,x].#

{\tt DoCon}  can represent this {\tt f} as in
\begin{itemize}
\setlength\itemsep{0pt}
\item {\tt Z[x][y][z] = UUU} \ \ \ --- {\tt UPol (UPol (UPol Z))},

\item and as in \ {\tt Z[z,y,x]} \ \ --- {\tt Pol Z}.
\end{itemize}
%
In \ {\tt MuPAD}, the representation \ \ \ \ \ \ \ \ \ \ \ \ \ \
                                   \verb#poly( 2*y*z + ... [z,y,x] )#
\\
is, probably, close internally to {\tt UUU} (?).
\bigskip

\underbar{{\bf Timing [sec]}} 
\footnotesize
\begin{verbatim}
  ghc-5.02.2 + DoCon make executable a.out:  read n, show $ t n, time a.out
  The programs are specified below.

                 DoCon         Axiom          MuPAD
              UUU   Z[z,y,x]   (UUU)?         (UUU)?

  f^n, n = 18|   1.1   1.5      1.3            0.9
           21|   2.8   3.2      2.4            1.7
           24|   7.5   8.7      6.8            2.8
           27|  17    22        8.3            4.5
           30|  34    47       12              6.9
           33|  51    71       35             10
           36|  63    86       43             14

  Control sums:  snd $ t n =  
  Z[z,y,x] 
  n = 18| (3344457783112,(Vec [5,95,-10] ))
      21| (-9279064030550640,(Vec [5,76,511] )) 
  UUU
      18| (9,1256648)
      21| (11,914941444)
      36| (18,3046219662585200)
\end{verbatim}
\normalsize
All the three programs ({\tt DoCon}  with {\tt Z[z,y,x]} model)
do not change essentially the performance with the change of 
variable order: \verb#< 10%#
\\
(for {\tt DoCon}  --- {\tt UUU}, we had not tried other orders).



\newpage
\underbar{{\tt Q[x,y], \ Q = Fraction Z}}


\footnotesize
\begin{verbatim}
  f^n,  f = x^2 + (2/3)*x*y + (3/4)*y   
  ghc-5.02.2 + DoCon make  a.out:  read n, show $ t n, time a.out ...
  Timing [sec]:
               DoCon          Axiom          MuPAD
          Q[y][x] Q[x,y]      Q[x,y]?  
  n = 30|   0.8    0.9         1.0              0.6
      40|   2.3    2.4         3.5              1.6
      50|   6.9    7.2         9.1              3.5
      60|  16     17          17                6.6
      70|  24     26          38               11
      80|  42     45          71               18
  Control sums:  
  for Q[x,y]
  n = 30| (-1243073261628119203,      (Vec [16,112]))
      40| (1431303549982259961049279, (Vec [40,20] ))
      80| (513301774737...2015210929, (Vec [80,40] ))
  for Q[y][x]
  n = 30| (15,2723214048358064267)
      40| (20,1826685434290034100820683)
      80| (40,7968629609539008146703468397491602214377532161823)
\end{verbatim}
\normalsize
%
The cost here does not change essentially with the \ {\tt x <-> y}  \ 
swap --- in both programs.
\bigskip

\underbar{{\bf Conclusion:}} \ \ It looks like 
%
\begin{itemize}
\setlength\itemsep{0pt}
\item {\bf (1)} For the polynomials within a very large size \\ 
      (say $(2*y*z + z + y*x + 3*y + 1)^{20}$ ) \ 
      {\tt DoCon}  arithmetic \ (\verb#+, *#) \ is almost as fast as of 
     {\tt Axiom}, and {\tt MuPAD}.

\item {\bf (2)} 
   {\tt MuPAD} arithmetic seems to have somewhat better asymptotic.
\end{itemize}
%
{\bf (1)} reflects a good quality of the GHC {\tt Haskell} 
compiler and possible `lazy' functional system efficiency.
\\
{\bf (2)} may be caused by a simplest naive algorithm of DoCon
for the polynomial product (no special clever methods applied).

And everything in {\tt DoCon} (except arithmetic of long integers) 
is written in {\tt Haskell}, the exponents consist of the 
arbitrary-size integers, the polynomial data contains any 
pp-ordering term and any variable list, the program works over 
any commutative ring \ldots



\newpage 
\underbar{{\bf Details}}
\medskip

\underbar{{\tt Integer} model:}
\\
both {\tt MuPAD} and {\tt DoCon} use the arbitrary size representation of 
{\tt Integer}.
\bigskip

\underbar{On laziness}
\\
We should separate the cost of \ $f^n$ \ computation itself from 
the cost of the result output.

In {\tt MuPAD} the output is suppressed by the {\tt `:'} postfix: \ 
\verb#p := f^n:# 
\\
In {\tt Axiom} it is done by appending {\tt `;'}.
\\
In the `lazy' system, we cannot do this. 
So, we provide the `equivalent' program for the comparison, the one 
composed with the `forcing' function \ {\tt force}.
{\tt force} should have a small output and bring small extra cost 
respectively to \ $f^n$ and should force the evaluation of all the 
parts of $f^n$.
We choose 
\begin{center}
          {\tt force r = show (sumOfExponents r, sumOfCoefficients r)}
\end{center}
In \ {\tt R[z][y][x], R[x][y]} \ model, we mean by `coefficients' 
the leaf coefficients from {\tt R}.
And for {\tt R = Q}, sum the numerators and denominators separately.
\bigskip
\bigskip
\bigskip



\underbar{{\bf Programs in detail}}
\bigskip

\underbar{Powering in {\tt Q[x,y]}}
%
\footnotesize
\begin{verbatim}
  In MuPAD:  
  ---------  
    n  := ...:    
    f  := poly( x^2 + (2/3)*x*y + (3/4)*y, [x,y] ):
    t0 := time();  p := f^n:  time() - t0;
      Runing:
            mupad;  read("m");  quit

  In Axiom
  ---------  
    P := MPOLY([x,y], Fraction Integer)
    )set message time on
    f :P := x^2 + (2/3)*x*y + (3/4)*y;
    n := 10;
    f^n;
       Running:  time axiom;  
                 )r a.input
                 )q 
                 y  


  In DoCon, Q[x,y] model:
  -----------------------
    import qualified Data.Map as Map (empty)
    import DExport      
    t n =                                      -- benchmark: snd (t n)
      let q1 = 1:/1  :: Fraction Z
          dQ = upField q1 Map.empty
          p1 = cToPol (lexPPO 2) ["x","y"] dQ q1
          f  = smParse p1 " x^2 + (2:/3)*x*y + (3:/4)*y "
          fp = f^n
      in  
      (fp, force fp)   
           where                  -- extra thing needed to compare to MuPAD
           force f = (fc cs, alteredSum es) 
                                         where  (cs,es) = unzip $ polMons f
           fc cs = sum $ map alteredSum [map num cs, map denom cs]
  
    Running:  ghci -package docon +RTS -M..m -RTS  Foo
              ...
              Foo> :set +s           
              Foo> snd (t n)


  In DoCon, Q[x][y] model:
  ------------------------
    module Foo where
    import qualified Data.Map as Map (empty)
    import DExport
      t n =                                     -- benchmark:  snd $ t n
      let q1 = 1:/1  :: Fraction Z
          dQ = upField q1 Map.empty
          x1 = cToUPol "x" dQ q1
          dX = upRing x1 Map.empty
          y1 = cToUPol "y" dX x1
          f  = smParse y1 " x^2 + (2:/3)*x*y + (3:/4)*y "
          fp = f^n
      in  
      (fp, force fp)
        where                                -- extra thing to meet MuPAD
        force f = (alteredSum $ exps f, m2 f)
        exps    = map snd . upolMons
        m2      = alteredSum . map m1 . pCoefs
        m1 f    = (alteredSum ns)+(alteredSum ds)
                  where
                  (ns,ds) = (map num $ pCoefs f, map denom $ pCoefs f)
\end{verbatim}
\normalsize




\newpage
\underbar{Powering in {\tt Z[z,y,x]}}
\bigskip

{\footnotesize
\begin{verbatim}
  In Axiom: 
  ---------   
    P := MPOLY([z,y,x],Integer)
    )set message time on
    f :P := 2*y*z + z + y*x + 3*y + 1; 
    n := ...;
    f^n;
    Running:  axiom;  )read a.input   )q y



  In MuPAD:   
  ------
    n  := ...:    
    f  := poly( 2*y*z + z + y*x + 3*y + 1, [z,y,x]):
    t0 := time(); 
    p := f^n:  time() - t0;  quit
    Running:                       mupad;  read("m")




  In DoCon, Z[z,y,x] model:  (a bit simpler than for Q[x,y])
  ------------------------- 
  import DExport
  main = interact (\s -> shows (snd $ t $ read s) "\n")
  t n =                                      -- benchmark: snd (t n)
    let p1 = cToPol (lexPPO 3) ["z","y","x"] dZ 1
        f  = smParse p1 " 2*y*z + z + y*x + 3*y + 1 "
        fp = f^n
    in
    (fp, force fp)
      where                          -- extra thing needed to compare to  MuPAD
      force f = (alteredSum cs, alteredSum es)
                                where  (cs,es) = unzip $ polMons f
  Example of running:
    ghci -package docon +RTS -M..m -RTS  Main
    ...
    Main> :set +s
    Main> main
    2                -- and press  Enter, Ctrl-d  to complete input
\end{verbatim}




\newpage
\begin{verbatim}
  DoCon, Z[x][y][z] model:  
  ------------------------  
  module Foo where
  import qualified Data.Map as Map (empty)
  import DExport
  t n = let x1 = cToUPol "x" dZ 1 :: UPol Z       -- benchmark: snd (t n)
            dX = upRing x1 Map.empty
            y1 = cToUPol "y" dX x1
            dY = upRing y1 Map.empty
            z1 = cToUPol "z" dY y1
            f  = smParse z1 " 2*y*z + z + y*x + 3*y + 1 "
            fp = f^n
        in
        (fp, force fp)
          where                                  -- extra thing to meet MuPAD
          force f = (alteredSum $ exps f, m3 f)
          exps    = map snd . upolMons
          m3      = alteredSum . map m2 . pCoefs
          m2      = alteredSum . map m1 . pCoefs
          m1      = alteredSum . pCoefs
\end{verbatim}
}



\newpage
\subsection{ GCD in Z[z,y,x] }
% ----------------------------
\label{sec-pe.g}


\underline{In {\tt Axiom}:}
{\footnotesize
\begin{verbatim}
  P := MPOLY([z,y,x],Integer)
  )set message time on
  d :P   := (2*z + 3*y + 4*x)*(z*y*x^2 + y^3 + 1)
  n      := ...;
  m      := ...;
  dp     := d^n;
  f1 : P := z + y + x;
  f2 : P := z - y + x + 2;
  g      := gcd (dp*f1^m, dp*f2^m);
                                    Running:  time  axiom  
                                              )r a.input   
                                              )q 
\end{verbatim}
}
\bigskip

\underline{In {\tt MuPAD}:}
{\footnotesize
\begin{verbatim}
  t0   := time();                             -- file  ./m
  n    := ...:
  m    := ...:
  vars := [z,y,x]:
  d    := poly( (2*z + 3*y + 4*x)*(z*y*x^2 + y^3 + 1), vars ):
  dp   := d^n:
  f1   := poly( z + y + x,     vars ):
  f2   := poly( z - y + x + 2, vars ):
  g    := gcd (dp*f1^m, dp*f2^m);
  time() - t0;
                        Running:   time mupad < m
\end{verbatim}
}
\bigskip


\underbar{In DoCon:}
{\footnotesize
\begin{verbatim}
  import DExport
  main = interact process  where  process s = case read s :: (Z,Z) of
                                                             (n,m) -> shows (f n m) "\n"
  f n m = let p1      = cToPol (lexPPO 3) ["z","y","x"] dZ 1  :: Pol Z
              d       = smParse p1 "(2*z + 3*y + 4*x)*(z*y*x^2 + y^3 + 1)"
              dp      = d^n
              [f1,f2] = map (smParse p1) ["z+y+x", "z-y+x+2"]
          in  gcD [dp*f1^m, dp*f2^m]

  Example of running:  ghci -package docon +RTS -M..m -RTS  Main
                       ...
                       Main> :set +s
                       Main> main
                       (2,2)        -- press  Enter, Ctrl-d  to complete input
\end{verbatim}
}

\newpage
\underbar{Timing [sec]:}
{\footnotesize
\begin{verbatim}
  ghc-5.02.2 + DoCon make \ a.out: \ read n, show $ t n,  time a.out

            DoCon       Axiom             MuPAD
                                     Z[z,y,x]  Z[y,x,z]
  (n,m) 
  (2, 8)|   1.0          5.0           3.0        23
  (2,12)|   3.8         15             6.7       -
  (2,16)|   9.9         30            15         -
  (2,20)|  21           63            31         186 
  (2,24)|  42           93            63         372
  (2,28)|  78          165           129         -          

--------------------------------------------------------------------------
Further comparing versions of DoCon and GHC  
-------------------------------------------

June 2005.  600 Mhz machine.  -M24m for memory.   

main = putStr $ shows (f n m) "\n"

Making:  ghc --make -O ... Main
Runing:  ./a.out +RTS -M24m -RTS

              DoCon-2.06,    DoCon-2.09
              ghc-5.02.3     ghc-6.4.1-pre-June-14-2005

Code size [byte]:                              ghc-July-12
  a.out  |    8.833.439      7.113.969         7.143.078
  Main.o |       11.104         13.560            13.560 

Time [sec]
  (n,m) 
  ------------------------------------- 
  (2,24)|      31              33              32
  (2,28)|      58              62              60

Minimal -M size [Mb]
  (2,24)|       4               4
  (2,28)|       5               5               5              

The time does not change with the memory increase above 24 Mb.
--------------------------------------------------------------------------
\end{verbatim}
}


It is measured for all the computation, including the evaluation of \ 
\verb#d^n*f1^m, d^n*f2^m#.
This is because in the `lazy' system it takes extra  considerations
to separate the cost of this preliminary \ \verb#d^n*f1^m, d^n*f2^m#.

{\tt DoCon} \ 
  applies here the plain {\tt Z[z,y,x]} model, though its GCD method 
  still gets to the intermediate domain of {\tt Z[z][y]} \ldots \
  The initial permutations on {\tt [z,y,x]} could make difference 
  for the computation cost. But for this example, it is less than  
  \verb#15%#.

{\tt MuPAD} \ is not so lucky: 
               some of these permutations increase the cost 7 times.
\bigskip

\underbar{{\bf Conclusion}}
\\
In this example {\tt DoCon}  looks like a winner.
And {\tt MuPAD} slows down considerably with the unlucky variable 
permutation.
\medskip

\underbar{Comments}
\\
Either {\tt MuPAD} has to gain at other data for {\tt gcd},  
or something is wrong with its GCD algorithm for \ 
$R[x_1,\ldots,x_n]$. \ 
For, the very polynomial arithmetics in {\tt DoCon}  looks as fast as 
of {\tt MuPAD} (Section~\ref{sec-pe.p}) --- for the polynomials 
of the size like in this example. And {\tt DoCon}  applies the old 
simplest GCD method, known from the popular book \cite{Kn} by 
D.Knuth (Volum 2, Section 4.6.1).




\newpage
\subsection{ Gr\"obner basis in $Q[x_1,\ldots,x_n]$ }
% ---------------------------------------------------
\label{sec-pe.gr} 
  
We denote \ \ {\tt Q = Fraction Z}.

The programs are asked to find the \ {\it reduced Gr\"obner basis} \
for a list  \ {\tt fs} \ of polynomials under the same power 
product comparison. The following examples were tried.
\bigskip


\subsubsection{`Consistency'}
\label{seq-pe.gr.consist}

{\bf Problem.} Derive the consistency condition for the given \ 
{\tt n} \ generic monic polynomial equations \ {\tt fs}, \ 
each in variable \ {\tt x} \ over the domain of rationals \ 
{\tt Q = Fraction Z}:
\\
the condition(s) on the parameter coefficients \ $a_{i,j}$, \ldots 
of the polynomials from {\tt fs} for {\tt fs} to have a common root 
in the complex numbers (resultant(s)).

Solution: consider {\tt fs} as polynomials in \ {\tt x, a$_{i,j}$} \ 
and set any pp-ordering in which {\tt x} is greater than any power
product free of {\tt x}, \ find the Gr\"obner basis \ $gs$ \ for \ 
{\tt fs}. The set \ \ \verb#gs0 = [g <- gs | deg_x g = 0]#.
\\
presents the neccessary conditions for the consistency. 
Theay are also sufficient for the consistency of each pair \ 
{\tt (f$_i$, f$_j$)}. 

I do not know so far whether they are sufficient in general.

But our business here is only to set several parameters $a_{i,j}$
in {\tt fs} and the pp-ordering, and see the cost at which the 
constant-in-x polynomials appear.

{\bf Case n = 3:}
\begin{center}
   \verb# fs = [x^2 + x*a1 + a0,  x^2 + x*b1 + b0,  x^2 + x*c1 + c0]#
\end{center}
for the lexicographic pp-ordering and the variables listed in 
decreasing order are \\ 
{\tt [x,a1,b1,c1,a0,b0,c0]}. \ 
The found Gr\"obner basis contains 9 polynomials: 
\footnotesize
\begin{verbatim}
  b1^2*c0 - b1*c1*b0 - b1*c1*c0 + c1^2*b0 + b0^2 - 2*b0*c0 + c0^2,
  a1*b0 - a1*c0 - b1*a0 + b1*c0 + c1*a0 - c1*b0,
  a1*b1*c0 - a1*c1*c0 - b1*c1*a0 + c1^2*a0 + a0*b0 - a0*c0 - b0*c0 + c0^2,
  a1^2*c0 - a1*c1*a0 - a1*c1*c0 + c1^2*a0 + a0^2 - 2*a0*c0 + c0^2,
  x*b0 - x*c0 - b1*c0 + c1*b0,
  x*a0 - x*c0 - a1*c0 + c1*a0,
  x*b1 - x*c1 + b0 - c0,
  x*a1 - x*c1 + a0 - c0,
  x^2 + x*c1 + c0
\end{verbatim}
\normalsize
4 of them do not depend on \ {\tt x}. 

The programs are as follows:


\newpage
{\footnotesize
\begin{verbatim}
  In DoCon:
  ---------
  conds =
    let q1   = 1:/1  :: Fraction Z
        dQ   = upField q1 Map.empty
        vars = ["x","a1","b1","c1","a0","b0","c0"]
        ppo  = lexPPO 7
        p1   = cToPol ppo vars dQ q1
        fs   = map (smParse p1) [ "x^2 + x*a1 + a0",
                                  "x^2 + x*b1 + b0",
                                  "x^2 + x*c1 + c0"
                                ]
        gs  = fst $ gxBasis fs
        gsM = transp $ Mt [gs] Map.empty
        pps = map (vecRepr . lpp) gs       -- for control
      in
      (pps, gsM)

    Running:  ghci -package docon Main +RTS -M..m -RTS
              Main> :set +s
              Main> let (ps, gsM) = conds
              ...
              Main> gsM
              ...
              Main> ps 

  In Axiom:  
  ---------  
  vars := [x,a1,b1,c1,a0,b0,c0];
  P    := MPOLY(vars, Fraction Integer)
  )set message time on
  fs : List P := [x^2 + x*a1 + a0, x^2 + x*b1 + b0, x^2 + x*c1 + c0];
  gs := groebner fs;
  ms := [leadingMonomial g  for g in gs];
  )spool res
  output (# gs); output ms; output gs;
  )spool off
    -- It writes the result to file  ./res
    -- (# gs), ms  are for control
    -- But we do not know so far how to specify the term ordering in 
    -- Axiom, do not know in what ordering this Groebner basis is found.
\end{verbatim}


\newpage
\begin{verbatim}
  In MuPAD:  
  ---------  
  vars := [x,a1,b1,c1,a0,b0,c0]:
  cp   := LexOrder:
  grb  := func( groebner::gbasis(hs,cp), hs ):
  lm   := func( lmonomial(h,cp), h ):
  fs   := [poly(x^2 + x*a1 + a0, vars),   -- ** enter this as 1 line
           poly(x^2 + x*b1 + b0, vars),   -- ** when running
           poly(x^2 + x*c1 + c0, vars)    -- ** MuPAD   
          ]:                              -- **
  t0 := time():  gs := grb(fs):  time() - t0;
  ms := map(gs,lm):
  write(Text,"res" ,ms):       -- see the files  ./res, 
  write(Text,"res1",gs):       --                ./res1
  quit
\end{verbatim}
}
%
But this task is too fast to compute. Let us consider
\bigskip



{\bf Case n = 4, degree = 3:} \ \ \ The programs are as follows:

{\footnotesize
\begin{verbatim}
  In DoCon:
  ---------
  conds =
     let
       q1   = 1:/1  :: Fraction Z
       dQ   = upField q1 Map.empty
       vars = ["x","c2","d2","a1","b1","c1","d1","a0","b0","c0","d0"]
       ppo  = (("",11), cp, [])
       cp (Vec (j:js)) (Vec (j':j's)) = 
                                case compare j j'
                                of
                                  EQ -> degLex (Vec js) (Vec j's)
                                  v  -> v
       p1   = cToPol ppo vars dQ q1
       fs   = map (smParse p1) [ "x^3          + x*a1 + a0",
                                 "x^3          + x*b1 + b0",
                                 "x^3 + x^2*c2 + x*c1 + c0",
                                 "x^3 + x^2*d2 + x*d1 + d0"
                               ]  
       gs  = fst $ gxBasis fs
       gsM = transp $ Mt [gs] Map.empty
       pps = map (vecRepr . lpp) gs       -- for control
    in (pps, gsM)
\end{verbatim}
}
%
We skip the parameters \ {\tt a2, b2} \ because the task is too
expensive.
To compute it under \ {\tt lexPPO 11} \ also looks too expensive
(in {\tt DoCon} ). 
So, {\tt DoCon}  sets the {\tt degLex} ordering for the tail power 
product.

Then, the Gr\"obner basis contains 65 polynomials; 
29 of them do not depend on \ {\tt x}: 

{\footnotesize
\begin{verbatim}
  d2*a0^2 - ... - b1^2*a0 + b1^2*d0 + b1*d1*a0 - b1*d1*b0,
  c2*a0*b0 - ... 0 + b1*c1*b0 - b1*c1*d0 - b1*d1*b0 + b1*d1*c0,
  c2*a0^2 - ...  + b1*c1*b0 - 2*b1*c1*d0 - 2*b1*d1*b0 + 2*b1*d1*c0,
  c2*a1*b0 - ... + d2*a1*c0 + d2*b1*a0 - d2*b1*c0 - d2*c1*a0 + d2*c1*b0,
  a1^3*b0 - ...  - b1^3*a0 - a0^3 + 3*a0^2*b0 - 3*a0*b0^2 + b0^3,
  ...
  x*b1^3*d0^2 - 2*x*b1^2*d1*b0*d0 - ... - 2*d1^2*b0^2*d0,
  ...
  x^2*c0 - x^2*d0 - x*c2*d0 + x*d2*c0 - c1*d0 + d1*c0,
  x^2*b0 - x^2*d0 + x*d2*b0 - b1*d0 + d1*b0,
  x^2*a0 - x^2*d0 + x*d2*b0 - a1*b0 + b1*a0 - b1*d0 + d1*b0,
  x^2*c1 - x^2*d1 - x*c2*d1 + x*d2*c1 + x*c0 - x*d0 - c2*d0 + d2*c0,
  x^2*b1 - x^2*d1 + x*d2*b1 + x*b0 - x*d0 + d2*b0,
  x^2*d2 - x*b1 + x*d1 - b0 + d0,
  x^2*c2 - x*b1 + x*c1 - b0 + c0,

  x^3 + x*b1 + b0
\end{verbatim}


\begin{verbatim}
  In MuPAD:         (it succeeds with  LexOrder  too)
  ---------
  vars := [x,c2,d2,a1,b1,c1,d1,a0,b0,c0,d0]:
  cp   := LexOrder:
  grb  := func( groebner::gbasis(hs,cp), hs ):
  lm   := func( lmonomial(h,cp), h ):
  fs   := [poly(x^3 + x*a1 + a0,          vars),   -- ** enter as One line
           poly(x^3 + x*b1 + b0,          vars),
           poly(x^3 + x^2*c2 + x*c1 + c0, vars),  
           poly(x^3 + x^2*d2 + x*d1 + d0, vars)
          ]:
  t0 := time():  gs := grb(fs):  time() - t0;
  ms := map(gs,lm):
  write(Text,"res" ,ms):
  write(Text,"res1",gs):
  quit

  In Axiom:  as earlier, only change  vars, fs  respectively.
  ---------
\end{verbatim}
}





\newpage
\subsubsection{AL --- Arnborg-Lazard system}
\medskip 
is 
\begin{verbatim}
      [x^2*y*z + x*y^2*z + x*y*z^2 + x*y*z + x*y + x*z + y*z,
       x^2*y^2*z + x^2*y*z + x*y^2*z^2 + x*y*z + x + y*z + z,
       x^2*y^2*z^2 + x^2*y^2*z + x*y^2*z + x*y*z + x*z + z + 1
      ]
\end{verbatim}
in \ {\tt Q[x,y,z]}, \ pp-ordering = {\tt degLex} \ 
(DegreeOrder in {\tt MuPAD}).

This example is said to come from certain paper by
Faugere, Gianni, Lazard, Mora of 1989.

The found Gr\"obner basis contains 15 of polynomials, their leading
power products are  
\begin{center} 
               {\tt [0,0,4], [0,1,3], [0,2,2], [0,3,1], [0,4,0]}, \\
               {\tt [1,0,3], [1,1,2], [1,2,1], [1,3,0], [2,0,2]}, \\
               {\tt [2,1,1], [2,2,0], [3,0,1], [3,1,0], [4,0,0]}
\end{center}



\underbar{Programs}  
\\
are like in `consist' test, only 

{\tt vars = ["x","y","z"], \ ppo = (("degl",3), degLex, [])}
\\
(in {\tt MuPAD}, \ {\tt ppo = DegreeOrder}).



\subsubsection{Cyclic roots}

Do not confuse this example with the one of the roots of equation \ 
$x^n-1$.

It is said, this example comes from the works by G.Bjoerck: \\
{\tt fs = [}

   $ x_1 + x_2 + \ldots\ + x_n, $ 

   $ x_1 x_2 + x_2 x_3 + \ldots\ + x_{n-1} x_n + x_n x_1, $

   \ldots 

   $ x_1 x_2 .. x_{n-1} + x_2 x_3 .. x_n + \ldots\ + x_{n-1} x_n .. x_{n-3}
                                                  + x_n x_1 .. x_{n-2}, $

   $ x_1 x_2 .. x_n - 1 $ \ {\tt ]},
\begin{verbatim}
  gs            = Groebner basis( fs ),
  variables     = [x_1 .. x_n],
  pp-comparison = degRevLex   (DegInvLexOrder in MuPAD)
\end{verbatim}
%
For \ {\tt n = 2, 3, 5, 6} \ it appears that \\
{\tt I = Ideal(gs) (= Ideal(fs))} \ has the zero dimension. \\
That is for each  $i \in [1..n]$  there exists \ $g \in gs$ \ 
such that \ $ lpp(g) = {x_i}^{n_i}, \ n_i > 0. $


\newpage
{\bf Some control:}\\ 
for \ {\tt n = 4}, \ {\tt gs} contains \ 7 \ polynomials, and their
leading power products are
\footnotesize
\begin{verbatim}
  [[1,0,0,0],[0,2,0,0],[0,1,2,0],[0,1,1,2], [0,1,0,4],[0,0,3,2],[0,0,2,4]]
\end{verbatim}
\normalsize
; for \ {\tt n = 5}, \ {\tt gs} contains \ 20 \ polynomials, and their
leading power products are\\
{\footnotesize
\begin{verbatim}
  [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0],[0,1,2,0,0],[0,0,0,4,0],
   [0,0,1,3,0],[0,1,0,3,0],[0,0,2,2,0],[0,1,1,2,0],[0,1,1,1,2],
   [0,1,0,0,5],[0,0,1,2,3],[0,1,0,2,3],[0,0,1,1,5],[0,0,2,0,5],
   [0,0,0,3,4],[0,0,0,0,8],[0,0,0,1,7],[0,0,1,0,7],[0,0,0,2,6]
  ]
\end{verbatim}
}


\underbar{{\tt DoCon} program}

The below function \ {\tt gcRoots} 

  takes \ {\tt n} \ and builds the needed equations \ 
  {\tt eqs = eqs(n)} \ in variables \ $[x_1,\ldots,x_n]$; 

  finds their Gr\"obner basis \ {\tt gs} \ 
  and its leading power products \ {\tt ps};

  returns \ {\tt (eqsM, ps, gsM)}, \ where \ {\tt eqsM, gsM} \ 
  are \ {\tt eqs} and {\tt gs} respectively converted to the 
  matrices for the need of nice printing.

  {\tt eqsM, ps} \ are used for the control.

Run this function, for example, in Interpreter:
{\footnotesize
\begin{verbatim}
  ghci -pacage docon M.hs  +RTS -M... -RTS
  ...
  M> :set +s
  M> let (eqs, ps, gsm) = gcRoots n    -- put n = 4,5,...          
  ...
  M> eqs                             -- control
  ...
  M> gs                              -- time consuming part
  ...
  M> ps                              -- control
  ...
\end{verbatim}
}


\newpage
{\footnotesize
\begin{verbatim}
  import qualified Data.Map as Map (empty)
  import DExport
  type K = Fraction Z
  gcRoots :: Z -> (Matrix (Pol K), [[Z]], Matrix (Pol K))
  gcRoots    n =  (eqsM, pps, gsM)
    where
    gs   = fst $ gxBasis eqs
    pps  = map (vecRepr . lpp) gs        -- for control
    eqsM = transp $ Mt [eqs] Map.empty
    gsM  = transp $ Mt [gs]  Map.empty
    eqs  =
      let
        unK   = 1:/1 :: Fraction Z
        dK    = upField unK Map.empty
        vars  = map (('x':) . show) [1..n]       -- ["x1".."xn"]
        o     = (("degRevLex",n), degRevLex, [])
        unp   = cToPol o vars dK unK
        vpols = varPs unK unp            -- [x1..xn] as polynomials
        fn    = (product1 vpols) - unp   -- x1*..+xn - 1

        eqs' (monpols:mpss) vps k =
                      if k==(n-1) then  map sum1 (monpols:mpss)
                      else
                        let rotate (x:xs) = xs++[x]
                            vps'          = rotate vps
                            mps           = zipWith (*) monpols vps'
                        in  eqs' (mps:monpols:mpss) vps' (k+1)
      in
      fn: (eqs' [vpols] vpols 1)
\end{verbatim}
}



\newpage
\underbar{MuPAD program}

{\bf Caution:} \ you may need to remove all line breaks in each of the 
below polynomial expressions:
 
{\footnotesize
\begin{verbatim}
  vars := [x1,x2,x3,x4,x5,x6]:
  cp   := DegInvLexOrder:
  grb  := func( groebner::gbasis(hs,cp), hs ):
  lm   := func( lmonomial(h,cp), h ):

  f1 := poly( x1*x2*x3*x4*x5*x6 - 1, vars ):
  f2 := poly( x1*x2*x3*x4*x5 + x1*x2*x3*x4*x6 + x1*x2*x3*x5*x6
              + x1*x2*x4*x5*x6 + x1*x3*x4*x5*x6 + x2*x3*x4*x5*x6,
              vars
            ):
  f3 := poly( x1*x2*x3*x4 + x2*x3*x4*x5 + x1*x2*x3*x6 + x1*x2*x5*x6
              + x1*x4*x5*x6 + x3*x4*x5*x6,
              vars
            ):
  f4 := poly( x1*x2*x3 + x2*x3*x4 + x3*x4*x5 + x1*x2*x6 + x1*x5*x6 +
              x4*x5*x6,
              vars
            ):
  f5 := poly( x1*x2 + x2*x3 + x3*x4 + x4*x5 + x1*x6 + x5*x6, vars):
  f6 := poly( x1 + x2 + x3 + x4 + x5 + x6, vars ):
  fs := [f1,f2,f3,f4,f5,f6]:

  t0 := time():
  gs := grb(fs):
  t  := time() - t0;

  ms := map(gs,lm):
  write(Text,"res" ,ms):
  write(Text,"res1",gs):
  quit
\end{verbatim}
}

Usage: \ put this program to file \ {\tt m} \ and command 

  \verb# time  mupad < m #
\medskip

This will 

  form the equations for \ {\tt n = 6}, \ \ 
  find their Gr\"obner basis \ {\tt gs},

  print \ {\tt gs} \ to file \ {\tt res}, \ \ 
  print leading monomials of \ {\tt gs} \ to file \ {\tt res1}, 

  print the timing.


\newpage
\underbar{Axiom program}

{\bf Caution:} \ you may need to remove all line breaks in each of the 
below polynomial expressions:
 
{\footnotesize
\begin{verbatim}
  vars := [x1,x2,x3,x4,x5,x6];
  P    := MPOLY(vars, Fraction Integer)
  )set message time on
  f1 :P := x1*x2*x3*x4*x5*x6 - 1;
  f2 :P := x1*x2*x3*x4*x5 + x1*x2*x3*x4*x6 + x1*x2*x3*x5*x6
            + x1*x2*x4*x5*x6 + x1*x3*x4*x5*x6 + x2*x3*x4*x5*x6;

  f3 :P := x1*x2*x3*x4 + x2*x3*x4*x5 + x1*x2*x3*x6 + x1*x2*x5*x6
            + x1*x4*x5*x6 + x3*x4*x5*x6;

  f4 :P := x1*x2*x3 + x2*x3*x4 + x3*x4*x5 + x1*x2*x6 + x1*x5*x6 + x4*x5*x6;
  f5 :P := x1*x2 + x2*x3 + x3*x4 + x4*x5 + x1*x6 + x5*x6;
  f6 :P := x1 + x2 + x3 + x4 + x5 + x6;

  fs : List P := [f1,f2,f3,f4,f5,f6];
  gs := groebner fs;   ms := [leadingMonomial g  for g in gs];
  )spool res
  output (# gs); output ms; output gs;
  )spool off
             Running:   time axiom
                        )r a.input
                        )q
\end{verbatim}
}



\newpage
\subsubsection{Timing [sec]:}
%
{\footnotesize
\begin{verbatim}
                             DoCon                 Axiom       MuPAD

  `Consistency' n = 3 |      0.3                     0.2        0.4
                n = 4 |    174 (special order)      34         17 
  AL                  |      2.2                  82, 329       1.9
  Cyclic roots (5)    |      4.1                     -          -
               (6)    | > 1000 (interrupted,      > 1800       80
                                50Mb used)
  Note: 
  Axiom computes the Groebner basis in unknown to us term ordering.
  The numbers  82, 329  in AL example correspond to the lists 
  [x,y,z], [z,y,x].
\end{verbatim}
}
\bigskip

\underbar{Comments}
\\
Generally, the Gr\"obner basis task is rather expensive. In unlucky
cases the cost of finding Gr\"obner basis for \ 
$ F = [f_1,\ldots,f_k]$ \ in \ $R[x_1,\ldots,x_n]$ \ 
may grow as about
$$       O( (d \cdot k)^{2^n} ), \ \ \ d = max_{f \in F} totalDegree(f).
$$
Hence any algorithmic method has to ``drop into a hole'' of many hours
of computation on some example of small enough size.
Very naturally, the Gr\"obner basis algorithms in 
{\tt DoCon, Axiom, MuPAD} contain several optimization rules of the
mathematical nature. But most probably, they have different rule sets, 
the author of this manual does not know the precise algorithms applied 
in {\tt Axiom} and {\tt MuPAD}. 
The purpose of these optimizations is to prevent 
``dropping into a hole'' in possibly  many cases.

Concerning the nature of {\tt Axiom} falls, we cannot say anything
definite, because do not know so far how to control the term ordering.

The last example is unlucky for the {\tt DoCon} optimization.
We think, this is not due to the programming system.

Probably, {\tt DoCon} has to optimize its Gr\"obner basis strategy.

May this {\tt DoCon} loss in \ CyclicRoots(6) \ be due to some bug?
Hardly so. Because the cases of \ {\tt n = 4, 5} \ are computed 
correct, as well as several other examples, not mentioned in this 
manual.




\newpage
\subsection{ Factoring in \ $GF(p)[x]$ }
% --------------------------------------
\label{sec-pe.f1}  

{\footnotesize
\begin{verbatim}
  Kn   factor (t^8 +t^6 +10*t^4 +10*t^3 +8*t^2 +2*t +8)   in  (Z/(13))[t]
  --
    = [(t^3 +8*t^2 +4*t +12, 1), (t^4 +2*t^3 +3*t^2 +4*t +6, 1), (t+3, 1)]  

  Z3-81  factor (t^81 - t)  over Z/(3) -->
  -----                         t*(t+1)*(t+2)                    -- 1
                                *(t^2+1)*(t^2+2*t+2)*(t^2+t+2)   -- 2
                                *(t^4+2*t+2)*(t^4+t+2) *         -- 4
                                ... further, all of  deg = 4
                                *(t^4+t^3+t^2+2*t+2)*(t^4+t^3+t^2+t+1)

  Z3-36-1  factor (t^36 + t + 1)  over Z/(3) -->
  -------     (t+2)
             *(t^3 +2*t^2 +2*t +2)
             *(t^13 +t^11 +2*t^10 +t^8 +t^7 +t^6 +2*t^5 +t^3 +t^2 +2)
             *(t^19 +2*t^18 +t^16 +2*t^15 +2*t^14 +t^10 +2*t^8 +2*t^7
               +t^6 +2*t^3 +2*t^2 +2*t +2
              )

  Z3-72-1    factor (t^72 + t + 1)  over Z/(3) -->
  -------                         [p(1), p(2), p(3), p(4), p(5), p(6)],
                                  deg p(i) = [1, 4, 4, 18, 22, 23]

  Z3-144-1   factor (t^144 + t + 1)  over Z/(3)  -->
  --------                                  [p(1), p(2), p(3), p(4)],
                                            deg p(i) = 1, 22, 29, 92.

  Program in DoCon:
  -----------------
  module Foo where
  import qualified Data.Map as Map (empty)
  import DExport
  t p str =                                  -- example:  t 3 "t^81 - t"
    let                                    
        iI = eucIdeal "be" p [] [] [(p,1)]   -- start preparing K = Z/(p)
        r0 = Rse 0 iI dZ                     -- 0 in Z/I
        dK = upField r0 Map.empty
        p1 = cToUPol "t" dK r0               -- <- K[t]
        f  = smParse p1 str          
    in  writeFile "res" $ show $ factor f
  Running:
           run ghci interpeter, see the result in file  ./res 


 
  In Axiom:  
  --------    P := UnivariatePolynomial(t, PrimeField ...)
              )set message time on
              f :P := ...
              factor(f)
              Running:     time  axiom  `)r a.input   )q y'

  In MuPAD:   q := ...:
  ---------   f := poly( ..., [t], IntMod(q) ):
              t := time():
              factor(f);    time() - t;  quit
    Running:
    write the above program to file ./m and command  time mupad < m   
    To see the result in the file  ./t  apply   tee | time mupad > t
    and command there  read("m"); Control-d
\end{verbatim}
}


\underbar{Timing [sec]:}

{\footnotesize
\begin{verbatim}
              DoCon    Axiom     MuPAD
  Kn      |    0.1      0.2       0.2
  Z3-81   |    0.5      0.5       0.6
  Z3-144-1|    1.2      1.9       2.9
  Z3-288-1|    3.4     20        16
  Z3-432-1|   12       55       114 
  Z3-576-1|   39       83       618         
\end{verbatim}
}
\medskip
                       
\underbar{\bf {Conclusion}}
\\
This table shows that {\tt DoCon}  and {\tt Axiom} computation 
seem to have the same cost order in {\tt n} on this {\tt Z3-n} task, 
and {\tt MuPAD} seems to have somewhat higher cost order. 




\newpage
\subsection{ Factoring in \ $GF(p)[x,y]$ }
% ----------------------------------------
\label{pe.f2} 


\underbar{{\bf Example to start with:}} \ \ 
factoring in \ {\tt (Z/(5))[x,y]}
%
{\footnotesize
\begin{verbatim}
  E4-1   factor (f*h),  f = x^4 + y*(y*x^2 + 1)      -- irreducibles,
  ----                  h = x^4 + y*(y*x + y^2 + 2)  -- n = 4 

  E4-2   factor (f*h),  f = x^4 + y*(y^2*x^2 + 1)    -- irreducibles
  ----                  h = x^4 + y*(y*x + y^2 + 2)  --

  Program in DoCon:
  -----------------       
  import qualified Data.Map as Map (empty)
  import DExport
  main = interact process           -- it reads, factors, tests and prints out 
    where
    process s = case  tf (read s :: (Z, [String], String, String))
                of
                (b, ft) -> shows b $ ("\n"++) $ shows ft "\n"

  type P = Pol (ResidueE Z)    -- (Z/(q))[x,y]

  tf :: (Z, [String], String, String) -> (Bool, Factorization P)
  tf    (q, vars,     fStr,   gStr  ) =
                       -- Read two polynomials, multiply them,
                       -- factor the product over  Z/(q),
                       -- multiply the factors by `unfactor',
                       -- return factors and test for their product.
    let                -- Example:   tf (5, ["x","y"], "x+y", "x-y")
       iI = eucIdeal "bef" q [] [] []
       r0 = Rse 0 iI dZ
       dK = upField r0 Map.empty
       p1 = cToPol (lexPPO 2) vars dK r0         -- unity polynomial
       h  = canAssoc ((smParse p1 fStr)*(smParse p1 gStr))
       ft = factor h
    in ((canAssoc $ unfactor ft) == h,  ft)
  Usage:
    ghc $doconCpOpt --make Main
    time a.out +RTS -M... -RTS  < d > r  
                                      -- reads from file ./d writes to ./r 
    Example contents of ./d :  (5, 
                                ["x","y"],     -- try swapping x,y
                                "(x+y)^2*x", 
                                "x^3 - y + 3"
                               )




  in Axiom:  P := MPOLY([x,y], PrimeField 5)
  --------   )set message time on
             f :P := ... ;  
             h :P := ... ;  e := expand(f*h);  factor(e)

  in MuPAD:  q    := ...:
  ---------  vars := ...:
             f    := poly( ..., vars, IntMod(q)):  
             h    := poly( ..., vars, IntMod(q)):  
             t    := time():
             e := expand(f*h):  factor(e);  time() - t;  quit

  --------------------------------------------------------------
  Timing:     Example E4-1    Example E4-2
  -------    [x,y]  [y,x] 

  DoCon      0.8    0.6        2.4  2.4
  Axiom      1.2    2.2        3.3  2.6
  MuPAD      1.8    1.7       20    1.8
\end{verbatim}
}
\bigskip



\underbar{{\bf RandRand family}}
\medskip

Given, \ {\tt n}, {\tt m}, \ form random non-constant monic 
polynomials \ \ $f_1 \ldots f_m$ 
\\ 
from \ $(Z/(p))[x,y]$, \ 
$p = 5$, \ \ $\deg_v f_i \leq n$ \ for \ $v = x, \ y$ 
\\
($f_i$ often occur irreducible);
\\
find \ \ $factor (f_i*f_j)$ \ \ for \ $1 \leq i < j \leq m$.

Each pair \ $(f_i, f_j)$ \ defines two examples: with the variable
orders $[x,y]$ and $[y,x]$. 
Thus, for \ $f_1, f_2, f_3, f_4$, \ we have to factor 12 polynomials.

To avoid displaying too large expressions, we sieve each obtained
random polynomials by deleting some monomials. For example, for \ 
{\tt n = 8, 9, 10}, \ there remains each fourth or each fifth 
monomial.

The obtained poynomials are displayed below, so that the reader can 
see the precise test.

Below, the average and maximal time are shown for \ 
$n = 3, 8, 9, 10$.





\newpage
\underbar{n = 3}

{\footnotesize
\begin{verbatim}
  f1 = x^3*y^3 + 2*x^3*y + 3*x^3 + 3*x^2*y^3 + 3*x^2*y^2 + 4*x^2*y
        + 3*x^2 + 4*x*y^3 + x*y^2 + x*y + 2*x + y^2 + 4*y + 4

  f2 = x^3*y^3 + 3*x^3*y^2 + 3*x^3 + 2*x^2*y^3 + 3*x^2*y^2 + 4*x^2*y
        + 3*x*y^3 + 2*x*y^2 + 4*x*y + x + 3*y^3 + y^2 + y + 4

  f3 = x^3*y^3 + 4*x^3*y^2 + 3*x^3*y + 2*x^2*y^3 + 4*x^2*y + 4*x^2
        + x*y^3 + 2*x*y^2 + 4*x*y + 3*x + 4*y^2 + 4
\end{verbatim}
}
%
For the pairs \ {\tt (f1,f2), (f1,f3), (f2,f3)}, \ set the \ 
\verb#./d# \ file contents and run the program as shown above.
For example, for {\tt (f1,f2)}, put 
\footnotesize
\begin{verbatim}
  (5, 
   ["x","y"],
   "x^3*y^3 + 2*x^3*y + 3*x^3 + 3*x^2*y^3 + 3*x^2*y^2 + 4*x^2*y
     + 3*x^2 + 4*x*y^3 + x*y^2 + x*y + 2*x + y^2 + 4*y + 4 ",  

   "x^3*y^3 + 3*x^3*y^2 + 3*x^3 + 2*x^2*y^3 + 3*x^2*y^2 + 4*x^2*y
    + 3*x*y^3 + 2*x*y^2 + 4*x*y + x + 3*y^3 + y^2 + y + 4 "   
  )
\end{verbatim}
\normalsize

For \ {\tt n = 8,9,10}, \ the pairs 

  {\tt (f1,f2), (f1,f3), (f1,f4), \ (f2,f3), (f2,f4), (f3,f4)} 
\\
are tested. 
 
{\footnotesize
\begin{verbatim}
  Timing [sec]:   DoCon  Axiom  MuPAD           
  n=3 (f1,f2)       1.0    1.7    2.0
      (f1,f3)       0.5    1.6    2.2
      (f2,f3)       1.2    1.7    2.3
\end{verbatim}
}



\newpage
\underbar{n = 8}

{\footnotesize
\begin{verbatim}
  f1 =
    x^8*y^8 + 3*x^8*y^4 + 3*x^8*y + 4*x^8 + 2*x^7*y^6 + 4*x^7*y^2
     + x^7*y + 2*x^6*y^6 + 3*x^6*y^2 + 4*x^6 + x^5*y^6 + 2*x^5*y^3
     + 4*x^4*y^8 + 2*x^4*y^4 + x^4*y + x^3*y^5 + 2*x^3*y^2 + 4*x^2*y^8
     + 2*x^2*y^7 + 2*x^2*y^3 + 3*x^2*y^2 + 2*x*y^8 + 4*x*y^5 + 2*x*y^2
     + x*y + y^5 + 2*y + 2
  f2 =
    x^8*y^6 + x^8*y^5 + 2*x^8*y + 3*x^7*y^7 + 4*x^7*y^3 + x^7
     + x^6*y^8 + x^6*y^6 + 2*x^6*y^2 + x^5*y^7 + x^5*y^3 + x^4*y^7
     + x^4*y^5 + 2*x^4*y + 4*x^3*y^3 + 4*x^3 + 4*x^2*y^5 + 4*x^2
     + 4*x*y^8 + 4*x*y^6 + 3*x*y^2 + y^3 + 4*y + 4
  f3 =
    x^8*y^7 + 2*x^8*y^4 + x^7*y^8 + 3*x^7*y^7 + x^7*y^4 + 3*x^6*y^8
     + 3*x^6*y^6 + 2*x^6*y^3 + x^6 + 4*x^5*y^6 + x^5*y^3 + 2*x^5
     + 3*x^3*y^4 + 4*x^3*y + 4*x^2*y^6 + 4*x^2*y^2 + x*y^7 + x*y^3
     + 3*x*y^2 + y^3 + 4*y + 4
  f4 =
    x^8*y^8 + 3*x^8*y^5 + 4*x^7*y^8 + 2*x^7*y^3 + 2*x^6*y^8
     + 4*x^6*y^4 + 3*x^6*y^3 + 4*x^5*y^8 + 2*x^5*y^4 + x^4*y^8
     + 2*x^4*y^5 + 4*x^4 + 3*x^3*y^6 + 2*x^3*y^3 + 3*x^3 + 4*x^2*y^6
     + 2*x^2*y^5 + 2*x^2*y^2 + 2*x*y^8 + x*y^5 + 2*x*y + 4*y^7 + 2*y^6
     + 3*y^2 + y + 1



  Timing [sec]:
  n = 8       DoCon          Axiom         MuPAD
           [x,y] [y,x] 

  (f1,f2)     24     9 |   174   176 |    26     30
  (f1,f3)     11    33 |   166   160 |    23     28
  (f1,f4)    242   108 |   166   175 |    36     23
  (f2,f3)    245    25 |   153   146 |   252     32
  (f2,f4)    107   103 |   350   164 |   138     27
  (f3,f4)     61     8 |   297   151 |    33     26
\end{verbatim}



\newpage
\begin{verbatim}
---------------------------------------------------------------------
Further comparing versions of DoCon and GHC  
-------------------------------------------

June 2005.  600 Mhz machine.   -M60m  for memory.   

Parsing, factoring and testing of   f1 * f4    (for n = 8).

main = putStr (shows (tf (5, ["x", "y"], f1, f4)) "\n")

Making:  ghc --make -O $doconCpOpt  Main
Runing:  ./a.out +RTS -M60 -RTS

                      DoCon-2.06,     DoCon-2.09
                      ghc-5.02.3      ghc-6.4.1-June-14    July-12

Code size [byte]
  a.out  |            8.974.226        7.193.088          7.215.984
  Main.o |              202.288          124.188            119.704

Time [sec]
  [x,y] |             290              313                  308
  [y,x] |                              145                  144

Minimal -M size [Mb]
  [x,y] |               9                9                    9

The time does not change with the memory increase above 60 Mb.
---------------------------------------------------------------------
\end{verbatim}
}




\newpage
\underbar{n = 9}

{\footnotesize
\begin{verbatim}
  f1 =
    x^9*y^9 + 2*x^9*y^7 + 3*x^9*y^6 + 3*x^9*y^2 + 4*x^9*y + x^9
     + x^8*y^9 + 4*x^8*y^5 + 4*x^8*y^4 + 2*x^7*y^4 + 4*x^7*y^3
     + x^7*y^2 + 4*x^6*y^8 + 2*x^6*y^7 + 3*x^6*y + 3*x^6 + 3*x^5*y^2
     + x^5*y + 4*x^5 + 4*x^4*y^5 + 2*x^4*y^4 + 4*x^3*y^7 + 2*x^3*y^6
     + 3*x^3*y^5 + x^2*y^9 + 2*x^2*y^6 + 2*x^2 + 2*x*y^9 + x*y^6
     + x*y^5 + 2*x + 2*y^9 + 3*y^8 + 4*y^7 + y^3 + y^2 + y + 1
  f2 =
    x^9*y^8 + x^9*y^7 + 2*x^9*y^5 + x^9 + 3*x^8*y^8 + x^8*y^3 + x^8*y
     + x^8 + x^7*y^9 + 4*x^6*y^8 + 3*x^6*y^7 + 4*x^6*y + 3*x^6
     + 4*x^5*y^8 + x^5*y + x^5 + x^4*y + x^4 + 4*x^3*y^9 + 2*x^3*y^3
     + x^3*y + x^3 + x^2*y^5 + x^2*y^4 + 4*x*y^6 + 3*x*y^5 + 2*x*y^4
     + 2*x*y^3 + 4*y^8 + y^7 + 2*y^6 + 2*y^2 + 3*y
  f3 = 
    x^9*y^8 + 2*x^9*y^7 + x^9*y^6 + 2*x^9*y + x^8*y^9 + 3*x^8*y^4
     + 3*x^8*y^2 + 4*x^7*y^4 + 4*x^7*y^3 + 3*x^6*y^6 + x^6*y^5
     + 2*x^6*y^3 + 2*x^5*y^7 + 4*x^5*y^6 + x^4*y^7 + 4*x^4*y^6 + 2*x^4
     + 3*x^3*y^8 + 3*x^3*y^7 + x^2*y^9 + 3*x^2*y^7 + 3*x*y^7 + 2*x*y^4
     + x*y^3 + x*y^2 + 4*y^8 + 3*y^7 + 3*y^6 + 3*y^2 + 2*y + 1
  f4 =
    x^9*y^9 + 2*x^9*y^8 + 2*x^9*y^7 + x^9*y^3 + 4*x^9*y^2 + 3*x^9
     + 2*x^8*y^9 + 4*x^8*y^7 + x^8*y^2 + 4*x^8*y + 3*x^7*y^6
     + 4*x^7*y^5 + 2*x^7*y^4 + x^7 + 2*x^6*y^9 + 2*x^6*y^8 + 3*x^6
     + 2*x^5*y^8 + 3*x^5*y^7 + 2*x^5 + 3*x^4*y^9 + 4*x^4*y^2
     + 3*x^4*y + 2*x^4 + 2*x^3*y^4 + 4*x^3*y^3 + 4*x^2*y^5 + 3*x^2*y^4
     + 4*x^2*y^3 + 3*x^2*y^2 + 4*x*y^6 + 4*x*y^5 + 4*y^9 + 3*y^8
     + 4*y^7 + 2*y^4 + y^3 + 2

  Timing [sec]:
  n = 9         DoCon       Axiom          MuPAD
             [x,y] [y,x] 
  (f1,f2)     16    170 |   514   787 |    42   2851 |
  (f1,f3)    439     49 |   371   720 |    41   2846 | 
  (f1,f4)    120     98 |   396   386 |    40     41 |
  (f2,f3)      4    374 |   629   551 |  2517   2527 |
  (f2,f4)    611     37 |   630   737 | 20907   2581 |
  (f3,f4)     61    177 |   369   759 |    45     50 |
\end{verbatim}
}



\newpage
\underbar{n = 10}

{\footnotesize
\begin{verbatim}
  f1 = 
   x^10*y^10 + 2*x^10*y^8 + 3*x^10*y^3 + 4*x^9*y^7 + 2*x^9*y + 3*x^9
     + 4*x^8*y^10 + 3*x^8*y^8 + x^8*y^2 + 2*x^8 + 3*x^7*y^10
     + 3*x^6*y^7 + x^6*y^6 + 3*x^5*y^9 + x^5*y^8 + x^4*y^9 + 3*x^4*y^8
     + 4*x^4 + 4*x^3*y^2 + x^3 + 4*x^2*y^3 + x^2*y^2 + x^2*y + x^2
     + x + 3*y^6 + y^4 + y^2 + y + 1
  f2 =
    x^10*y^9 + 3*x^10*y^7 + x^9*y^8 + 3*x^9*y^6 + 2*x^8*y^3
     + 3*x^7*y^10 + x^7*y^7 + 4*x^7 + 4*x^6*y + 4*x^6 + 3*x^5
     + x^4*y^6 + 4*x^4*y^5 + 3*x^3*y^6 + 4*x^3*y^5 + 2*x^2*y^8
     + 2*x^2*y^7 + x*y^10 + 4*x*y^9 + 4*x + 4*y^10 + 2*y^8 + 3*y^3
     + 4*y^2 + 3*y
  f3 =
    x^10*y^10 + 2*x^10*y^9 + 2*x^10*y^8 + x^9*y^7 + x^9*y^5 + x^9*y^4
     + 4*x^9*y^2 + 4*x^8 + x^7*y^5 + 3*x^7*y^4 + 2*x^6*y^2 + x^6*y
     + x^6 + 3*x^5*y^3 + 3*x^5*y^2 + x^4 + 2*x^3*y^9 + x^3*y^8 + 4*x^3
     + 3*x^2*y^10 + x^2*y^2 + 3*x*y^2 + 2*x*y + 3*y^6 + 3*y^3 + 4*y^2
     + 3*y + 4
  f4 =
    x^10*y^10 + 4*x^10*y^9 + 4*x^10*y^8 + 4*x^10*y^2 + x^10*y
     + 3*x^9*y^10 + 2*x^9*y^5 + 2*x^9*y^3 + 3*x^9 + 3*x^8*y^5
     + x^8*y^4 + 3*x^8*y^3 + 4*x^7*y^5 + 2*x^7*y^4 + 2*x^6*y^3
     + 2*x^6*y^2 + x^6 + 3*x^5 + x^4*y^6 + 3*x^4*y^5 + x^3*y^4
     + 2*x^3*y^2 + x^2*y^9 + 3*x^2 + 4*x*y^10 + 4*x + 4*y^10 + 2*y^9
     + 4*y^3 + 3*y^2 + y + 1

  Timing [sec]:
  n = 10         DoCon        Axiom       MuPAD
              [x,y] [y,x] 
  (f1,f2)     313   1422 |  566   578 |   541   542 |
  (f1,f3)    1310   1397 |  585   876 |  4968   109 |
  (f1,f4)     451   1373 |  619   622 |    89    72 |
  (f2,f3)      30    105 |  537   557 |    64    72 |
  (f2,f4)    1387     16 |  590   602 |   102    62 |
  (f3,f4)      56   1370 |  620  1141 |    74    93 |
\end{verbatim}  
}





\newpage
\underbar{Summarized statistic}
{\footnotesize
\begin{verbatim}
  March 30 - April 10, 2002, Medicis Center, laudomia4, Linux

  Timing [sec]:  
  -------------     
      Average time | maximal time

  DoCon      0.9         1.2               n =  3
  Axiom      1.7         1.7
  MuPAD      2.2         2.3
  -----------------------------------------------
  DoCon     81         245                 n =  8
  Axiom    190         350
  MuPAD     56         252
  -----------------------------------------------
  DoCon    180         611                 n =  9
  Axiom    571         787
  MuPAD   2874       20907
  -----------------------------------------------
  DoCon    769        1422                 n = 10
  Axiom    658        1141
  MuPAD    566        4968
\end{verbatim}
}
\bigskip
\bigskip


\underbar{Conclusions}
\medskip

Of course, without knowing the very factoring methods in {\tt Axiom}, 
{\tt MuPAD}, these numbers do not mean much. \\
The impression is as follows. \\
The programs look equally fast on average. Because \ n = 10 \ implies 
very large intermediate computations with the polynomials of degree
20  both in  \ x \ and in  \ y.  And any essential difference in the 
order of the algorithm is likely to cause a great difference in the 
cost for such large data.
\\
{\tt Axiom} looks the most stable. \\
{\tt MuPAD} falls into a hole of 6 hours \ 
    in one of the examples for n = 9. This is somewhat suspicious.

Some details about {\tt DoCon} : \\
it applies the method by \cite{Me3} adopted from \cite{CG} 
(see also \cite{Le}),\\
whith the proved upper bound main part of \ \ 
$O( \deg_x^4 \cdot deg_y^3 )$.

The Hensel lift takes from 0.15 (for large {\tt n}) up to 
0.60 of the cost (ghc-4.08 profiling).\\
The rest is spent by finding of a small vector in certain lattice
over \ $GF(p)[x]$.

The square-freeing repeats the GCD operation in \ $GF(p)[x,y]$; \ 
it cost is made small due to applying a special Chinese-remainder 
method \ \verb#upolGCD_Chinese#. 



\subsection{ Conclusions on whole testing }
% ----------------------------------------- 
\label{sec-pe.c}  

\underbar{{\bf Algorithms and programming tools}}
\medskip

We believe, in the above examples, as everywhere in practice, the 
method details\\
({\it mathematics}) cost more than the difference in the programming 
systems --- for any reasonably designed programming tools.

Looking at the above examples, we think that {\tt Haskell} seems 
efficient enough not to loose the performance gain, when it comes
from the algorithm.

A good benchmark needs much more effort, maybe, one year of studying
{\tt Axiom}, {\tt MuPAD} programming and designing examples.
\bigskip

\underbar{{\bf Algorithm quality}}
%
\begin{itemize}
\setlength\itemsep{0pt}
\item Polynomial arithmetic (\verb#+, *, ^#) 
  \\
  looks almost as fast in {\tt DoCon}  as in {\tt Axiom}, {\tt MuPAD}
  --- for not very large data.\\
  Asymptotically, {\tt DoCon}  looses a little to {\tt Axiom} and 
  looses considerably to {\tt MuPAD}. Probably, this is due to 
  insufficient optimization in algorithm.

\item On half of the Gr\"obner basis tasks, \ {\tt DoCon}  looses 
      greatly in performance to {\tt MuPAD}. \ No doubt, this is
  due to the insufficient optimization in the algorithm applied in 
  {\tt DoCon}. 

\item In the example serie for multivariate polynomial GCD,\\
      and for factoring in \ $GF(p)[x]$ \\
      (and maybe, some implied linear algebra),\\
      {\tt DoCon}  wins a little relatively to {\tt Axiom} \\
      and wins considerably relatively to {\tt MuPAD}.

\item In factoring in $GF(p)[x,y]$, \\
  the programs {\tt Axiom, DoCon, MuPAD} show approximately equal 
  performance, even for the large degrees. \\
  But {\tt MuPAD} falls strangely into a 6 hours `hole' on one of 
  the suggested examples. 
\end{itemize}
\bigskip

\underbar{{\bf Remark on linear systems}}
\medskip

In factoring in $GF(p)[x]$, \ {\tt DoCon}  relies on the large dense 
linear system solution over $Z/(p)$, \ and \ $GF(p)[x,y]$ \ 
relies on the large {\it sparse} linear system solution over \
$Z/(p)$. \ 
In both cases {\tt DoCon}  represents a matrix as a list of rows, a row 
--- as a list of matrix entities or as a list of indexed entities.
{\tt DoCon}  avoids arrays.









\newpage
\section{ Literature references }
% -------------------------------

\begin{thebibliography}{MoM}
%
\bibitem[Al]{Al} S.~M.~Watt et al. \ {\it Aldor Compiler User Guide.}
\\
IBM Thomas J. Watson Research Center. \verb#<http://www.aldor.org>#

\bibitem[Au]{Au} L.~Augustsson. \
{\it Cayenne --- a language with dependent types}. \\
In Proceedings of International Conference on Functional Programming 
(ICFP'98). ACM Press, September 1998.

\bibitem[Bu]{Bu} B.~Buchberger. \\ 
{\it Gr\"obner Bases: An Algorithmic Method in Polynomial Ideal Theory.
} \\ 
CAMP. Publ. No.83--29.0 November 1983

\bibitem[BL]{BL} B.~Buchberger, R.~Loos. \ 
{\it Algebraic Simplification.} \\
In ``Computer Algebra. Symbolic and Algebraic Computation'', \\
edited by B.Buchberger et al., Springer Verlag, 1982,1983

\bibitem[CG]{CG} A.~L.~Chistov, D.~Yu.~Grigoryev. \\
{\it Polynomial-time factoring of the multivariable polynomials over 
a global field.} \\
Preprint E-5-82 of the Leningrad department of Steklov
Mathematical Institute LOMI, USSR, 1982. \\
There also exists the LOMI preprint in Russian of 1984 containing 
the same algorithm description.

\bibitem[Da]{Da} J.~H.~Davenport, B.~M.~Trager. \\
{\it Scratchpad's View of Algebra I: Basic Commutative Algebra}. \\
Lecture Notes in Computer Science, Vol.~429, pp.40--54 (1990).

\bibitem[Ed]{Ed} H.~M.~Edwards. \\
{\it Fermat's last theorem. A genetic introduction to algebraic number 
theory.} \ 
Springer-Verlag, 1977

\bibitem[FH]{FH} A.~J.~Field, P.~G.~Harrison \ 
{\it Functional programming}. \\
Addison-Wesley, 1988.

\bibitem[Fo]{Fo} J.~Fokker. \ 
{\it Explaining algebraic theory with functional programs}. \\
Proceedings of FPLE'95, LNCS 1022, pp. 139-158. \\ 
\verb#<http://www.cs.ruu.nl/people/jeroen>#

\bibitem[GH]{GH} {\it Glasgow Haskell Compiler.} \ 
\verb#<http://www.haskell.org/ghc>#.

\bibitem[GM]{GM} R.~Gebauer, H.~M.~Moeller. \ 
{\it On Installation of Buchberger's Algorithm.} \\
Journal of Symbolic Computation (1988), Vol. 6.

\bibitem[GTZ]{GTZ} P.~Gianni, B.~Trager, G.~Zacharias. \\
{\it Gr\"obner Bases and Primary Decomposition of Polynomial Ideals.}
\\
Journal of Symbolic Computation (1988), Vol.6, pp.149-167

\bibitem[Ha]{Ha}
{\it Haskell 98: A Non-strict, Purely Functional Language}. \\
Report of February 1999. \ \verb#<http://www.haskell.org>#

\bibitem[HJ]{HJ} R.~Hinze, S.~P.~Jones. \ 
{\it Derivable type classes.} \\
In Proceedings of the Haskell Workshop, Montreal, 2000. \\
\verb#<http://www.dcs.gla.ac.uk/~simonpj>#

\bibitem[HFP]{HFP} P.~Hudak, J.~Fasel, J.~Peterson. \ 
{\it A gentle introduction to Haskell}. \\
Technical report, YALEU/DCS/RR-901, Yale University. 1996. \\
\verb#<http://haskell.org/tutorial>#

\bibitem[Je]{Je} R.~D.~Jenks, R.~S.~Sutor, et al. \\
{\it Axiom, the Scientific Computation System}. \\
Springer-Verlag, New York--Heidelberg--Berlin (1992).

\bibitem[JJM]{JJM} S.~P.~Jones, M.~Jones, E.~Meijer. \\
{\it Type classes: an exploration of the design space}. \\
1997. \ 
In Proceedings of the Haskell Workshop. \\
\verb#<http://www.dcs.gla.ac.uk/~simonpj/>#

\bibitem[Jo]{Jo} S.~L.~P.~Jones et al. \\
{\it Implementation of Functional Programming Languages.} \\
Prentice Hall. 1987.

\bibitem[Ka]{Ka} J.~Karczmarczuk. \\
{\it Functional Programming and Mathematical Objects}. \\
Proceedings of FPLE'95, Nijmegen 1995; Springer LNCS 1022.

\bibitem[Kn]{Kn}  D.~E.~Knuth. \ 
{\it The Art of Computer Programming.} Volums 1,2,3. \\
Addison-Wesley, 1973

\bibitem[La]{La} S.~Lang. \ {\it Algebra.} \ Addison-Wesley, 1965.

\bibitem[Le]{Le} A.~K.~Lenstra. \\ 
{\it Factoring Multivariate Polynomials over Finite Fields}. \\
Journal of Computer and System Sciences, Volum 30 (1985), pp.235-248.

\bibitem[LLL]{LLL} A.~K.~Lenstra, H.~W.~Jr.~Lenstra, L.~Lovasz. \\
{\it Factoring polynomials with rational coefficients}. \\
Math. Ann. Volum 261 (1982), pp.515-534.

\bibitem[Ma]{Ma} I.~G.~Macdonald. \ 
{\it Symmetric Functions and Hall Polynomials.} \\
Clarendon Press, Oxford, 1979.

\bibitem[Md]{Md} M.~Clavel \& al. \\
{\it Maude: Specification and Programming in Rewriting Logic.} \\
\verb#<http://maude.csl.sri.com>#  

\bibitem[Me1]{Me1} S.~D.~Meshveliani. \\
{\it The Algebraic Constructor CAC: Computing in Construction-defined 
Domains.} \\
Lecture Notes in Computer Science, 722, 1993.

\bibitem[Me2]{Me2} S.~D.~Mechveliani. \ 
{\it BAL basic algebra library for Haskell.} \\ 
Paper manuscript (\verb#haskellInCA*#) and BAL program source.
Pereslavl-Zalessky, 2000-2001. \ 
\verb#<http://www.botik.ru/pub/local/Mechveliani/basAlgPropos/>#

\bibitem[Me3]{Me3} S.~D.~Mechveliani. \\ 
{\it Cost bound for LLL-Grigoryev method for factoring in GF(q)[x,y].
} \\ 
To appear (in Russian) in Fundamental and Applied Mathematics,
Math.dep. of Moscow State University 
\verb#<http://www.math.msu.su/~fmp/>#. \\
The file with English version will be available as \\
\verb#<http://www.botik.ru/pub/local/Mechveliani/otherPapers/ovfEng*>#

\bibitem[Me4]{Me4} S.~D.~Mechveliani. \\ 
{\it Computer algebra with Haskell:
  applying functional-categorial-`lazy' programming
}. \\ 
In Proceedings of International Workshop CAAP-2001,
Dubna, Russia. 

\bibitem[Mi]{Mi} M.~Mignotte. \ 
{\it Math\'{e}matiques pour le caclul formel}. \\
Presses Universitaires de France, 1989. \\ 
English translation: {\it Mathematics for computer algebra}. \\
Springer Verlag, 1992.

\bibitem[Mo]{Mo} H.~M.~M{\oe}ller. \ 
{\it On the Construction of Gr\"obner Bases Using Syzygies.} \\
Journal of Symbolic Computation (1988), Vol. 6.

\bibitem[MoM]{MoM} H.~M.~M{\oe}ller, F.~Mora. \\
{\it New Constructive Methods in Classical Ideal Theory.} \\
Journal of Algebra, v 100, pp.138-178 (1986)

\bibitem[Mu]{Mu} {\it MuPAD the Multi Processing Algebra Data Tool}
\\
\verb#<http://www.mupad.de>#, \ 
\verb#<ftp.mupad.de>#, \\ 
\verb#<http://math-www.uni-paderborn.de/MuPAD/>#

\bibitem[Zi]{Zi} R.~Zippel. \ 
{\it The Weyl Computer Algebra Substrate.} \\
Lecture Notes in Computer Science, vol.722, pp.303-318 (1993)
%
\end{thebibliography}










\newpage
\section{ Cross reference and help }
% ----------------------------------
\label{sec-cross}  


The {\it items} are listed below in alphabetical order. \\
Usually, an item is provided with \ \ 
reference, \ type description, \ short commentary.
\bigskip
\bigskip
\\ 
% 
%
%
{\tt absValue} \ \ \ref{sec-grp.fn} \ \ \ {\tt :: AddGroup a => a -> a} 

  absolute value. Correct for {\tt (IsOrderedGroup, Yes)}
\medskip
\\
{\tt add} \ \ \ref{sec-smg.a} \ \ \ 
              addition operation of \ {\tt AddSemigroup} \ category
\medskip
\\
{\tt addEPermut} \ \ \ref{sec-pm.d} \ \ \  
                                    {\tt :: EPermut -> EPermut -> EPermut}

\verb#        # composes e-permutations on disjoint sets
\medskip
\\
\verb#addListToAssocList_C# \ \ \ref{sec-dprel} \ \ \ 
                                         repeated \ \verb#addToAssocList_C#
 
\verb#        # {\tt :: Eq a => (b -> b -> b) -> [(a,b)] -> [(a,b)] -> [(a,b)]}
\medskip
\\
{\tt AddGroup} \ \ \ref{sec-grp.ct} \ \ \ 
                                        category of additive commutative groups

\verb#     #  {\tt class AddMonoid a => AddGroup a where}

\verb#         # 
           {\tt baseAddGroup :: a -> Domains1 a -> (Domains1 a, Subgroup a)}
\medskip
\\
{\tt AddMonoid} \ \ \ref{sec-mnd} \ \ \ 
                                   {\tt class AddSemigroup a => AddMonoid a} 

\verb#        # category of additive monoid \ ({\tt zeroS x} \ \ gives zero)
\medskip
\\
{\tt AddSemigroup} \ \ \ref{sec-smg.a} \ \ \ a category
 
\verb#   # {\tt class Set a => AddSemigroup a where}
 
\verb#       baseAddSemigroup...add...zero_m...neg_m...sub_m...times_m#
\medskip
\\
\verb#ToAssocList_C# \ \ \ref{sec-dprel}

  \verb#addToAssocList_C :: Eq a => (b->b->b) -> [(a,b)] -> a -> b -> [(a,b)]#

\verb#        # combines with the previous binding
\medskip
\\
{\tt addUnknowns} \ \ \ref{sec-dprel} \ \ \ 
  {\tt :: Eq a => [(a,PropValue)] -> [a] -> [(a,PropValue)]}

\verb#   # 
     adds {\tt (nm, Unknown)} for any {\tt nm} skipped in association list  
\medskip
\\
{\tt addVarsPol} \ \ \ref{sec-pol.f}, \ref{sec-pol.f} 

\verb#      # {\tt :: Char -> PPOrdTerm -> [PolVar] -> Pol a -> Pol a}
 
 $ a[x_1,\ldots,x_n] \rightarrow \ a[y_1,\ldots,y_m,x_1,\ldots,x_n] $
  \ or to \ $a[x_1,\ldots,x_n,y_1,\ldots,y_m]$
\medskip
\\
{\tt ADomDom} \ \ \ref{sec-up} \ \ \
                        {\tt type ADomDom a = a -> Domains1 a -> Domains1 a}
\medskip
\\
{\tt algRelsPols}  \ \ (\ref{sec-pol.a.gr} \{ar\})

\verb#    #   {\tt :: EuclideanRing k =>}

\verb#            [Pol k] -> [PolVar] -> PPOrdTerm -> [Pol k] -> [Pol k]#
%%
\\
{\tt AlgSymmF} \ \ \ref{sec-dme}, \ref{sec-symmf} \ \ \ 
                     {\tt DoCon} module exporting items for Symmetric functions
\medskip
\\                       
{\tt allMaybes} \ \ \ref{sec-dprel} \ \ \ {\tt :: [Maybe a] -> Maybe [a]}
\medskip
\\                       
{\tt allMaybesVec}  \ \ \ref{sec-vec.f} 

\verb#        # {\tt (fmap Vec . allMaybes) :: [Maybe a] -> Maybe (Vector a)}
\medskip
\\                       
{\tt allPermuts} \ \ \ref{sec-pm.d} \ \ {\tt :: [Integer] -> [Permutation]}

\verb#        # build the full permutation list (in any order) 

\verb#        # given a list ordered {\emph decreasingly}
\medskip
\\                       
{\tt alteredSum}  \ \ \ref{sec-dprel} \ \ \ {\tt :: Num a => [a] -> a}

\verb#      # 
     $ [x_1,\ldots,x_n] \longrightarrow\ \sum_{i = 1}^n (-1)^{i-1} x_i $ \ \ 
     --- for non-empty list
\medskip
\\                       
{\tt and3} \ \ \ref{sec-dprel} \ \ \ 
                             {\tt :: PropValue -> PropValue -> PropValue}
\medskip
\\                       
{\tt antiComp} \ \ \ref{sec-dprel} \ \ \ {\tt :: CompValue -> CompValue}

\verb#                       # {\tt LT -> GT;  GT -> LT;  EQ -> EQ}
\medskip
\\                       
{\tt applyPermut} \ \ \ref{sec-pm.d} \ \ \ {\tt :: Ord a => [Z] -> [a] -> [a]}

\verb#               \ks -> map snd . sortBy (compBy fst) . zip ks #

\verb#              # example: \ {\tt [2,3,4,1] "abbc" --> "cabb"}
\medskip
\\                       
{\tt applyTransp} \ \ \ref{sec-pm.d} \ \ \ {\tt :: (Z, Z) -> [a] -> [a]}

\verb#        # Transpose elements No $i$, $j$, \ \ 
                $1 \leq i \leq j \leq $ {\tt length xs}
\medskip
\\                       
{\tt applyTranspSeq} \ \ \ref{sec-pm.d} \ \ 

\verb#        # {\tt :: (Ord a, Show a) => (a,a) -> [(a,b)] -> [(a,b)]}

\verb#    # 
     Transpose entities indexed by \ $i \leq j$ \ in a sequence of pairs \ldots
\medskip
\\                       
{\tt baseAddGroup} \ \ \ref{sec-grp.ct} \ \ 
                        operation from {\tt AddGroup} category

\verb#            # {\tt :: a -> Domains1 a -> (Domains1 a,Subgroup a)}
\medskip
\\                       
{\tt baseAddSemigroup} \ \ \ref{sec-smg.a}, (~\ref{sec-prp.ske} BO) 

\verb#          # {\tt :: a -> Domains1 a -> (Domains1 a, Subsemigroup a)}

\verb#          # operation from {\tt AddSemigroup} category
\medskip
\\                       
{\tt baseEucRing} \ \ \ref{sec-euc} \ \ operation from {\tt EuclideanRing}

\verb#          # {\tt :: a -> Domains1 a -> (Domains1 a, EucRingTerm a)}
\medskip
\\                       
{\tt baseFactrRing} \ \ \ref{sec-ftr} \ \ 
                              operation from {\tt FactorizationRing}

\verb#          # {\tt :: a -> Domains1 a -> (Domains1 a, FactrRingTerm a)}
\medskip
\\                       
{\tt baseGCDRing} \ \ \ref{sec-gcd} \ \ operation from {\tt GCDRing} category

\verb#          # 
         {\tt baseGCDRing :: a -> Domains1 a -> (Domains1 a, GCDRingTerm a)}
\medskip
\\                       
{\tt baseLinSolvLModule} \ \ \ref{sec-mod.ls}, ~\ref{sec-mod.lsm} 

\verb#     #  
      {\tt :: (r,a) -> Domains2 r a -> (Domains2 r a, LinSolvModuleTerm r a)}
     
\verb#     # operation from \ {\tt LinSolvLModule r a} \ category
\medskip
\\                       
{\tt baseLinSolvRing} \ \ \ref{sec-linr} \ \ 
                             operation from {\tt LinSolvRing} category

\verb#          # {\tt :: a -> Domains1 a -> (Domains1 a, LinSolvRingTerm a)}
\medskip
\\
{\tt baseMulSemigroup} \ \ \ref{sec-smg.m}, (~\ref{sec-prp.ske} BO) \ \ 
                        operation from {\tt MulSemigroup} category

\verb#           # {\tt :: a -> Domains1 a -> (Domains1 a, Subsemigroup a)}
\medskip
\\                       
{\tt baseRing} \ \ \ref{sec-rg}, (\ref{sec-prp.ske} BO) \ \ 
                                operation from {\tt Ring} category

\verb#              # {\tt :: a -> Domains1 a -> (Domains1 a, Subring a)}
\medskip
\\                       
{\tt baseSet} \ \ \ref{sec-set.ct}, (\ref{sec-prp.ske} DS) \ \ 
              operation from {\tt Set} category

\verb#              # {\tt :: a -> Domains1 a -> (Domains1 a, OSet a)} 
        
\verb#              # description of subset related to sample element
\medskip
\\                       
{base-operation} \ \ (\ref{sec-prp.ske} BO) \ \ --- 
                        such as \ {\tt baseSet, baseAddGroup}, \ldots
\medskip
\\                       
{\tt binomCoefs} \ \ \ref{sec-dprel} \ \ \ {\tt :: Z -> [Z]}

\verb#     # binomial coefficients: \ 
             $ n \rightarrow [C(n,k),\ldots,C(n,0)], \ \ k \leq n/2 + 1 $
\medskip
\\                       
{\tt boolToPropV} \ \ \ref{sec-dprel} \ \ \
               \verb#(\b -> if b then Yes else No)  :: Bool -> PropValue}#
\medskip
\\                       
{\tt bundle} \ \ (\ref{sec-prp.ske} MD) \ \ (domain, many-domain) 

\verb#        # a finite collection of domain terms stored each under its Key, 

\verb#        # Key = {\tt CategoryName = Set | AddGroup| Ring | } \ldots
\medskip
\\                       
{\tt canAssoc} \ \ \ref{sec-gcd} \ \ \ {\tt :: a -> a}

\verb#      # 
            operation from {\tt GCDRing} category: canonical associated element
\medskip
\\                       
{\tt canAssocM} \ \ \ref{sec-mod.ls}, \ref{sec-mod.lsm} \ \ \ 
                                            {\tt :: r -> a -> a}

\verb#       # Operation from \ {\tt LinSolvLModule r a} \ category: canonical 

\verb#       # 
         associated vector in \ {\tt a}. First argument is a sample for {\tt r}
\medskip
\\                       
{\tt canFr} \ \ \ref{sec-fr.i} \ \ bring to canonical fraction
 
\verb#           # {\tt :: GCDRing a => String -> a -> a -> Fraction a}
           
\verb#     # {\tt mode = "g"} \ means to cancel by gcd, \ \ "i", "" mean \ldots
\medskip
\\                       
{\tt canInv} \ \ \ref{sec-gcd} \ \ \ {\tt :: a -> a} 

\verb#           # 
             operation from {\tt GCDRing} category: canonical invertible factor
\medskip
\\                       
{\tt canInvM} \ \ \ref{sec-mod.ls}, \ref{sec-mod.lsm} \ \ \
             {\tt :: r -> a -> r}

\verb#             # Operation from \ {\tt LinSolvLModule r a} \ category:

\verb#             # canonical invertible factor for the vector from \ {\tt a}
\medskip
\\                       
{\tt Cast} \ \ (\ref{sec-prp.ske} CT), \ref{sec-dprel}

\verb#        # 
               category for mapping from domain of {\tt b} to domain of {\tt a}

\verb#        #   {\tt class Cast a b where  cast :: Char -> a -> b -> a}
\medskip
\\                       
{\tt category} \ \ (\ref{sec-prp.ske} CT, IN), \ref{sec-prp.hr}, \ \ \ 
           notion 'domain'.

\verb#            # In DoCon, it is a class of domains defined by {\tt Haskell}

\verb#            # class declarations, presumed conditions and sample element
\medskip
\\                       
{CategoryName} \ \ \ref{sec-dd.b} \ \ \ {\tt data CategoryName = }


\verb#    # 
      {\tt Set | AddSemigroup | AddGroup | MulSemigroup | MulGroup | Ring | }

\verb#    #  
      {\tt LinSolvRing | GCDRing  | FactorizationRing | EuclideanRing |} \ldots
\medskip
\\                       
{\tt Categs} \ \ \ref{sec-dme} \ \ 
                 {\tt DoCon} module exporting various {\tt Domain} data descriptions
\medskip
\\                       
{\tt char} \ \ \ref{sec-rg.fn} \ \ \ {\tt :: Ring a => a -> Maybe Z}

\verb#              #  haracteristic of a ring defined by given sample
\medskip
\\                       
{\tt Char} \ \ \ref{sec-ch} \ \ \ Haskell type and Domain in DoCon.

\verb#             # {\tt DoCon} supplies it with the {\tt OrderedSet} instance
\medskip
\\                       
{\tt coefsToPol} \ \ \ref{sec-pol.f} \ \ \ coefficient list to polynomial

\verb#         # {\tt :: Ring a => Char -> Pol a -> [Z] -> [a] -> (Pol a, [a])}

\verb#         # polynomial domain is given by sample
\medskip
\\                       
{\tt CommutativeRing} \ \ \ref{sec-gcd} \ \ \ a category   

\verb#              # {\tt class Ring a => CommutativeRing a}
     
\verb#              # presumed: {\tt (Commutative, Yes)}
\medskip
\\                       
\verb#compare_m# \ \ \ref{sec-set} \ \ \ {\tt :: a -> a -> Maybe CompValue}

\verb#   # operation from {\tt Set} category for partial ordering 

\verb#   # on the base set. Its simplest definition is \ {\tt compareTrivially}
\medskip
\\                       
{\tt compBy} \ \ \ref{sec-dprel} \ \ \ 
               {\tt :: Ord b => (a -> b) -> Comparison a}

\verb#                 \f x y -> compare (f x) (f y)#
\medskip
\\                        
{\tt Comparison} \ \ \ref{sec-dprel} \ \ \
                         {\tt type Comparison a = a -> a -> CompValue}
\medskip
\\                       
{\tt CompValue} \ \ \ref{sec-dprel} \ \ \ {\tt type CompValue = Ordering}

\verb#       # 
             a name {\tt DoCon} uses for Haskell's \ {\tt Ordering \ (LT | EQ | GT)} 
\medskip
\\                       
{\tt conjPrtt} \ \ \ref{sec-symmf.p.p} \ \ \ 
                   {\tt :: Partition -> Partition} \ \ \ conjugated partition
\medskip
\\                       
{\tt constMatr} \ \ \ref{sec-mt.f} \ \ \ {\tt :: Matrix a -> a -> Matrix a}

\verb#              # replaces all entities in a matrix with a given value
\medskip
\\                       
\verb#Construction_Ideal# \ \ \ref{sec-il.g} 

\verb#      newtype Construction_Ideal a = GenFactorizations [Factorization a]#
\medskip
\\                       
{\tt constructor} \ \ (\ref{sec-prp.ske} DS) \ \ {\tt DoCon} uses the data type

  constructors ({\tt Pol, Fraction, ResidueE \ldots}) to build domains

  from other domains. And {\it instances} are defined for constructors.
\medskip
\\                       
{\tt constSqMatr} \ \ \ref{sec-mt.f} \ \ \
                         {\tt :: SquareMatrix a -> a -> SquareMatrix a}

\verb#                      # analog for \ {\tt constMatr} 
\medskip
\\
{\tt constVec} \ \ \ref{sec-vec} \ \ \ {\tt :: Vector a -> b -> Vector b}

\verb#       # Constant vector. Example: \ {\tt (Vec [1,2,3]) 'c' -> Vec "ccc"}
\medskip
\\                       
{\tt cPMul} \ \ \ref{sec-pl} \ \ 
                       product of a polynomial class thing by coefficient 

\verb#   (\a-> pMapCoef 'r' (mul a)) :: (PolLike p, Ring a) => a -> p a -> p a#
\medskip
\\                       
{\tt ct} \ \ see \ {\tt class Cast} \ in~\ref{sec-dprel}, 
             (\ref{sec-prp.ske} CS), \ref{sec-prp.skco.cs}

\verb#                   (cast '_')  :: Cast a b => a -> b -> a #
\medskip
\\                       
{\tt cToEMon} \ \ \ref{sec-polv.e.i} \ \ \ {\tt :: [a] -> Z -> b -> EMon b}

\verb#      # 
      makes e-monomial from coefficient, position No and number of variables
\medskip
\\                       
{\tt cToEPol} \ \ \ref{sec-polv.e.i} \ \ \ coefficient to e-polynomial 

\verb#              # {\tt AddGroup a =>  EPol a -> Z -> a -> EPol a}

\verb#              # parameters taken from e-polynomial sample
\medskip
\\                       
{\tt cToPol} \ \ \ref{sec-pol.f} \ \ \ coefficient to polynomial
 
\verb#   # {\tt :: Ring a => PPOrdTerm -> [PolVar] -> Domains1 a -> a -> Pol a}

\verb#   # a natural way to produce some polynomial
\medskip
\\                       
{\tt cToRPol} \ \ \ref{sec-rpol.d} \ \ \ coefficient to r-polynomial

\verb#              # {\tt :: RPolVarsTerm -> Domains1 a -> a -> RPol a}

\verb#              # usable way to initiate some r-polynomial
\medskip
\\                       
{\tt cToSymMon} \ \ \ref{sec-symmf.sp.i} \ \ \
                                        \verb#(\c-> (c, [])) :: a -> SymMon a#

\verb#              # for {\tt c} $\neq 0$, \ this yields sym-monomial
\medskip
\\                       
{\tt cToSymPol} \ \ \ref{sec-symmf.sp.i} \ \ \ similar to {\tt cToPol}

\verb#         # {\tt :: AddGroup a => PrttComp -> Domains1 a -> a -> SymPol a}
\medskip
\\                       
{\tt cToUPol} \ \ \ref{sec-upo.i} \ \ coefficient to univariate polynomial

\verb#              # {\tt :: Ring a => PolVar -> Domains1 a -> a -> UPol a}
             
\verb#              # apply it to produce some univariate polynomial
\medskip
\\                         
{\tt ctr} \ see \ {\tt class Cast} \ in~ref{sec-dprel}, 
          (\ref{sec-prp.ske} CS), \ref{sec-prp.skco.cs} 

\verb#              # {\tt (cast 'r') \ :: Cast a b => a -> b -> a}
\medskip
\\                       
\verb#cubeList_lex# \ \ \ref{sec-dprel} \ \ 
             lists in lex-increasing order all vectors $[a_1,\ldots,a_n]$ 

\verb#              # over \ {\tt a} \ in the cube defined by bounds:
 
\verb#              # {\tt :: (Shows a, Ord a, Enum a) => [(a,a)] -> [[a]]}
\medskip
\\                       
{\tt deg} \ \ \ref{sec-pl} \ \ \ {\tt :: CommutativeRing a => p a -> Z}

            Total degree. Operation from constructor class {\tt PolLike}
\medskip
\\                       
{\tt deg0} \ \ \ref{sec-pl} \ \ \ 
      {\tt deg} generalized to ``if zero, return given value''

\verb#        # {\tt :: (PolLike p, AddSemigroup (p a), CommutativeRing a) =>}

\verb#        # {\tt Char -> Z -> p a -> Z}
\medskip
\\                       
{\tt degInVar} \ \ \ref{sec-pl} \ \ 
               operation from constructor class {\tt PolLike}

\verb#              # {\tt :: CommutativeRing a => Z -> Z -> p a -> Z}

\verb#              # $\deg f$ \ in variable No i, \ {\tt for0} \ for zero $f$
\medskip
\\
{\tt degLex} \ \ \ref{sec-pp.d} \ \ \ {\tt :: PPComp} \ \
                                    degree-lexicographic pp comparison 
\medskip
\\                       
{\tt degRevLex} \ \ \ref{sec-pp.d} \ \ \ {\tt :: PPComp}

\verb#           # pp comparison: first by total deg, then, by {\tt lexFromEnd}
\medskip
\\                       
{\tt delBy} \ \ \ref{sec-dprel} \ \ \ {\tt :: (a -> Bool) -> [a] -> [a]}

\verb#              # deletes first element satisfying given predicate
\medskip
\\                       
\verb#del_n_th# \ \ \ref{sec-dprel} \ \ \ {\tt :: Z -> [a] -> [a]} \ \ 
                removes element No n from list
\medskip
\\                       
{\tt denom} \ \ \ref{sec-fr.i} \ \ \ 
                         \verb#(_ :/ d) -> d# \ \ \ denominator of fraction 
\medskip
\\                       
{\tt det} \ \ \ref{sec-lin.d} \ \ \ {\tt CommutativeRing a => [[a]] -> a}

\verb#              # Determinant of matrix via expansion by row

\verb#              # (Gauss method is applied in \verb#det_euc#)
\medskip
\\                       
\verb#det_euc# \ \ \ref{sec-lin.d} \ \ \ {\tt EuclideanRing a => [[a]] -> a}

\verb#     # Determinant over Euclidean ring. Gauss reduction to staircase form

\verb#     # via repeated remainder division.
\medskip
\\                       
\verb#det_upol_finField# \ \ \ref{sec-upo.a.d} \ \ \ 
                             $\det M$ \ over $k[x]$, \ $k$ \ a finite field

\verb#        # {\tt :: Field k => [ResidueE (UPol k)] -> [[UPol k]] -> UPol k}

\verb#        # Highly efficient method using interpolation.
\medskip
\\                       
{\tt DExport} \ \ \ref{sec-dme} \ \ {\tt DoCon} module reexporting all

      open {\tt DoCon} items and many of GHC. See also~\ref{sec-start.1}
\medskip
\\                       
{\tt diagMatrKernel} \ \ \ref{sec-lin.sl} \ \ \ 
                                     {\tt :: Ring a => [[a]] -> [[a]]}

\verb#        # Kernel basis for a diagonal matrix having no zeroes on diagonal
\medskip
\\                       
{\tt dimOverPrime} \ \ \ref{sec-rg.sub} \ \ \ 
                   {\tt :: InfUnn Z} \ \ \ dimension over a prime field.

\verb#    # Part of \ {\tt WithPrimeField} \ term of \ \verb#Opeartion_Subring#
\medskip
\\                       
{\tt dimOverPrimeField} \ \ \ref{sec-rg.fn} \ \ \ 
                                       {\tt :: Subring a -> InfUnn Z}

\verb#          # examples: \ \ {\tt Z, Z[x] --> UnknownV, \ Z/(3) --> Fin 1}, 

\verb#          # {\tt (Z/(3))[x] --> Infinity}
\medskip
\\                       
\verb#directProduct_group# \ \ \ref{sec-pair.d} 
 
\verb#        # {\tt (Set a, Set b) =>}

{\tt a -> OSet a -> Subgroup a -> b -> OSet b -> Subgroup b -> Subgroup (a,b)}
\medskip
\\                       
\verb#directProduct_ring# \ \ \ref{sec-pair.d} 

  {\tt :: (Ring a, Ring b) => a -> Subring a -> b -> Subring b -> Subring (a,b)
  }

\verb#         # {\tt zA, zB}\ are the zeroes of rings \ {\tt A, B}
\medskip
\\                       
\verb#directProduct_semigroup# \ \ \ref{sec-pair.d}

\verb#        # {\tt :: Subsemigroup a -> Subsemigroup b -> Subsemigroup (a,b)}
\medskip
\\                       
\verb#directProduct_set# \ \ \ref{sec-pair.d} \ \ \
                                 {\tt :: OSet a -> OSet b -> OSet (a,b)}
\medskip
\\                       
{\tt divide} \ \ \ref{sec-smg.m} \ \ \ {\tt :: MulSemigroup a => a -> a -> a}

\verb#      # polymorphic division (composed \verb#divide_m# and \ {\tt error})
\medskip
\\                       
{\tt divides} \ \ \ref{sec-smg.m} \ \ \ 
                                 {\tt :: MulSemigroup a => a -> a -> Bool}

\verb#                     \x y -> isJust $ divide_m y x#
\medskip
\\                      
\verb#divide_m# \ \ \ref{sec-smg.m} \ \ \ \verb#:: a -> a -> Maybe a#

\verb#            # left-quotient operation of {\tt MulSemigroup} category:

\verb#            # solving of \ \verb#x*a = b# \ for {\tt x}.
\medskip
\\
\verb#divide_m2# \ \ \ref{sec-smg.m} \ \ \ 
                     \verb#:: a -> a -> (Maybe a, Maybe a, Maybe (a,a))#

\verb#              # division operation of {\tt MulSemigroup} category:

\verb#              # left, right, and bi-sided quotient.
\medskip
\\                       
{\tt divRem} \ \ \ref{sec-euc} \ \ \ {\tt :: Char -> a -> a -> (a, a)}

\verb#  # operation of EuclideanRing category: \ 
                              {\tt mode x y -> (quotient, remainder)}  
\medskip
\\                       
{\tt DivRemCan} \ \ \ref{sec-euc} \ \ \ \verb#:: Property_EucRing#

\verb#      # 
     {\tt (DivRemCan,Yes)} means correctness of {\tt 'c'} mode in {\tt divRem} 
\medskip
\\                       
{\tt DivRemMin} \ \ \ref{sec-euc} \ \ \verb#:: Property_EucRing# 
 
\verb#     # 
      {\tt (DivRemMin,Yes)} means correctness of {\tt 'm'} mode in {\tt divRem} 
\medskip
\\                       
{\tt dom} \ \ \ref{sec-dd.dm} \ \ \ {\tt dom :: c a -> Domains1 a}

\verb#              # operation from constructor class {\tt Dom}:

\verb#              # Example: for \ {\tt f} from {\tt Z[x], \ dom f = dZ}
\medskip
\\
{\tt docon.conf} \ \ \ref{sec-start.1} \ \ docon package configuration
\medskip
\\                       
{\tt Dom} \ \ \ref{sec-dd.dm}, (\ref{sec-prp.ske} CS, DE)

\verb#      class Dom c where {dom :: c a -> Domains1 a;  sample :: c a -> a}#

\verb#  # Example: \ for \ \verb#f = UPol _ 0 _ dZ,   dom f = dZ, sample f = 0#
\medskip
\\                       
{\tt domain}  \ \ (\ref{sec-prp.ske} D, DT) \ \ \ algebraic domain 

\verb#        # (belongs to some {\it categories}), a concrete {\tt Set} or 
  
\verb#        # 
          {\tt Group, Ring}, etc. It is defined mostly as class instance \ldots
\medskip
\\                       
{\tt Domain1} \ \ \ref{sec-dd.b}, (\ref{sec-prp.ske} MD)

\verb#       # {\tt data Domain1 a = D1Set !(OSet a) | D1Smg !(Subsemigroup a)}

\verb#                            # {\tt | D1Group !(Subgroup a) | } \ldots
\medskip
\\                       
{\tt Domain2} \ \ \ref{sec-dd.b}, (\ref{sec-prp.ske} MD)

\verb#            # {\tt data Domain2 a b = D2Module !(Submodule a b) |}

\verb#                           # {\tt D2LinSolvM !(LinSolvModuleTerm a b)}
\medskip
\\                       
{\tt Domains1} \ \ \ref{sec-dd.b}, (\ref{sec-prp.ske} MD)

\verb#           # {\tt type Domains1 a = Map.Map CategoryName (Domain1 a)}

\verb#           # represents a domain (a bundle) with one parameter \ {\tt a}
\medskip
\\                       
{\tt Domains2} \ \ \ref{sec-dd.b}, (\ref{sec-prp.ske} MD)

\verb#         # {\tt type Domains2 a b = Map.Map CategoryName (Domain2 a b)}

\verb#         # represents domain (bundle) with two parameters \ {\tt a, b}
\medskip
\\                       
{\tt DPair} \ \ (see \ref{sec-dme}, \ {\tt pair}) \ \  
                 {\tt DoCon} module exporting items for constructor {\tt (,)}
\medskip
\\                       
{\tt DPrelude} \ \ see \ref{sec-dme}, \ref{sec-dprel} \ \ \
               module exporting the {\tt DoCon} Prelude
\medskip
\\                       
{\tt dropAsMuch} \ \ \ref{sec-dprel} \ \ \ {\tt :: [a] -> [b] -> [b]}

\verb#        #  {\tt dropAsMuch xs ys ==  \ drop |xs| ys}, \ \ 
                 only it is better implemented.
\medskip
\\
{\tt dZ} \ \ \ref{sec-z.b} \ \ \ 
                         \verb#dZ = upEucFactrRing _ Map.empty  :: Domains1 Z#

\verb#   # 
        It contains all known domain terms for {\tt Z}. \ See also \ref{sec-up}
\medskip
\\                       
\verb#ecpPOT_weights# \ \ \ref{sec-polv.e.i} \ \ \ 
                                 similar to \verb# ecpTOP_weights#,

\verb#              # {\tt :: Bool -> [PowerProduct] -> PPComp -> EPPComp}

\verb#              # only the positions are compared first
\medskip
\\                       
\verb#ecpTOP_weights# \ \ \ref{sec-polv.e.i} \ \ \ 
                                         Term-Over-Position epp-comparisons 

\verb#              # induced by given pp-comparison and list of weights.  

\verb#              # {\tt :: Bool -> [PowerProduct] -> PPComp -> EPPComp}
\medskip
\\                       
{\tt ecpTOP0} \ \ \ref{sec-polv.e.i} \ \ \
                                       {\tt :: Bool -> PPComp -> EPPComp}

\verb#           # specialization of \ \verb#ecpTOP_weights# \ to zero weights
\medskip
\\                       
{\tt elemSymPols} \ \ \ref{sec-symmf.t.i} \ \ Elementary symmetric polynomials

\verb#              # $ [e_1,\ldots,e_n], \ \ \ e_i \in \ R[x_1,\ldots,x_n] $

\verb#        # 
            {\tt :: CommutativeRing a => Pol a -> Domains1 (Pol a) -> [Pol a]}
\medskip
\\                       
{\tt eLm} \ \ \ref{sec-polv.e.i} \ \ \ leading e-monomial

\verb#              # {\tt :: CommutativeRing a => EPol a -> EMon a}

\verb#              \f -> case epolMons f of {m:_ -> m;  _ -> error ...} #
\medskip
\\                       
{\tt eLpp} \ \ \ref{sec-polv.e.i} \ \ \  
           {\tt :: CommutativeRing a => EPol a -> EPP}

\verb#              # leading e-power product of non-zero e-polynomial
\medskip
\\                       
{\tt EMon} \ \ see \ref{sec-polv.e.i}, \ {\tt EPP, EPol}

\verb#              # {\tt type EMon a = (a, EPP)} \ \ \ extended monomial
\medskip
\\                       
{\tt emonMul} \ \ \ref{sec-polv.e.i} \ \ product of monomial by -emonomial

\verb#              # {\tt :: Ring a => a -> Mon a -> EMon a -> [EMon a]}

\verb#            \zero (a,p) (b,(j,q)) -> case mul a b of c -> if c==zero ...#
\medskip
\\                       
{\tt EPartition} \ \ see \ref{sec-symmf.p.p}, \ {\tt toEPrtt}
  
\verb#             # {\tt type EPartition = [Z]} \ \ --- expanded partitions
\medskip
\\                       
{\tt EPermut} \ \ \ref{sec-pm.d} \ \ \ {\tt type EPermut = [(Z,Z)]}

\verb#           # Extended form of permutation. It is made from  

\verb#           # {\tt Pm xs :: Permutation} \ \ by \ \ {\tt zip (sort xs) xs}
\medskip
\\                       
{\tt ePermutCycles} \ \ \ref{sec-pm} \ \ \ {\tt :: EPermut -> [EPermut]}

\verb#        # 
          Decomposes extended permutation $s$ to cycles \ $ [c_1,\ldots,c_r]$, 

\verb#        # length $c_1 \geq \ldots \geq$ length $c_r$ 
\\
\\
\\                       
{\tt EPol} \ \ see \ref{sec-polv.e.i}, \ {\tt EMon}, \ref{sec-polv.i},  
           \ref{sec-polv.i.e}

\verb#             # {\tt data EPol a = EPol ![EMon a] !EPPOTerm !(Pol a)}

\verb#             # indexed monomial-wise representation for polynomial vector
\medskip
\\                       
{\tt epolECp} \ \ \ref{sec-polv.e.i} \ \ \ {\tt :: EPol a -> EPPComp}

\verb#     #  
   {\tt (eppoECp . epolEPPOTerm)} \ \ extracts comparison for e-power-products 
\medskip
\\                       
{\tt epolEPPOTerm} \ \ \ref{sec-polv.e.i} \ \ 
              {\tt :: EPol a -> EPPOTerm} \ extracts EPPOTerm from e-pol
\medskip
\\                       
{\tt epolLCoord} \ \ \ref{sec-polv.e.i} \ \ \ 
                 {\tt :: CommutativeRing a => EPol a -> Z}  

\verb#             # leading e-monomial coordinate of non-zero e-polynomial
\medskip
\\                       
{\tt epolMons} \ \ \ref{sec-polv.e.i} \ \ {\tt :: EPol a -> [EMon a]} \ \ 
               extracts e-monomial list
\medskip
\\                       
{\tt epolPol} \ \ \ref{sec-polv.e.i} \ \ {\tt :: EPol a -> Pol a} \ \
                  extracts polynomial sample
\medskip
\\                       
{\tt epolPPCp} \ \ \ref{sec-polv.e.i} \ \ \
              {\tt (polPPComp . epolPol) :: EPol a -> PPComp}

\verb#              # extracts comparison for polynomial power products
\medskip
\\                       
{\tt epolToVecPol} \ \ \ref{sec-polv.e.i} \ \ \ 
  {\tt :: CommutativeRing a => Z -> EPol a -> Vector (Pol a)}

  Converts e-polynomial to polynomial vector \ {\tt Vec [\ldots]} \ 
  of given size 
\medskip
\\                       
{\tt EPP} \ \ \ref{sec-polv.e.i} \ \ \ {\tt type EPP = (Z, PowerProduct)}

\verb#      # Extended power product $(i,pp)$ represents the part of a  
  
\verb#      # 
        polynomial vector: monomial \ $1 \cdot pp$ \ related to coordinate No i
\medskip
\\                       
{\tt EPPComp} \ \ \ref{sec-polv.i} \ \ \ {\tt type EPPComp = Comparison EPP}

\verb#                # used similarly as \ {\tt PPComp}
\medskip
\\                       
{\tt eppoCp} \ \ \ref{sec-polv.i} \ \ \ {\tt tuple44 :: EPPOTerm -> PPComp}

\verb#                # extracts pp comparison
\medskip
\\                       
{\tt eppoECp} \ \ \ref{sec-polv.i} \ \ \
                                       {\tt tuple41 :: EPPOTerm -> EPPComp}

\verb#              # extracts epp comparison
\medskip
\\                                   
{\tt eppoMode} \ \ \ref{sec-polv.i} \ \ \ 
           {\tt tuple42  :: EPPOTerm -> String} \ \ \ extracts mode
\medskip
\\                       
{\tt eppoWeights} \ \ \ref{sec-polv.i} \ \ \ 
                           {\tt tuple43 :: EPPOTerm -> [PowerProduct]} 

\verb#              # extracts weights
\medskip
\\                       
{\tt EPPOTerm} \ \ \ref{sec-polv.i} \ \ term describing epp ordering.

\verb#        # {\tt type EPPOTerm = (EPPComp, String, [PowerProduct], PPComp)}

\verb#        # epp comparison function, \ mode, \ list of weights, \ldots
\medskip
\\                       
{\tt EPVecP} \ \ \ref{sec-polv.i} \ \ \ 
                          {\tt type EPVecP a = (EPol a, [Pol a])} 

\verb#              # used similarly as \ {\tt PVecP}
\medskip
\\     
\\                  
{\tt Eq} \ \ (\ref{sec-prp.ske} BSE) \ \ Standard Haskell class with equality

\verb#         # operation {\tt (==)}. \ {\tt DoCon} defines {\tt (==)} as algebraic 

\verb#         # equality for each domain (often, not as syntactic idenity)
\medskip
\\                       
{\tt eqListsAsSets} \ \ \ref{sec-dprel} \ \ \ 
                   {\tt :: Eq a => [a] -> [a] -> Bool}

\verb#            \xs ys -> all (`elem` xs) ys  &&  all (`elem` ys) xs #
\medskip
\\                       
{\tt eqFactrz} \ \ \ref{sec-ftr.op} \ \ \
            {\tt :: Eq a => Factorization a -> Factorization a -> Bool}

\verb#         # ``Equivalent factorizations''. Order of factors is immaterial
\medskip
\\                       
{\tt eucGCDE} \ \ \ref{sec-euc.fn} \ \ \
                        {\tt :: EuclideanRing a => [a] -> (a, [a])}

\verb#  # extended GCD for a list: \
          \verb#\xs -> (d,qs),  d = # 
                       $ \gcd [x_1,\ldots,x_n] = \sum_{i = 1}^n q_i x_i $
\medskip
\\                       
{\tt eucIdeal} \ \ see {\tt PIRChinIdeal}, \ref{sec-il.e} \ \
                                            builds ideal description.
 
\verb#        :: (FactorizationRing a, EuclideanRing a) =>#

\verb#        String -> a -> [a] -> [a] -> Factorization a -> PIRChinIdeal a#
\medskip
\\                       
{\tt Euclidean} \ \ \ref{sec-euc} \ \ \ \verb#:: Property_EucRing#

\verb#         # (Euclidean,Yes) \ means \ {\tt eucNorm, (divRem anyMode)} \ 

\verb#         # are correct algorithms for Euclidean ring structure
\medskip
\\                       
{\tt EuclideanRing} \ \ \ref{sec-euc} \ \ \ a category 

\verb#     # {\tt class (GCDRing a, LinSolvRing a) => EuclideanRing a where}

\verb#                {eucNorm :: a -> Z;  divRem ... baseEucRing ...} #
\medskip
\\                       
{\tt eucNorm} \ \ \ref{sec-euc} \ \ \ {\tt :: a -> Z} \ \ \ 
                        a norm, operation of {\tt EuclideanRing} category
\medskip
\\                       
{\tt EucRingTerm} \ \ \ref{sec-euc} \ \ \ 
                  description of Euclidean ring attributes:

\verb#     # {\tt data EucRingTerm a = }

\verb#        EucRingTerm {eucRingProps :: !Properties_EucRing} deriving(Show)#
\medskip
\\                       
{\tt evenL} \ \ \ref{sec-dprel} \ \ \ {\tt :: [a] -> Char}

\verb#    '+'# \ means that a given list has even length, \ 
         {\tt '-'} \ --- odd length 
\medskip
\\
{\tt Expression} \ \ \ref{sec-prp.pars}, \ref{sec-pars} \ \ 

\verb#    # intermediate data between {\tt String} and domain element.  

\verb#    # Elements are parsed from expressions. \ Say \ {\tt "(1+22)*3a"} 

\verb#    # may parse by {\tt (infixParse . lexLots)} to \ \verb#E (L "*") ...#
\medskip
\\
{\tt extendFieldToDeg} \ \ \ref{sec-upo.a.e} \ \ 
    extends finite field $k$ to field of given dimension over $k$

\verb#        # {\tt :: Field k => UPol k -> Domains1 (UPol k) -> Z ->}

\verb#                    (ResidueE (UPol k), Domains1 (ResidueE (UPol k)))#
\medskip
\\
{\tt FAA} \ \ \ref{sec-noncompol} \ \ Free associative algebra

\verb#                            # (of non-commutative polynomials)

{\tt data FAA a = FAA [FAAMon a] a FreeMOrdTerm FAAVarDescr (Domains1 a)}
\medskip
\\
{\tt FAAMon} \ \ \ref{sec-noncompol.faaarith} 

\verb#           type FAAMon a = (a, FreeMonoid)    -- FAA monomial #
\medskip
\\
{\tt faaNF} \ \ \ref{sec-noncompol.reduc} 

\verb#  # {\tt :: (EuclideanRing a) => String -> [FAA a] -> FAA a -> \ldots}
 
  reduction to Groebner normal form of non-commutative polynomial over a 

  Commutative Ring.
\medskip
\\
{\tt FAAVarDescr} \ \ \ref{sec-noncompol.faaarith} 

\verb# # 
{\tt type FAAVarDescr = (Maybe Z, (Z-> Maybe PolVar, PolVar-> Maybe Z))}
\medskip
\\ 
{\tt factor} \ \ \ref{sec-ftr} \ \ \ {\tt :: a -> Factorization a}

\verb#      # 
         factoring to primes: operation from \ {\tt FactorizationRing} category
\medskip
\\
{\tt factorial} \ \ \ref{sec-dprel} \ \ \  
                    \verb#{\0 -> 1; \n -> product [1..n]}  :: Z -> Z#
\medskip
\\
{\tt Factorial} \ \ \ref{sec-rg.pr} \ \ \verb#:: Property_Subring# \ \ 
                ``is a unique-factorization ring''
\medskip
\\               
{\tt Factorization} \ \ \ref{sec-ftr} \ \ \ 
                    {\tt type Factorization a = [(a,Z)]} \ \ \ \ Example: 

  \verb#   8*49*3 = 2^3*7^2*3# \ expresses as \ 
                            {\tt [(2,3),(7,2),(3,1)] :: Factorization Z}
\medskip
\\
{\tt FactorizationRing} \ \ \ref{sec-ftr} \ \ 
                      category of rings with factorization algorithm:

\verb#     # {\tt class GCDRing a => FactorizationRing a where}

\verb#                     isPrime...factor...primes...baseFactrRing#
\medskip
\\ 
{\tt FactrRingTerm} \ \ \ref{sec-ftr} \ \ \ 
                                {\tt data FactrRingTerm a =} \ldots

\verb#              # factorization ring attribute description
\medskip
\\
{\tt factrzDif} \ \ \ref{sec-ftr.op} \ \ 
                 difference of factorizations, factors order immaterial.

  {\tt :: Eq a => 
          Factorization a -> Factorization a -> Maybe (Factorization a)}

  Example: \ {\tt [(a,1),(b,2)] [(b,1)] --> Just [(a,1),(b,1)]}
\medskip
\\
{\tt Field} \ \ see \ref{sec-fld}, notion {\tt IsField}. \ \  A category:
             
\verb#        # {\tt class (EuclideanRing a, FactorizationRing a) => Field a}
                                      
\verb#        # presumed: {\tt (IsField,Yes)}
\medskip
\\  
{\tt Finite} \ \ \ref{sec-set.o} \ \ \verb#:: Property_OSet# \ \ \
                                                      ``is a finite set''
\medskip
\\
{\tt firstSWHook} \ \ \ref{sec-symmf.p.p} \ \ \
                                 {\tt :: Z -> Partition -> Maybe SHook}

\verb#       # 
         first skew hook \ $\lambda-\mu$ \ of weight $w$ in diagram \ $\lambda$

\verb#       # --- the one with the highest possible head, if there exists any
\medskip
\\
{\tt fmapfmap} \ \ \ref{sec-dprel} \ \ \verb#\f = fmap (fmap f)#

\verb#              :: (Functor c, Functor d) => (a->b) -> c (d a) -> c (d b)#
\medskip
\\ 
{\tt fmapmap} \ \ \ref{sec-dprel} 

\verb#       (\f -> fmap (fmap f))  :: Functor c => (a -> b) -> c [a] -> c [b]#
\medskip
\\
{\tt Fraction} \ \ \ref{sec-fr} \ \ \ \verb#infixl 7 :/#

\verb#      data Fraction a = !a :/ !a  deriving (Eq, Read)#

\verb#       # deriving \ {\tt Eq} \ relies on canonic representation approach
\medskip
\\
{\tt Fraction module} \ \ (see \ref{sec-dme}, \ref{sec-fr}) \ 
                      {\tt DoCon} module exporting items for {\tt Fraction}
\medskip
\\
{\tt freeMGCD} \ \ \ref{sec-noncompol.pp} 

\verb#       # {\tt :: FreeMonoid -> FreeMonoid -> (FreeMonoid, FreeMonoid)}
\medskip
\\
{\tt freeMN} \ \ \ref{sec-noncompol.pp} \ \ {\tt :: FreeMonoid -> Maybe Z}

\verb#      freeMN (FreeM mn _) = mn  #
\medskip
\\
{\tt freeMOComp} \ \ \ref{sec-noncompol.pp} \ \ 
                            {\tt :: FreeMOrdTerm -> Comparison FreeMonoid}
\medskip
\\
{\tt freeMOId} \ \ \ref{sec-noncompol.pp} \ \  {\tt :: FreeMOrdTerm -> PPOId}
\medskip
\\
{\tt FreeMonoid} \ \ \ref{sec-noncompol.pp}

\verb#       data FreeMonoid = FreeM (Maybe Z) [(Z,Z)]  deriving (Show, Eq)#
\medskip
\\
{\tt FreeMOrdTerm} \ \ \ref{sec-noncompol.pp}

\verb#       # {\tt type FreeMOrdTerm = (PPOId, Comparison FreeMonoid)}
\medskip
\\
{\tt freeMRepr} \ \ \ref{sec-noncompol.pp} \ \ {\tt :: FreeMonoid -> [(Z,Z)]}

\verb#                             freeMRepr  (FreeM _ ps) =  ps #
\medskip
\\
{\tt freeMWeightLexComp} \ \ \ref{sec-noncompol.pp} 

\verb#       # {\tt :: (Z -> Z) -> FreeMonoid -> FreeMonoid -> CompValue}
\medskip
\\
{\tt frobenius} \ \ \ref{sec-rg.sub} \ \ \ {\tt :: (a -> a, a -> MMaybe a)}

  data field in \ {\tt WithPrimeField} construct of \verb#Operation_Subring#, 

  data for the maps \ \verb#(^p) :: a -> a# \ \ and its inverse
\medskip
\\
{\tt fromEPermut} \ \ \ref{sec-pm.d} \ \ \ 
                           {\tt (Pm . map snd) :: EPermut -> Permutation}
\medskip
\\
{\tt fromEPrtt} \ \ \ref{sec-symmf.p.p} \ \ \ 
                                   {\tt :: EPartition -> Partition} \ \ \
                    inverse to \ {\tt toEPrtt}
\medskip
\\ 
\\
{\tt fromExpr} \ \ \ref{sec-set}, \ref{sec-pars} \ \ \
                         {\tt :: a -> Expression String -> ([a], String)}

\verb#   # Operation from {\tt Set} category: parses by sample the element from

\verb#   # expression {\tt e}, \ {\tt e} usually obtained by \ 
           {\tt infixParse} {\it string}
\medskip
\\
{\tt fromHeadVarPol} \ \ \ref{sec-pol.f} \ \ \ {\tt :: UPol (Pol a) -> Pol a}

  
\verb#     # 
      $ (a[x_2,\ldots,x_n])[x1] \rightarrow a[x_1,x_2,\ldots,x_n], \ \ n > 1 $

\verb#     # 
      Inverse to \ {\tt headVarPol}. \ For the \ {\tt lexComp} \ ordering only
\medskip
\\
{\tt fromi} \ \ \ref{sec-rg.fn} \ \ \ {\tt :: Ring a => a -> Z -> a} 

\verb#  # map from integer by sample. 
  Composition of \verb#fromi_m# and \ {\tt error}

\verb#  # Example: \ \verb# fromi (Vec [1:/2)]) 3 =  Vec [3:/1] #
\medskip
\\
\verb#fromi_m# \ \ \ref{sec-rg} \ \ \ {\tt :: a -> Z -> Maybe a} \ \ 
                  operation from {\tt Ring} category.

  Standard homomorphism \ {\tt Z -> a}, \ domain \ {\tt a} defined by      
  given sample. 
  
  Example: \ \verb# fromi_m (0:/1) 3 = Just (3:/1) #
\medskip
\\
{\tt fromOverHeadVar} \ \ \ref{sec-pol.f} \ \ \ 
                      {\tt :: CommutativeRing a => Pol (UPol a) -> Pol a} 

\verb#    # $ (a[y])[x_1,\ldots,x_n] \rightarrow a[y,x_1,\ldots,x_n] $

\verb#    # Inverse to \ {\tt toOverHeadVar}. \ Only for {\tt lexComp} ordering
\medskip
\\
{\tt fromPolOverPol} \ \ \ \ref{sec-pol.f} \ \ 

\verb#      # 
     from \ {\tt a[xs][ys]} \ to \ {\tt a[xs \ ys]} \ or to \ {\tt a[ys \ xs]}
\medskip
\\
{\tt fromRPol} \ \ \ref{sec-rpol.d} \ \ r-polynomial to polynomial:

\verb#        # {\tt :: CommutativeRing a => PPOrdTerm -> RPol a -> Pol a}
\medskip
\\
{\tt fromSqMt} \ \ \ref{sec-mt.f} \ \ \
           \verb#(\SqMt rs d -> Mt rs d) :: SquareMatrix a -> Matrix a#
\medskip
\\
{\tt fromSymPol} \ \ \ref{sec-symmf.sp} \ \ 
               expand sym-polynomial to polynomial of given sample:

  {\tt :: CommutativeRing a => Pol a -> Domains1 (Pol a) -> SymPol a -> Pol a}
  
  Method: convert to \ $h(e_1,\ldots), \ e_i$ \ elementary symmetrics \ldots
\medskip
\\
{\tt fromUPol} \ \ \ref{sec-pol.f} \ \ \ {\tt :: UPol a -> Pol a} \ \ 
                convert from univariate polynomial:

\verb#      # make vector of size 1 from each exponent,
    
\verb#      # set the variable list \ {\tt [v]} \ and \ {\tt lexPPO} \ ordering
\medskip
\\
{\tt fromZ} \ \ \ref{sec-dprel} \ \ \ {\tt fromInteger :: Num a => Z -> a}
\medskip
\\
{\tt FullType} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet# \ \ 
                                     ``subset = all values of this type''
\medskip
\\
{\tt gatherFactrz} \ \ \ref{sec-ftr.op} \ \ \
                   {\tt :: Eq a => Factorization a -> Factorization a}

\verb#          # Bring to true factorization by joining repetitions.
                
\verb#          # Example: \ {\tt [(f,2),(g,1),(f,3)] -> [(f,5),(g,1)]}
\medskip
\\
{\tt gcD} \ \ \ref{sec-gcd} \ \ \ {\tt :: [a] -> a} \ \ \ 
             operation from {\tt GCDRing} category: gcd for a list
\medskip
\\
{\tt GBasis} \ \ see \ref{sec-dme}, \ref{sec-pol.a.gr} \ \ 
                      {\tt DoCon} module exporting items of Gr\"obner basis
\medskip
\\
\\
\\
{\tt GCDRing} \ \ \ref{sec-gcd} \ \ category of rings with gcd algorithm:

  {\tt class (CommutativeRing a, MulMonoid a) => GCDRing a where}
  
\verb#  baseGCDRing...canAssoc...canInv...gcD...lcM...hasSquare...toSquareFree#
\medskip
\\ 
{\tt GCDRingTerm} \ \ see \ref{sec-gcd}, \verb#Property_GCDRing# \ \
                      gcd-ring description term:

  \verb#      data GCDRingTerm a = GCDRingTerm {gcdRingProps :: ...} ...#
\medskip
\\
{\tt genFactorizationsFromIdeal} \ \ \ref{sec-il.g.fn} \ \ \ 
                                  {\tt :: Ideal a -> Maybe [Factorization a]} 

\verb#    # 
     extract factorization list from first {\tt GenFactorizations} construction
\medskip
\\
{\tt gensToIdeal} \ \ \ref{sec-il.g.b} \ \ \ makes ideal from generators

\verb#  :: LinSolvRing a => [a] -> [Factorization a] -> Properties_IdealGen ->#
 
\verb#   Properties_Ideal -> Domains1 a -> Domains1 a -> (Domains1 a, Ideal a)#
\medskip
\\
{\tt getOp} \ \ \ref{sec-pars} \ \ 
                         get operation group from table (for parsing)

\verb#           # {\tt :: Eq a => OpTable a -> a -> Maybe (OpGroupDescr a)}
\medskip
\\
\verb#greaterEq_m# \ \ \ref{sec-dprel} \ \ \
                 \verb#(x==y || greater_m x y) :: Set a => a -> a -> Bool#  
\medskip
\\
\verb#greater_m# \ \ \ref{sec-dprel} \ \ \ {\tt :: Set a => a -> a -> Bool}

\verb#              case compare_m x y of {Just GT -> True,  _-> False}#
\medskip
\\
{\tt gxBasis} \ \ \ref{sec-linr.g} \ \ \ 
        {\tt :: [a] -> ([a], [[a]])} \ \ \ generalization of Gr\"obner basis,

\verb#              #   operation from \ {\tt LinSolvRing} \ category, 
\medskip
\\
{\tt gxBasisM} \ \ \ref{sec-mod.ls}, \ref{sec-mod.lsm}, \ref{sec-gx} \ \ \ 
                     {\tt :: r -> [a] -> ([a], [[r]])}
 
\verb#              # operation from \ {\tt LinSolvLModule r a} \ category
\medskip
\\
{\tt halve} \ \ \ref{sec-dprel} \ \ \ {\tt :: [a] -> ([a], [a])} \ \ 
               breaks list by the middle
               
\verb#              # Example: \ {\tt [1,2,3,4,5] --> ([1,2,3],[4,5])}
\medskip
\\
{\tt HasNilp} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring# \ \ 
                                ``ring has a nilpotent''
\medskip
\\
{\tt HasZeroDiv} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring# \ \ 
                                        ``ring has zero divisor''
\medskip
\\
{\tt headVarPol} \ \ \ref{sec-pol.f} \ \ brings polynomial to head variable

  {\tt :: CommutativeRing a => Domains1 (Pol a) -> Pol a -> UPol (Pol a)}

 {\tt  a$[x_1,x_2,\ldots,x_n] \ \longrightarrow$ \ a$[x_2,\ldots,x_n][x_1]$ }
\medskip
\\
{\tt HBand} \ \ \ref{sec-symmf.p.p} \ \ \ 
            {\tt type HBand = [Z]} \ \ \ horizontal band (of combinatorics): 

\verb#        # a skew diagram containing not more than one box in each column
\medskip
\\
{\tt henselLift} \ \ \ref{sec-upo.a.h} 
  
  {\tt :: (EuclideanRing a, FactorizationRing a, Ring (ResidueE a) =>}

  \verb#  UPol a -> UPol a -> UPol a -> Maybe (UPol a) -> a -> a -> Z -> Z ->#

  \verb#  (UPol a, UPol a, UPol a, a) #
\medskip
\\
{\tt hookLengths} \ \ \ref{sec-symmf.p.kn} \ \ \ {\tt :: Partition -> [[Z]]}

\verb#         # a matrix, each \ {\tt h(i,j)} \ is the length of the hook of the 

\verb#         # point \ {\tt (i,j)} \ in a given Young diagram.
\medskip
\\
{\tt hPowerSums} \ \ \ref{sec-symmf.t.i} \ \ \ 
                       {\tt :: CommutativeRing a => Pol a -> [Pol a]}
  
\verb#              # homogeneous power sums \ $ p_i = \sum_{k = 1}^n x_k^i $

\verb#              # built from the given sample polynomial
\medskip
\\
\verb#h'to_p_coef# \ \ \ref{sec-symmf.t.i} \ \ \ {\tt :: Partition -> Z}

  coefficient \ $z_{\lambda}$ \ in expression \ 
             $ h(n) = sum_{|\lambda| = n} (1/z_{\lambda}) p_{\lambda} $

  of the full homogeneous function \ $h_n$
\medskip
\\
{\tt Ideal} \ \ \ref{sec-il.g} \ \ \ description of ideal in a ring: 

\verb#           data Ideal a = Ideal {idealGens :: !(Maybe [a]), ...}# 
\medskip
\\
{\tt idealConstrs} \ \ \ref{sec-il.g} \ \ \ 
                                     \verb#:: ![Construction_Ideal a]#

\verb#     # part of description of ideal. \ So far, it may contain only 

\verb#     # {\tt (GenFactorizations fts)} \ --- for a factorial ring \ {\tt a}
\medskip
\\
{\tt idealGenProps} \ \ \ref{sec-il.g} \ \ \ 
                                         \verb#:: !Properties_IdealGen#
   
\verb#        # part of description of ideal: properties of generator list
\medskip
\\
{\tt idealGens} \ \ \ref{sec-il.g} \ \ \ \verb#:: !(Maybe [a])#

\verb#     # Part of description of ideal: generators. \ {\tt Just gs} \ means 
   
\verb#     # a finite generator list, \ \ {\tt Nothing} --- such list not found
\medskip
\\
{\tt idealOpers} \ \ \ref{sec-il.g} \ \ \ 
         \verb#:: !(Operations_ideal a)# \ \ part of description of ideal
\medskip
\\ 
{\tt idealProps} \ \ \ref{sec-il.g} \ \ \ 
               \verb#:: !Properties_Ideal# \ \ part of description of ideal 
\medskip
\\
{\tt incomparable} \ \ \ref{sec-dprel} \ \ \ 
         \verb#(compare_m x y == Nothing)  :: Set a => a -> a -> Bool#
\medskip
\\
{\tt infixParse} \ \ (see {\tt lexLots, infixParse} in 
                 ~\ref{sec-pars}) \ \ parses expression list:

  {\tt :: (Eq a, Read a, Show a)=> 
                             ParenTable a-> OpTable a-> [Expression a]-> }
      
 \verb#                                               ([Expression a], String)#
\medskip
\\
{\tt InfUnn} \ \ \ref{sec-dprel} \ \ \
                        {\tt data InfUnn a = Fin !a | Infinity | UnknownV} 
 
  \verb#                                # {\tt deriving (Eq, Show, Read)} 

\verb#    # 
         domain \ {\tt a} \ extended with the  values \ {\tt Infinity, Unknown}
\medskip
\\
{\tt Integer} \ \ \ref{sec-z} \ \ \
                      {\tt type Z = Integer} \ \ ring of integers, 

  supplied with the instances of \ {\tt EuclideanRing, OrderedRing}, \ 
  and some others
\medskip
\\
{\tt intListToSymPol} \ \ \ref{sec-symmf.t.i} 

  {\tt :: Ring a => 
       Char-> SymPol a-> Partition-> [Partition] -> [Z] -> SymPol a}
            
  converts integer list to sym-polynomial under {\tt pLexComp} ordering
\medskip
\\
\\
{\tt inv} \ \ \ref{sec-smg.m} \ \ \ {\tt :: MulSemigroup a => a -> a}

\verb#            # inversion (composed \verb#inv_m# and \ {\tt error})
\medskip
\\
{\tt invEPermut} \ \ \ref{sec-pm.d} \ \ \ {\tt :: EPermut -> EPermut} \ \ 
                                          inverse e-permutation
\medskip
\\ 
\verb#inverseMatr_euc# \ \ \ref{sec-lin.u} \ \ \  
                              {\tt :: EuclideanRing a => [[a]] -> [[a]]}

\verb#           # inversion of matrix over an Euclidean ring.

\verb#           # Returnes \ {\tt []} \ for in-invertible matrix.
\medskip
\\
{\tt invertible} \ \ \ref{sec-smg.m} \ \ \ 
              \verb#(isJust . inv_m)  :: MulSemigroup a => a -> Bool#
\medskip
\\ 
{\tt invSign} \ \ \ref{sec-dprel} \ \ \ 
                   {\tt ('+' --> '-';  '- ' --> '+') \ :: Char -> Char}
\medskip
\\
\verb#inv_m# \ \ \ref{sec-smg.m} \ \ \ {\tt :: a -> Maybe a}
 
\verb#   # operation from {\tt MulSemigroup} category: inverse element.

\verb#   # Example: \ \verb#map inv_m [-1,0,2] = [Just (-1), Nothing, Nothing]#
\medskip
\\          
{\tt IsBaseSet} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet#
\medskip
\\
{\tt IsCanAssocModule} \ \ \ref{sec-mod.lsm} 
\medskip
\\
{\tt isCEucRing} \ \ \ref{sec-euc.fn} 

\verb#     (lookupProp DivRemCan . eucRingProps) :: EucRingTerm a -> PropValue#
\medskip
\\
{\tt isCommutativeSmg} \ \ \ref{sec-smg.fn} 

\verb#   (lookupProp Commutative . subsmgProps) :: Subsemigroup a -> PropValue#
\medskip
\\
{\tt isCorrectRse} \ \ \ref{sec-rse.p} \ \ \ 
                        {\tt :: EuclideanRing a => ResidueE a -> Bool}

   \verb#           Rse x i _ -> case pirCIBase i of b -> x==(remEuc 'c' x b)#
\medskip
\\
{\tt isCorrectRsg} \ \ \ref{sec-rsg} \ \ \ 
                                   {\tt :: AddGroup a => ResidueG a -> Bool}

  \verb#  \Rsg x d _ -> case subgrCanonic $ fst d of Just cn -> x==(cn x)#

  \verb#                                             Nothing -> error ...#
\medskip
\\
{\tt isCorrectRsi} \ \ \ref{sec-rsi.p} \ \ \
                        {\tt :: LinSolvRing a => ResidueI a -> Bool}

                 tests for generator list with property {\tt (IsGxBasis, Yes)}
\medskip
\\
{\tt isDiagMt} \ \ \ref{sec-mt.f} \ \ \ 
          {\tt :: AddGroup a => [[a]] -> Bool} \ \ ``is a diagonal matrix''
\medskip
\\
{\tt isEucRing} \ \ \ref{sec-euc.fn}

 \verb#    (lookupProp Euclidean . eucRingProps) :: EucRingTerm a -> PropValue#
\medskip
\\
{\tt isField} \ \ \ref{sec-rg.fn} \ \ \ {\tt :: Subring a -> PropValue}
\medskip
\\
{\tt IsFreeModuleBasis} \ \ \ref{sec-mod.s} \ \ \ 
                             \verb#:: Property_SubmoduleGens#

\verb#        # {(IsFreeModuleBasis,Yes)} \ means the generators are linearly

\verb#        # independent over $R$, \ \ module $M$ is free
\medskip
\\
\\
{\tt isGBasis} \ \ (\ref{sec-pol.a.gr} \{ig\}) \ \ \ 
               {\tt :: EuclideanRing a => [Pol a] -> Bool}

\verb#                 # ``is a (weak) Gr\"obner basis''
\medskip
\\ 
{\tt isGCDRing} \ \ \ref{sec-gcd} 

\verb#    (lookupProp WithGCD . gcdRingProps)  :: GCDRingTerm a -> PropValue#
\medskip
\\
{\tt IsGradedRing} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring#

\verb#       # the triplet \ {\tt (Grading' cp weight forms)} \ from 

\verb#       # {\tt subringOpers} \ satisfies the grading axioms  
\medskip
\\
{\tt isGroup} \ \ \ref{sec-smg.fn} 
  
\verb#     (lookupProp IsGroup . subsmgProps) :: Subsemigroup a -> PropValue#
\medskip
\\
{\tt IsGxBasis} \ \ \ref{sec-il.g} \ \ \ \verb#:: Property_IdealGen#

\verb#       # condition for canonic reduction by an ideal $I$, \ldots 
  
\verb#       #   See the gx-basis notion in \ref{sec-gx}
\medskip
\\
{\tt isGxModule} \ \ \ref{sec-mod.lsm} \ \ \ 
                           {\tt :: LinSolvModuleTerm r a -> PropValue}
\medskip
\\
{\tt isGxRing} \ \ \ref{sec-linr.t} \ \ \ 
                              {\tt :: LinSolvRingTerm a -> PropValue}

\verb#         # {\tt lookupProp IsGxRing . linSolvRingProps}
\medskip
\\
{\tt IsGxRing} \ \ \ref{sec-linr.t} \ \ \ \verb#:: Property_LinSolvRing#

  {\tt (IsGxRing,Yes)} \ means {\tt ModuloBasisDetaching} and \ldots \ \ 
  See \ref{sec-gx}
\medskip
\\   
{\tt isLowTriangMt} \ \ \ref{sec-mt.f} \ \ \ 
     {\tt :: AddGroup a=> [[a]] -> Bool} \ ``is a lower-triangular matrix''
\medskip
\\
{\tt isMaxIdeal} \ \ \ref{sec-il.g.fn} \ \ \ 
                 {\tt :: Ideal a -> PropValue} \ \ ``is a maximal ideal''
\medskip
\\
{\tt IsMaxIdeal} \ \ \ref{sec-il.g} \ \ 
              \verb#:: Property_Ideal# \ \ key for ``is a maximal ideal''
\medskip
\\
{\tt isMonicPP} \ \ \ref{sec-pp.d} \ \ \ {\tt :: PowerProduct -> Bool}

\verb#       # monic pp corresponds to a monomial \ $x_i^{k_i}, \ k_i \geq 0$
\medskip
\\
{\tt isoDomain1} \ \ see \ref{sec-iso}, {\tt isoOSet, isoRing, \ldots}

\verb#       # {\tt :: (a -> b) -> (b -> a) -> Domain1 a -> Domain1 b}

\verb#       # builds isomorphic copy of the given domain term
\medskip
\\
{\tt isoDomains1} \ \ \ref{sec-iso} \ \ isomorphic copy of a bundle 

\verb#       # {\tt :: (a -> b) -> (b -> a) -> Domains1 a -> Domains1 b}

\verb#       # \verb#... mapFM (\_ dom -> isoDomain1 f f' dom) ...#
\medskip
\\
{\tt isoDomain22} \ \ \ref{sec-iso} \ \ \ similar to {\tt isoDomain1}

\verb#       # {\tt :: (a -> b) -> (b -> a) -> Domain2 c a -> Domain2}
\medskip
\\
{\tt isoDomains22} \ \ \ref{sec-iso} \ \ \ similar to {\tt isoDomains1}

\verb#       # {\tt :: (a -> b) -> (b -> a) -> Domains2 c a -> Domains2 c b}
\medskip
\\
{\tt isoGroup} \ \ \ref{sec-grp.fn} \ \ \ isomorphic image of subgroup

\verb#       # {\tt :: (a -> b) -> (b -> a) -> Subgroup a -> Subgroup b}
\medskip
\\
{\tt isoModule} \ \ \ref{sec-mod.lsm} \ \ \ 
        {\tt :: (a -> b) -> (b -> a) -> Submodule r a -> Submodule r b}

\verb#          # isomorphic image of submodule description
\medskip
\\
{\tt isoOSet} \ \ \ref{sec-set.fn} \ \ isomorphic copy of set term
     
\verb#             # {\tt :: (a -> b) -> (b -> a) -> OSet a -> OSet b}
\medskip
\\
{\tt isOrderedBy} \ \ \ref{sec-dprel} \ \ \ 
                         {\tt :: Comparison a -> [a] -> Bool}

\verb#                   # ``list is ordered by given comparison''
\medskip
\\
{\tt isOrderedRing} \ \ \ref{sec-rg.fn} \ \ \ {\tt :: Subring a -> PropValue}
\medskip
\\
{\tt IsOrderedRing} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring#
\medskip
\\
{\tt isoRing} \ \ \ref{sec-rg.fn} \ \ \ isomorphic copy of ring term 
 
\verb#               :: (a -> b) -> (b -> a) -> Subring a -> Subring b#
\medskip
\\
{\tt isoSemigroup} \ \ \ref{sec-smg.fn} \ \ isomorphic copy of semigroup term 

\verb#          :: (a -> b) -> (b -> a) -> Subsemigroup a -> Subsemigroup b#
\medskip
\\
{\tt isPrimaryIdeal} \ \ \ref{sec-il.g.fn} \ \ \ {\tt :: Ideal a -> PropValue}
\medskip
\\
{\tt IsPrimaryRing} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring#

\verb#            # ``any zero divisor in this ring is a nilpotent''
\medskip
\\
{\tt isPrime} \ \ \ref{sec-ftr} \ \ \ {\tt :: a -> Bool} \ \
                   operation from {\tt FactorizationRing} category
\medskip
\\
{\tt isPrimeIdeal} \ \ \ref{sec-il.g.fn} \ \ \ {\tt :: Ideal a -> PropValue}
\medskip
\\
{\tt isPrimeIfField} \ \ \ref{sec-rg.fn} \ \ \ {\tt :: Subring a -> PropValue}

\verb#          # ``is a prime field (correct to apply only for a field)''
\medskip
\\
{\tt isPrtt} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt :: Partition -> Bool}

\verb#            # tests \ {\tt p :: [(Z,Z)]} \ for being a partition
\medskip
\\
{\tt IsRealField} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring#

\verb#        IsField  &&  (-1  is not a sum of squares in this ring) #
\medskip
\\
{\tt isStaircaseMt} \ \ \ref{sec-mt.f} \ \ \ 
        {\tt :: AddGroup a => [[a]] -> Bool} \ \ ``is a staircase matrix''
\medskip
\\
{\tt isZero} \ \ \ref{sec-smg.fn} \ \ \ {\tt :: AddSemigroup a => a -> Bool}

\verb#            isZero a = case zero_m a of Just z -> a==z  #

\verb#                                        _      -> False #
\medskip
\\
{\tt isZeroMt} \ \ \ref{sec-mt.f} \ \ \ 
            {\tt :: AddSemigroup a => [[a]] -> Bool} \ \ ``is zero matrix''
\medskip
\\
{\tt kostkaColumn} \ \ \ref{sec-symmf.p.kn} \ \ 
  column \ $[ K(\lambda,\mu) | \ \lambda \in \ldots  ]$ \ 
  of Kostka numbers \ldots

\verb#          :: Partition -> [Partition] -> (Map.Map Partition Z, [Z])#
\medskip
\\
{\tt kostkaNumber} \ \ \ref{sec-symmf.p.kn} \ \ 
            mumber of tableaux of shape $\lambda$ \ldots

  {\tt :: FiniteMap Partition Z -> Partition -> Partition ->}

  \verb#                               # {\tt (Map.Map Partition Z, Z)}
\medskip
\\ 
{\tt kostkaTMinor} \ \ \ref{sec-symmf.p.kn} \ \ \
                            {\tt :: [Partition] -> [Partition] -> [[Z]]} 

\verb#            # transposed minor of matrix of Kostka numbers
\medskip
\\
{\tt lc} \ \ \ref{sec-pl} \ \ \ {\tt :: (PolLike p, Set a) => p a -> a}
   
\verb#         \f -> = case pCoefs f of {a:_ -> a;  _ -> error "lc 0 ..."}#

\verb#           # leading coefficient for non-zero polynomial-like thing
\medskip
\\
{\tt lc0} \ \ \ref{sec-pl} \ \ \
  {\tt :: (PolLike p, AddSemigroup (p a), Set a) => a -> p a -> a}
                                             
\verb#                 \zr f -> if isZero f then zr else lc f #
\medskip
\\
{\tt lcM} \ \ \ref{sec-gcd} \ \ \ {\tt :: [a] -> a}

\verb#         # operation from {\tt GCDRing} category: \ lcm \ for a list
\medskip
\\
{\tt ldeg} \ \ \ref{sec-pl} \ \ \ {\tt :: CommutativeRing a => p a -> Z}

\verb#       # operation from constructor class {\tt PolLike}: 

\verb#       # total degree of {\tt lpp} (depends on monomial ordering)
\medskip
\\
{\tt leastEMon} \ \ \ref{sec-polv.e.i} \ \ \
          {\tt :: CommutativeRing a => EPol a -> EMon a}

\verb#        \f -> case epolMons f of {[] -> error...;  ms -> last ms}#
\medskip
\\
{\tt leastMon} \ \ \ref{sec-pol.f} \ \ \ {\tt :: Set a => Pol a -> Mon a}

\verb#           # last monomial of a non-zero polynomial
            
\verb#          \f-> case polMons f of {[] -> error ...;  ms -> last ms}#
\medskip
\\
{\tt leastUPolMon} \ \ \ref{sec-upo.i} \ \ \ 
                           {\tt :: Set a => UPol a -> UMon a}

\verb#           \f -> case upolMons f of {[] -> error...;  ms-> last ms}#
\medskip
\\
{\tt LeftModule} \ \ \ref{sec-mod.l} \ \ category Left Module over a Ring

\verb#    # {\tt class (Ring r, AddGroup a) => LeftModule r a where}

\verb#                      {cMul :: r -> a -> a,   baseLeftModule :: ...}#
\medskip
\\
\verb#essEq_m# \ \ \ref{sec-dprel} \ \ \
              \verb#(x==y || less_m x y)  :: Set a => a -> a -> Bool#
\medskip
\\
\verb#less_m# \ \ \ref{sec-dprel} \ \ \ {\tt :: Set a => a -> a -> Bool}

\verb#          case compare_m x y of {Just LT -> True; _-> False} #
\medskip
\\
{\tt lexComp} \ \ \ref{sec-pp.d} \ \ \ {\tt :: PPComp} \ \
                                             lexicographic pp comparison
\medskip
\\
{\tt lexFromEnd} \ \ \ref{sec-pp} \ \ \ {\tt :: PPComp}

\verb#       # compares power products lexicographically-from-end
\medskip
\\
{\tt lexListComp} \ \ \ref{sec-dprel} \ \ \ 
                {\tt :: (a -> b -> CompValue) -> [a] -> [b] -> CompValue}

\verb#     # 
      compares lists lexicographically according to given element comparison
\medskip
\\
{\tt lexLots} \ \ \ref{sec-pars} \ \ \ {\tt :: String -> [Expression String]}

 \verb#             # breaks string to the list of lexemes, 

 \verb#             # according to standard {\tt Haskell} set of delimiters
\medskip
\\
{\tt lexPPO} \ \ \ref{sec-pp.o} \ \ \ {\tt :: Z -> PPOrdTerm} 

\verb#       # most usable ppo is \ {\tt lexPPO n = (("",n), lexComp, [])}
\medskip
\\
{\tt LinAlg} \ \ \ref{sec-dme}, \ref{sec-lin} \ \ 
                           {\tt DoCon} module exporting items for linear algebra
\medskip
\\
\verb#linBasInList_euc# \ \ \ref{sec-lin.u} \ \ \ 
            {\tt :: EuclideanRing a => [[a]] -> ([Bool], [[a]])}
 
\verb#      # 
         mark in a matrix maximal possible linearly independent subset of rows 
\medskip
\\
{\tt LinSolvLModule} \ \ \ref{sec-mod.ls} \ \
         category Syzygy Solvable Left Module over a Ring:

\verb#       # 
       {\tt class (LinSolvRing r, LeftModule r a) => LinSolvLModule r a \ldots}
\medskip
\\
{\tt LinSolvModuleTerm} \ \ \ref{sec-mod.lsm} \ \ \ 
                         {\tt data LinSolvModuleTerm r a =}

\verb#                    LinSolvModuleTerm {linSolvModuleProps :: ...}# \ldots
\medskip
\\
{\tt LinSolvRing} \ \ \ref{sec-linr}, \ref{sec-gx}

\verb#   # category Syzygy Solvable Ring with Cacnonical Ideal reduction  

\verb#   # {\tt class (CommutativeRing a, MulMonoid a) => LinSolvRing a \ldots}
\medskip
\\
{\tt LinSolvRingTerm} \ \ \ref{sec-linr.t} \ \ \ 
                      {\tt data LinSolvRingTerm a =}

\verb#                        LinSolvRingTerm {linSolvRingProps ::...}# \ldots
\medskip
\\
{\tt listToSubset} \ \ \ref{sec-set.fn} \ \ 
                            makes Listed Proper subset in base set

\verb#         :: Set a => [a] -> [Construction_OSet a] -> OSet a -> OSet a#
\medskip
\\
{\tt List} \ \ \ref{sec-l} \ \ For {\tt List} constructor {\tt []},  
                             {\tt DoCon} provides only \ {\tt Set} \ instance,  

\verb#         # in addition to {\tt Haskell} instances
\medskip
\\
{\tt lm} \ \ \ref{sec-pl} \ \ \ {\tt :: CommutativeRing a => p a -> Mon a}
 
\verb#             # leading monomial of non-zero pol-like thing
\medskip
\\
{\tt lmU} \ \ \ref{sec-upo.i} \ \ \ {\tt :: Set a => UPol a -> UMon a}

                          leading monomial of an univariate polynomial
\medskip
\\
{\tt logInt} \ \ \ref{sec-z.fn} \ \ \ 
                    {\tt :: (Ord a, OrderedRing a) => a -> a -> Z}
  
\verb#      \b a -># integer part of logarithm of {\tt a > 1} by {\tt b > 1}
\medskip
\\
{\tt lookupProp} \ \ \ref{sec-dprel} 

\verb#  (\a-> mbPropV . lookup a) :: Eq a => a -> [(a,PropValue)] -> PropValue#
\medskip
\\
{\tt lpp} \ \ \ref{sec-pl} \ \ \ operation from {\tt PolLike} category:
               
\verb#       # {\tt :: CommutativeRing a => p a -> PowerProduct} 
               
\verb#       # leading power product of non-zero pol-like thing
\medskip
\\
{\tt mainMtDiag} \ \ \ref{sec-mt.f} \ \ \ {\tt :: [[a]] -> [a]} \ \ 
                                                 main diagonal of matrix 
\medskip
\\ 
{\tt Makefile} \ \ see \ref{sec-start.2}, \ file \ {\tt install.txt}.
\medskip
\\
{\tt mapfmap} \ \ \ref{sec-dprel} \ \ 
       \verb#(\f -> map (fmap f)) :: Functor c => (a->b) -> [c a] -> [c b]#
\medskip
\\
{\tt mapmap} \ \ \ref{sec-dprel} \ \ \ 
                          {\tt map (map f) :: (a -> b) -> [[a]] -> [[b]]}
\medskip
\\
{\tt mapMt} \ \ \ref{sec-mt.f} \ \ \ 
                           {\tt :: (a -> a) -> Matrix a  -> Matrix a}

\verb#         # map to matrix \ \ \verb#\f (Mt rs d) -> Mt (mapmap f rs) d#
\medskip
\\
{\tt mapSqMt} \ \ \ref{sec-mt.f} \ \ \ 
              {\tt :: (a -> a) -> SquareMatrix a -> SquareMatrix a} 

map to square matrix:  \verb#     \ f (SqMt rs d) -> SqMt (mapmap f rs) d#
\medskip
\\
{\tt Matrix} \ \ \ref{sec-mt.f} \ \ \
               {\tt data Matrix a = Mt ![[a]] !(Domains1 a)} 

\verb#     Mt rows dm  # 
       should contain non-empty list of non-empty lists of same length
\medskip
\\
{\tt matrHead} \ \ \ref{sec-mt.f} \ \ \ 
                             {\tt (mtHead . matrRows) :: Matrix a -> a}
\medskip
\\
{\tt matrHeight} \ \ \ref{sec-mt.f} \ \ \  
                                 (mtHeight . matrRows) :: Matrix a -> Z
\medskip
\\
{\tt matrRows} \ \ \ref{sec-mt.f} \ \ \
                        \verb#(\ Mt rs _ -> rs) :: Matrix a -> [[a]]# 
\medskip
\\
{\tt matrTail} \ \ \ref{sec-mt.f} \ \ \ {\tt :: Matrix a -> [[a]]}

\verb#            \m -> case matrRows m of {_:rs -> rs,  _ -> error...}#
\medskip
\\
{\tt matrWidth} \ \ \ref{sec-mt.f} \ \ \ 
                          \verb#(mtWidth . matrRows) :: Matrix a -> Z#
\medskip
\\
{\tt maxAhead} \ \ \ref{sec-dprel} \ \ {\tt :: Comparison a -> [a] -> [a]}

      put ahead maximum without changing the order of the rest
\medskip
\\
{\tt maxBy} \ \ \ref{sec-dprel} \ \ \ 
        {\tt :: Comparison a -> [a] -> a} \ \ maximum by given comparison
\medskip
\\
{\tt maxHWBand} \ \ \ref{sec-symmf.p.p} \ \ \ 
                              {\tt :: Char -> Partition -> Z -> Maybe HBand}

\verb#              # maximal h-w-band in a given partition
\medskip
\\
{\tt maxMinor} \ \ \ref{sec-lin.u} \ \ \
                          {\tt :: Z -> Z -> [[a]] -> [[a]]}

\verb#          # pre-matrix obtained by deleting i-th row and j-th column

\verb#                    \i j rows -> delColumn j (del_n_th i rows) #
\medskip
\\
{\tt maxPartial} \ \ \ref{sec-dprel} \ \ 
                       like \ {\tt minPartial}, \ only for \ maximum
\medskip
\\
{\tt maybePair} \ \ \ref{sec-pair.c} \ \ \ 
               {\tt :: Maybe a -> Maybe b -> Maybe (a,b)}

\verb#                   {(Just x) (Just y) -> Just (x,y);  _ _ -> Nothing}#
\medskip
\\
{\tt mbPropV} \ \ \ref{sec-dprel} \ \ \
                   {\tt :: Maybe PropValue -> PropValue}

\verb#                                     {Just v -> v;  _-> Unknown}#
\medskip
\\
{\tt membership} \ \ \ref{sec-set.o} \ \ \ {\tt :: !(Char -> a -> Bool)}

\verb#      # 
      part of description of a subset $S$: \ algorithm for solving \ $x \in S$
\medskip
\\
\\
{\tt mEPolMul} \ \ \ref{sec-polv.e.i} \ \ \ 
                       {\tt :: Ring a => Mon a -> EPol a -> EPol a}

\verb#               # product of monomial by e-polynomial
\medskip
\\
{\tt mEPVecPMul} \ \ \ref{sec-polv.e.i} \ \ \
               \verb#\m (f,v) -> (mEPolMul m f, map (mPolMul m) v)#
\medskip
\\
{\tt mergeBy} \ \ \ref{sec-dprel} \ \ \
               {\tt :: Comparison a -> [a] -> [a] -> [a]} 

\verb#           # merge lists ordered by given comparison
\medskip
\\
{\tt mergeE} \ \ \ref{sec-dprel} \ \ \
  {\tt :: Comparison a -> [a] -> [a] -> ([a], Char)}

\verb#     # 
          extended merge: \ permutation sign {\tt '+' | '-'} also accumulates
\medskip
\\
{\tt minAhead} \ \ \ref{sec-dprel} \ \ \ {\tt :: Comparison a -> [a] -> [a]}

\verb#              # puts ahead minimum without changing the order of the rest
\medskip
\\
{\tt minBy} \ \ \ref{sec-dprel} \ \ \
            {\tt :: Comparison a -> [a] -> a} \ \ minimum by given comparison
\medskip
\\
{\tt minPartial} \ \ \ref{sec-dprel} \ \ minimum by Partial ordering: 

\verb#       # {\tt :: Eq a => (a -> a -> Maybe CompValue) -> [a] -> Maybe a}

\verb#   # Returns either \ {\tt Nothing} \ or \ {\tt Just m} \ 
         ($m \in xs$, \ $m \leq x$ for all $x \in xs$)
\medskip
\\
{\tt minPrttOfWeight} \ \ \ref{sec-symmf.p.p} \ \ 
                \verb#{\0 -> [];  \n -> [(1,n)]} :: Z -> Partition#

\verb#           # minimal partition for the given weight
\medskip
\\
{\tt minRootOfNatural} \ \ \ref{sec-z.fn} 
\begin{verbatim} 
                 :: Natural -> Maybe (Natural, Natural)
                    -- n              e        r
\end{verbatim} 

  For \ {\tt n > 1} \ finds \ {\tt e} and {\tt r} \ such that \ 
  \verb#n = r^e#, 

   and returns \ {\tt Just (e, r)} \ with the minimal possible \ 
   {\tt e > 1}, if such exists. 

   It such does not exist, it returs \ {\tt Nothing}.
\medskip
\\
{\tt MMaybe} \ \ \ref{sec-dprel} \ \ \ {\tt type MMaybe a = Maybe (Maybe a)}
\medskip
\\
{\tt module} \ \ see \ {\tt LeftModule}
\medskip
\\
{\tt moduleConstrs} \ \ \ref{sec-mod.s} \ \ \ 
                    \verb#:: ![Construction_Submodule r a]#

\verb#                  # data field in Submodule description
\medskip
\\
{\tt moduleGenProps} \ \ \ref{sec-mod.s} \ \ \ 
                     \verb#:: !Properties_SubmoduleGens#

\verb#      # data field in submodule description: properties of generator list
\medskip
\\
{\tt moduleGens} \ \ \ref{sec-mod.s} \ \ \ 
          \verb#:: !(Maybe [a])# \ \ data field in {\tt Submodule} 

\verb#       # description for \ {\tt sM :: Submodule r a} : \ generator list
\medskip
\\
{\tt moduleOpers} \ \ \ref{sec-mod.s} \ \ \ 
                    \verb#:: !(Operations_Submodule r a)# 

\verb#                       # data field in {\tt Submodule} description
\medskip
\\
{\tt moduleProps} \ \ \ref{sec-mod.s} \ \ \ 
                  \verb#:: Properties_Submodule# \ \ 
                  data field in submodule description
\medskip
\\
{\tt moduleRank} \ \ \ref{sec-mod.s} \ \ \ {\tt :: !(InfUnn Z)} \ \ 
                                 data field in Submodule description
\medskip
\\
{\tt moduloBasis} \ \ \ref{sec-linr.m} \ \ \  
                       {\tt :: String -> [a] -> a -> (a, [a])}

\verb#      # 
         operation from {\tt LinSolvRing}: \ zero detaching reduction by ideal

\verb#       # generators. Generalization of Gr\"obner normal form.
\medskip
\\
\\
\\
{\tt ModuloBasisCanonic} \ \ \ref{sec-linr.t} \ \ \ 
                                      \verb#:: Property_LinSolvRing#

\verb#  # 
   {\tt (ModuloBasicCanonic, Yes)} \ means \ {\tt (ModuloBasisDetaching, Yes)}

\verb#  # And \ that the \ {\tt 'c'} \ mode is correct
\medskip
\\
{\tt ModuloBasisDetaching} \ \ \ref{sec-linr.t} \ \ \ 
                                   \verb#:: Property_LinSolvRing#
\medskip
\\
{\tt moduloBasisM} \ \ 
               \ref{sec-mod.ls}, \ref{sec-mod.lsm}, \ref{sec-gx} \ \ 
               operation from \ {\tt LinSolvLModule r a}

\verb#                       :: r  -> String -> [a] -> a -> (a, [r])#

\verb#             # zero detaching reduction of by submodule generators
\medskip
\\
{\tt Mon} \ \ \ref{sec-pol.rp} \ \ \ 
        {\tt type Mon a = (a, PowerProduct)} \ \ \ (multivariate) monomial
\medskip
\\
\verb#monicUPols_overFin# \ \ \ref{sec-upo.i} \ \ \
                         {\tt :: CommutativeRing a => UPol a -> [[UPol a]]}

\verb#   # Univariate monic polynomials over a finite ring breaked to lists of

\verb#   # 
          polynomials of same degree. Domain parameters taken from given sample
\medskip
\\
{\tt monLcm} \ \ \ref{sec-pol.f} \ \ \
       {\tt :: GCDRing a => Mon a -> Mon a -> Mon a} \ \ lcm of monomials:

\verb#          \ (a,p) (b,q) -> case gcD[a,b] of g -> (a*(b/g), ppLcm p q)#
\medskip
\\
{\tt monMul} \ \ \ref{sec-pol.f} \ \ \ 
                         {\tt :: Ring a => a -> Mon a -> Mon a -> [Mon a]}
                       
\verb#                   # product of monomials
\medskip
\\
{\tt monoid} \ \ see \ {\tt AddMonoid, \ MulMonoid}
\medskip
\\
{\tt monomial} \ \ see \ {\tt UMon, \ Mon}
\medskip
\\
{\tt monToSymMon} \ \ \ref{sec-symmf.sp.i} \ \ \ {\tt :: Mon a -> SymMon a}
\medskip
\\
{\tt mPolMul} \ \ \ref{sec-pol.f} \ \ \ 
                              {\tt :: Ring a => Mon a -> Pol a -> Pol a}

\verb#                      # product of monomial by polynomial
\medskip
\\
{\tt mPVecPMul} \ \ \ref{sec-pol.f} \ \ \ 
                          {\tt :: Ring a => Mon a -> PVecP a -> PVecP a}

\verb#              \ m (f,gs) -> (mPolMul m f, map (mPolMul m) gs) #
\medskip
\\
{\tt mtHead} \ \ \ref{sec-mt.f} \ \ \ 
              {\tt (head . head) :: [[a]] -> a \ \ \ matrix(1,1)} \ entity
\medskip
\\
{\tt mtHeight} \ \ \ref{sec-mt.f} \ \ \ 
              {\tt = genericLength :: [[a]] -> Z} \ \ \ height of matrix
\medskip
\\
{\tt mtWidth} \ \ \ref{sec-mt.f} \ \ \ 
                              {\tt :: [[a]] -> Z} \ \ \ width of matrix
\medskip
\\
{\tt mul} \ \ \ref{sec-smg.m} \ \ \ {\tt :: a -> a -> a}

\verb#          # multiplication operation from \ {\tt MulSemigroup} \ category
\medskip
\\
{\tt MulGroup} \ \ \ref{sec-grp.ct} \ \ \ category Multiplicative Group:

\verb#     # {\tt class MulMonoid a => MulGroup a where}

\verb#             baseMulGroup :: a -> Domains1 a -> (Domains1 a, Subgroup a)#
\medskip
\\
\\
\\
{\tt MulMonoid} \ \ \ref{sec-mnd} \ \ category Multiplicative Monoid

\verb#      # {\tt class MulSemigroup a => MulMonoid a}

\verb#      # 
           Presumed is that \ \verb#(unity _)# \ yields the true unity element
\medskip
\\
{\tt MulSemigroup} \ \ \ref{sec-smg.m} \ \ categogy Multiplicative Semigroup:

\verb#   # {\tt class Set a => MulSemigroup a where}

\verb#        baseMulSemigroup...mul...unity_m...inv_m...divide_m...power_m...#
\medskip
\\
{\tt mulSign} \ \ \ref{sec-dprel} \ \ \ 
       {\tt (\ x y -> if x==y then '+' else '-')  :: Char -> Char -> Char}
\medskip
\\
{\tt Multiindex} \ \ \ref{sec-upo.pl} \ \ \ {\tt type Multiindex i = [(i,i)]}
\medskip
\\
{\tt multiplicity} \ \ \ref{sec-rg.fn} \ \ \
                        {\tt :: CommutativeRing a =>  a -> a -> (Z,a)}
                         
\verb#      # 
  $(m, \ y/(x^m))$, \ \ $m$ = multiplicity of $x$ in $y$ \ in a factorial ring.
  
\verb#      # $x, \ y$ \ should be non-zero, \ $x$ \ not invertible.
\medskip
\\
{\tt mUPolMul} \ \ \ref{sec-upo.i} \ \ \ 
         {\tt :: Ring a => UMon a -> UPol a -> UPol a} \ \ product by monomial
\medskip
\\
{\tt neg} \ \ \ref{sec-smg.fn} \ \ \ \verb# :: AddSemigroup a => a -> a#

\verb#        # 
        $x \rightarrow -x$, \ composition of \verb#neg_m# and \ {\tt error}
\medskip
\\
\verb#neg_m# \ \ \ref{sec-smg.a} \ \ \ {\tt :: a -> Maybe a}

\verb#         #  operation of {\tt AddSemigroup} category: opposite element
\medskip
\\
{\tt nextPermut} \ \ \ref{sec-pm.d} \ \ \ {\tt :: [Z] -> Maybe [Z]}
                         
\verb#             # next permutation by lexicographic order
\medskip
\\
{\tt not3} \ \ \ref{sec-dprel} \ \ \ {\tt :: PropValue -> PropValue}

\verb#               Yes -> No,  No -> Yes,  Unknown -> Unknown #
\medskip
\\
{\tt num} \ \ \ref{sec-fr.i} \ \ \ 
   \verb#(\ (n :/ _) -> n) :: Fraction a -> a# \ \ numerator of fraction
\medskip
\\
{\tt numOfPVars} \ \ \ref{sec-pol.f} \ \ \ 
                 {\tt (genericLength . pVars) :: PolLike p => p a -> Z}
\medskip
\\
{\tt numOfStandardTableaux} \ \ \ref{sec-symmf.p.kn}, \cite{Ma} \ \ \ 
             {\tt :: Partition -> Z} \ \ \ number of standard tableaux

\verb#       # 
      = \ $ weight(\lambda)! \ / \ (\prod_{h \in hooks(\lambda)} length(h)) $
 
\verb#       # The program tries to keep intermediate products possibly small.
\medskip
\\
{\tt ofFiniteSet} \ \ \ref{sec-set.fn} \ \ \ 
                  {\tt :: Set a => a -> PropValue} \ \ 
                  ``sample defines a finite base set''

\verb#               \x -> case baseSet x Map.empty of (_,s) -> isFiniteSet s#
\medskip
\\
{\tt OpDescr} \ \ \ref{sec-pars} \ \ \ {\tt type OpDescr = (Z,Z,Z,Z)}

\verb#     # {\tt (left arity, right arity, left precedence, right precedence)}
\medskip
\\
{\tt operation} \ \ (\ref{sec-prp.ske} CT) \ \ {\tt Haskell} class operation. 

\verb#         # DoCon also calls it a {\it category} operation. 
  
\verb#         # Examples: \ \verb#add, +, *, baseRing, fromExpr#
\medskip
\\
\verb#Operations_Ideal# \ \ \ref{sec-il.g} 

\verb#          type Operations_Ideal a = [(OpName_Ideal, Operation_Ideal a)]#
\medskip
\\
\verb#Operations_Submodule# \ \ \ref{sec-mod.s} \ \ \ 
                            \verb#type Operations_Submodule r a =#  

      \verb#              [(OpName_Submodule, Operation_Submodule r a)]#
\medskip
\\
\verb#Operations_Subring# \ \ \ref{sec-rg.sub} \ \ part of {\tt Subring} term

\verb#     type Operations_Subring a = [(OpName_Subring, Operation_Subring a)]#
\medskip
\\
\verb#Operation_Ideal# \ \ \ref{sec-il.g}

\verb#   newtype Operation_Ideal a = IdealRank' (InfUnn Z) deriving (Eq, Show)#
\medskip
\\
\verb#Operation_Submodule# \ \ \ref{sec-mod.s} \ \ \
                           \verb#data Operation_Submodule r a =#

     \verb#                    GradingM' !PPComp !(a -> PPComp) !(a -> [a]) #
\medskip
\\
\verb#Operation_Subring# \ \ \ref{sec-rg.sub} \ \ 
                                         some ring (field) attributes

\verb#        data Operation_Subring a = WithPrimeField' #

\verb#                    {frobenius...dimOverPrime...primeFieldToZ ...}#
\medskip
\\
{\tt OpGroupDescr} \ \ \ref{sec-pars} \ \ fixity \& arities of operation

  {\tt type OpGroupDescr a =}
                   {\tt (a, (Maybe OpDescr, Maybe OpDescr, Maybe OpDescr))}

  (0,r) --- prefix \& arity r (like $-x$), \ \ 
  (l,0) --- postfix ($n!$), \ \ (l,r) --- infix ($x+y$)
\medskip
\\
\verb#OpName_Ideal# \ \ \ref{sec-il.g} 

\verb#          data OpName_Ideal = IdealRank deriving (Eq, Ord, Enum, Show)#
\medskip
\\
\verb#OpName_Submodule# \ \ \ref{sec-mod.s} 

\verb#      data OpName_Submodule = GradingM deriving (Eq, Ord, Enum, Show)#
\medskip
\\
\verb#OpName_Subring# \ \ \ref{sec-rg.sub} 

\verb#        data OpName_Subring = WithPrimeField deriving (Eq,Ord,Enum,Show)#
\medskip
\\
{\tt OpTable} \ \ \ref{sec-pars} \ \ \ {\tt type OpTable a = [OpGroupDescr a]}

to describe formats and arities of operations processed by {\tt infixParse}
\medskip
\\  
{\tt OrderedAddGroup} \ \ \ref{sec-grp.ct} \ \ 
                                     category Ordered Additive Group: 

\verb#     # {\tt class (AddGroup a, OrderedAddMonoid a) => OrderedAddGroup a}

\verb#     # 
          Presumed: base {\tt AddGroup} possesses {\tt (IsOrderedSubgroup,Yes)}
\medskip
\\
{\tt OrderedAddMonoid} \ \ \ref{sec-mnd} \ \ 
                      category Ordered Additive Monoid: 

\verb#       # 
       {\tt class (OrderedAddSemigroup a, AddMonoid a) => OrderedAddMonoid a}
\medskip
\\
{\tt OrderedAddSemigroup} \ \ \ref{sec-smg.a} \ \   
                          category Ordered Additive Semigroup:

\verb#     # 
   {\tt class (OrderedSet a, AddSemigroup a) => OrderedAddSemigroup a}
  
\verb#     # 
  Presumed: base {\tt AddSemigroup} possesses {\tt (IsOrderedSubsemigroup,Yes)}
\medskip
\\
\\
\\
{\tt OrderedField} \ \ \ref{sec-fld} \ \ category Ordered Field:

\verb#           # {\tt class (RealField a, OrderedRing a) => OrderedField a}
\medskip
\\
{\tt OrderedMulGroup} \ \ \ref{sec-grp.ct} \ \ 
                            category Ordered Multiplicative Group: 

\verb#      # {\tt class (OrderedMulMonoid a,MulGroup a) => OrderedMulGroup a}

\verb#      # Presumed:  base {\tt MulGroup} is as an ordered group
\medskip
\\
{\tt OrderedMulMonoid} \ \ \ref{sec-mnd} \ \ 
                        category Ordered Multiplicative Monoid: 

\verb#      # 
        {\tt class (OrderedMulSemigroup a, MulMonoid a) => OrderedMulMonoid a}
\medskip
\\
{\tt OrderedMulSemigroup} \ \ \ref{sec-mnd} \ \ 
                  category Ordered Multiplicative Semigroup:

\verb#       # {\tt class MulSemigroup a => OrderedMulSemigroup a}

\verb#       # 
         Presumed: {\tt bS = base MulSemigroup} is an ordered subsemigroup
\medskip
\\
{\tt OrderedRing} \ \ \ref{sec-gcd} 

\verb#       # 
       {\tt class (CommutativeRing a, OrderedAddGroup a) => OrderedRing a}

\verb#       # Presumed:  base ring possesses {\tt (IsOrderedRing, Yes)}
\medskip
\\
{\tt OrderedSet} \ \ \ref{sec-ord} \ \ \ 
                         {\tt class (Ord a, Set a) => OrderedSet a}

\verb#       # 
      Presumed: on base set, \verb#compare_m# possesses {\tt (OrderIsTotal,Yes)}

\verb#       # and agrees with \ {\tt compare}: \ 
                    \verb#(compare_m x y)==(Just (compare x y))#
\medskip
\\ 
{\tt OrderIsArtin} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet#

\verb#     # 
       ``subset contains no infinite increasing sequence by \verb#compare_m#''
\medskip
\\
{\tt OrderIsNoether} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet#

\verb#            # ``\verb#compare_m # is Noetherian on this subset''
\medskip
\\
{\tt OrderIsTotal} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet#

\verb#             # ``\verb#compare_m # never returns Nothing on this subset''
\medskip
\\                
{\tt OrderIsTrivial} \ \ \ref{sec-set.o} \ \ \ \verb#:: Property_OSet#

\verb#     # 
     ``\verb#compare_m # coincides with {\tt compareTrivially} on this subset''
\medskip
\\
{\tt orderModuloNatural} \ \ \ref{sec-z.fn} 
\begin{verbatim} 
                 :: Natural -> Integer -> Natural
                    -- r       a
\end{verbatim} 
\verb#     min [k > 0 | a^k = 1 (mod r)]# \ \ --- 
for \ {\tt r > 1, \ \ r} \ mutually prime with \ {\tt a}.
\medskip
\\
{\tt or3} \ \ \ref{sec-dprel} \ \ \
                           {\tt :: PropValue -> PropValue -> PropValue}

\verb#         \Yes _ -> Yes,  \_ Yes -> Yes,  \No No -> No,  \_ _ -> Unknown#
\medskip
\\
{\tt OSet} \ \ \ref{sec-set.o} \ \ constructor for subset description
\medskip
\\
{\tt osetBounds} \ \ \ref{sec-set.o} \ \ \ 
                    {\tt :: !(MMaybe a, MMaybe a, MMaybe a, MMaybe a)}

\verb#              # data field in subset description
\medskip
\\
{\tt osetCard} \ \ \ref{sec-set.o} \ \ \ {\tt :: !(InfUnn Z)}

\verb#                   # data field in subset description: cardinality
\medskip
\\
{\tt osetConstrs} \ \ \ref{sec-set.o} \ \ \ 
      \verb#:: ![Construction_OSet a]# \ \ data field in subset term
\medskip
\\
{\tt osetList} \ \ \ref{sec-set.o} \ \ \ {\tt :: Maybe [a]} 
               
\verb#             # data field in subset description: \ finite listing.

\verb#             # {\tt Nothing} \ means the listing is unknown.
\medskip
\\
{\tt osetPointed} \ \ \ref{sec-set.o} \ \ \ 
                      {\tt :: !(MMaybe a)} \ \ data field in subset X :

\verb#   # 
     chosen element in X. {\tt Just (Just e)} means {\tt e} chosen from X, 

\verb#   # {\tt Just Nothing} --- X is empty, \ \ 
           {\tt Nothing} --- {\tt DoCon} cannot find element in X
\medskip
\\
{\tt osetProps} \ \ \ref{sec-set.o} \ \ \ 
                \verb#:: Properties_OSet# \ \ data field in subset term
\medskip
\\
{\tt osetSample} \ \ \ref{sec-set.o} \ \ \ {\tt :: !a} \ \ 
                    data field in subset term: sample data for type
\medskip
\\
{\tt Pair} \ \ \ref{sec-pair} \ \ functor {\tt (,)} of direct product.

\verb#     # 
         for {\tt a, b} \ldots {\tt DoCon} provides {\tt (a,b)} with the instances

\verb#     # of \ {\tt Set, AddSemigroup, \ldots, LinSolvRing}
\medskip
\\
{\tt pairNeighbours} \ \ \ref{sec-dprel} \ \ \ {\tt :: [a] -> [(a,a)]} 

                   Example: \ {\tt [1,2,3,4,5] -> [(1,2),(3,4)]}
\medskip
\\
{\tt ParenTable} \ \ see \ref{sec-pars}, \verb#OpTab_.hs# \ \ \ 
                                   {\tt type ParenTable a = [(a,a)]}

\verb#         # describes all the allowed parentheses pairs for parsing.

\verb#         # A parenthesis may be any lexeme from \ {\tt a}.
\medskip
\\
{\tt parse} \ \ \ref{sec-prp.pars}, \ref{sec-pars} 

\verb#     # {\tt smParse e} \ parses from string to domain element by a 

\verb#     # 
  sample {\tt e}, \ \ {\tt smParse} composes with \ {\tt infixParse, fromExpr}
\medskip
\\
{\tt Partition} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt type Partition = [(Z,Z)]}

\verb#    # A partition known from combinatorics. It is either \ {\tt []} \ or 

\verb#    # 
         $\lambda = [(j_1,m_1),\ldots,(j_k,m_k)], \ \ j_1 > \ldots > j_k > 0,$
         \ \ (or \ $(j_1^{m_1} \ldots j_k^{m_k})$)
\medskip
\\
{\tt Partition module} \ \ see~\ref{sec-dme}, \ref{sec-symmf.p} \ \ 
                       {\tt DoCon} module exporting items for partitions
\medskip
\\
{\tt partitionN} \ \ \ref{sec-dprel} \ \ \ 
                           {\tt :: (a -> a -> Bool) -> [a] -> [[a]]}

\verb#    # breaks list into groups by the given equivalence relation.

\verb#    #
    For the equivalent items being {\it neighbours} apply better {\tt groupBy}
\medskip
\\
{\tt pCDiv} \ \ \ref{sec-pl} \ \ \
            {\tt :: CommutativeRing a => p a -> a -> Maybe (p a)}

\verb#      # operation from {\tt PolLike} : divide a pol-like thing by coefficient
\medskip
\\
{\tt pCoef} \ \ \ref{sec-pl} \ \ \ 
                            {\tt :: CommutativeRing a => p a -> [Z] -> a}
     
\verb#       # 
      operation of {\tt PolLike} class: coefficient of given power product.

\verb#       # 
        {\tt c = pCoef f js} \ \ \ For {\tt UPol}, \ {\tt js = [j]} \ldots
\medskip
\\
{\tt pCoefs} \ \ \ref{sec-pl} \ \ \ {\tt :: p a -> [a]} \ \ 
                                    operation from {\tt PolLike}: 

\verb#          # coefficients listed in same order as monomials;

\verb#          # for {\tt RPol}, the order is ``depth first''
\medskip
\\
{\tt pCont} \ \ \ref{sec-pl} \ \ operation from {\tt PolLike} class: 

  {\tt (gcD . pCoefs) :: (GCDRing a, PolLike p) => p a -> a} \ \ 
                                              content of pol-like data
\medskip
\\
{\tt pDeriv} \ \ \ref{sec-pl} \ \ \
                {\tt :: CommutativeRing a => Multiindex Z -> p a -> p a}

  Operation from {\tt PolLike} constructor class: derivative by multiindex.

  Example: for $[x_1,x_2,x_3,x_4]$, \ 
  {\tt pDeriv [(2,3),(4,2)]} \ $ \leftrightarrow \ (d/dx_2)^3 (d/dx_4)^2 $
\medskip
\\
{\tt pDivRem} \ \ \ref{sec-pl} \ \ \
                 {\tt :: CommutativeRing a => p a -> p a -> (p a, p a)}

  Operation from {\tt PolLike} constructor class: division with remainder.

  For \ $k[x], \ k$ a field, \ it is Euclidean division.
\medskip
\\
{\tt permGroupCharColumn} \ \ \ref{sec-symmf.p.ch} 

\verb#     # {\tt :: Partition -> [Partition] -> (Map.Map Partition Z, [Z])}

\verb#     # column of the character values obtained by \ {\tt permGroupCharValue}
\medskip
\\ 
{\tt permGroupCharTMinor} \ \ \ref{sec-symmf.p.ch} \ \ \ 
                              {\tt :: [Partition] -> [Partition] -> [[Z]]}

  transposed minor of matrix of Irreducible Character Values \ 
  $cha(w)(\lambda, \rho)$

  for permutation group \ $S(w)$. \ \ See also {\tt permGroupCharColumn}
\medskip
\\
{\tt permGroupCharValue} \ \ \ref{sec-symmf.p.ch} \ \ 
                         Irreducible character values for $S(n)$. 

\verb#     # {\tt :: Map.Map Partition Z -> Partition -> Partition ->}

\verb#                                              (Map.Map Partition Z, Z)#
\medskip
\\
{\tt Permut} \ \ see~\ref{sec-dme}, \ref{sec-symmf}

\verb#     # 
       {\tt DoCon} module exporting items for symmetric functions (sym-polynomials)  
\medskip
\\
{\tt Permutation} \ \ \ref{sec-pm.p} \ \ \
                      {\tt newtype Permutation = Pm [Z] deriving(Eq,Read)}

\verb#     # 
      In \ {\tt Pm xs} \ {\tt xs} should be non-empty and free of repetitions.

\verb#     # The base domain of such sample is \ $S( length(n) )$.
\medskip
\\
{\tt permutCycles} \ \ \ref{sec-pm.d} \ \ \ 
         {\tt :: Permutation -> [[Z]]} \ \ decomposes permutation to cycles

\verb#            # Example: \ {\tt Pm [2,1,7,5,3] -> [[2,1],[7,3],[5]]}
\medskip
\\
{\tt permutRepr} \ \ \ref{sec-pm.d} \ \ \ 
                               \verb#(\ Pm xs -> xs) :: Permutation -> [Z]#
\medskip
\\
{\tt permutSign} \ \ \ref{sec-pm.d} \ \ \ {\tt :: Permutation -> Char} \ \ 
                                permutation sign: {\tt '+'} or {\tt '-'}
\medskip
\\
{\tt pFreeCoef} \ \ \ref{sec-pl} \ \ \ 
                               {\tt :: CommutativeRing a => p a -> a}

\verb#       # operation from {\tt PolLike} constructor class: free coefficient
\medskip
\\
{\tt pFromVec} \ \ \ref{sec-pl} \ \ \ 
                          {\tt :: CommutativeRing a => p a -> [a] -> p a}

operation from {\tt PolLike} constructor class (so far, only for {\tt UPol}):

  convert (dense) vector to pol-like data of the given sample.
\medskip
\\
{\tt pHeadVar} \ \ \ref{sec-pl} \ \ \  
                        {\tt :: (PolLike p, Set a) => p a -> PolVar}

  \verb#               \f -> case pVars f of {v:_ -> v;  _ -> error...} #
\medskip
\\
{\tt PIR} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Property_Subring# \ \ \   
                                        ``is a principal ideal ring''        
\medskip
\\
{\tt PIRChinIdeal} \ \ (see~\ref{sec-il.e}, {\tt eucIdeal}) \ \  
                   Special ideal representation,

\verb#     # for a principle ideal ring, suitable for Chinese remainder method:

\verb#     # 
      {\tt \ldots PIRChinIdeal \{pirCIBase...pirCICover...pirCIOrtIdemps...\}}
\medskip
\\  
{\tt pirCIBase} \ \ \ref{sec-il.e} \ \ \ {\tt :: !a} 

\verb#      # 
         data field in ideal \ {\tt iI :: PIRChinIdeal a} : \ base for {\tt iI}
\medskip
\\
{\tt pirCICover} \ \ \ref{sec-il.e} \ \ \ {\tt :: ![a]}

\verb#     #
    data field in ideal \ {\tt iI :: PIRChinIdeal a}. \ \ contains \ {\tt bs} 

\verb#     # 
     such that \ {\tt iI =} $\cap_{i \ldots} b_i, \ \ (b_i)+(b_j) = (1)$ \ldots
\medskip
\\
{\tt pirCIFactz} \ \ \ref{sec-il.e} \ \ \ 
             {\tt :: !(Factorization a)} \ \ \ factorization of a base:

\verb#              # a data field in ideal \ {\tt iI :: PIRChinIdeal a} 
\medskip
\\
{\tt pirCIOrtIdemps} \ \ \ref{sec-il.e} \ \ \ 
                {\tt :: ![a]} \ \ data field in {\tt iI :: PIRChinIdeal a}
  
\verb#     # 
        Lagrange orthogonal idempotents \ $ e_i, \ \ 1 = \sum_{i = 1}^n e_i, $

\verb#     # 
    $ e_i \in (b_i), \ \ [b_1,\ldots,b_n] $ \ \ is decomposition of ideal base
\medskip
\\
{\tt pIsConst} \ \ \ref{sec-pl} \ \ \ 
                {\tt :: CommutativeRing a => p a -> Bool}

         ``is a constant pol-like thing'': 
         operation from {\tt PolLike} constructor class
\medskip
\\
{\tt pLexComp} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt :: PrttComp}

\verb#            # inverse lexicographical ordering on partitions
\medskip
\\
{\tt pLexComp'} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt :: PrttComp} \ \ 
                    In \cite{Ma} it is denoted as \ \ $Ln\prime$ \ (?):

\verb#            # conjugated to {\tt pLexComp} comparison.
\medskip
\\
{\tt pMapCoef} \ \ \ref{sec-pl} \ \ \
               {\tt :: AddGroup a => Char -> (a -> a) -> p a -> p a}

  Operation from {\tt PolLike} constructor class: \ 
  maps {\tt f} to each coefficient.

  {\tt mode = 'r'} \ means to detect and delete appeared zero monomials
\medskip
\\
{\tt pMapPP} \ \ \ref{sec-pl} \ \ \ 
                 {\tt :: AddGroup a => ([Z] -> [Z]) -> p a -> p a}

\verb#    # 
      Operation from {\tt PolLike} construtor class: maps f to each exponent.
 
\verb#    # It does not reorder the monomials, nor sums similar ones.
\medskip
\\
{\tt Pol} \ \ \ref{sec-pol.rp},
              (\ref{sec-prp.ske} DF), \ref{sec-prp.skco.df}
              (multivariate) polynomial 

\verb#    # 
          {\tt data Pol a = Pol ![Mon a] !a !PPOrdTerm ![PolVar] !(Domains1 a)}

  {\tt Pol mons c o vars aD} \ 
  has monomial list {\tt mons} sorted by pp-ordering \ {\tt o}; \ldots
\medskip
\\
{\tt polDegs} \ \ \ref{sec-pol.f} \ \ \ {\tt :: [Z] -> Pol a -> [Z]} \ \ 
                                        degrees in each variable

\verb#    # Returns given value for zero polynomial. \ \ Example: \ for 

\verb#    # 
         {\tt f = $x^2 z + x z^4 + 1 \in Z[x,y,z],$ \ \ polDegs [] f = [2,0,4]}
\medskip
\\
{\tt PolLike} \ \ \ref{sec-pl} \ \ \ {\tt class Dom p => PolLike p \ldots} 

\verb#       # Constructor class joining \ {\tt UPol, Pol, RPol, EPol, SymPol}
\medskip
\\
{\tt Pol module} \ \ \ref{sec-dme}, \ref{sec-pol} \ \ 
                 {\tt DoCon} module exporting items for polynomials  
\medskip
\\
{\tt polMons} \ \ \ref{sec-pol.rp} \ \ \ {\tt :: Pol a -> [Mon a]} \ \ \
                                           extracts monomial list
\medskip
\\
{\tt polNF} \ \ (\ref{sec-pol.a.gr} \{n\}) \ \ 
                               Gr\"obner reduction by polynomials

\verb#    # 
    {\tt :: EuclideanRing a => String -> [Pol a] -> Pol a -> (Pol a, [Pol a])}

\verb#    # It is ideal detachig for a Gr\"obner basis \cite{Mo}
\medskip
\\
\verb#polNF_e# \ \ \ref{sec-polv.e.gr} \ \ 
                              {\tt polNF} generalized for e-polynomials

{\tt :: EuclideanRing a => String -> [EPol a] -> EPol a -> (EPol a, [Pol a])}
\medskip
\\
{\tt polPermuteVars} \ \ \ref{sec-pol.f} \ \ \
                     {\tt :: AddGroup a => [Z] -> Pol a -> Pol a}

\verb#    # 
   Substitution for polynomial variables given by permutation at {\tt [1..n]}. 

\verb#    # Monomial list reorderes, but the variable list remains.
\medskip
\\
{\tt PolPol} \ \ \ref{sec-pol.f} \ \ \ {\tt type PolPol a = Pol (Pol a)}
\medskip
\\
{\tt polPPComp} \ \ \ref{sec-pol.rp} \ \ \ 
                                   {\tt (ppoComp . pPPO) :: Pol a -> PPComp}   

\verb#           # extracts power product ordering function
\medskip
\\                
{\tt polPPOId} \ \ \ref{sec-pol.rp} \ \ \ 
                                  {\tt (ppoId . pPPO) :: Pol a -> PPOId}

\verb#          # extracts power product ordering term identifier
\medskip
\\
{\tt polPPOWeights} \ \ \ref{sec-pol.rp} \ \ \ 
                              {\tt (ppoWeights . pPPO) :: Pol a -> [[Z]]}

\verb#           # extracts power product ordering term weights 
\medskip
\\
{\tt polSubst} \ \ \ref{sec-pol.f} \ \ \ 
                               Substitute polynomials for variables

{\tt :: CommutativeRing a => Char -> Pol a -> [Pol a] -> [[Pol a]] -> Pol a}
\medskip
\\
{\tt polToEPol} \ \ \ref{sec-polv.e.i} \ \ \ 
                                   {\tt :: Z -> EPPOTerm -> Pol a -> EPol a}

   embed pol to e-pol of given constant coordinate No i and epp 
   ordering term:

         \verb#      \ i o f -> EPol [(c, (i,p)) | (c,p) <- polMons f] o f #
\medskip
\\
{\tt polToHomogForms} \ \ \ref{sec-pol.f} \ \ 
                                  homogeneous forms of polynomial

\verb#     # 
        {\tt :: (AddGroup a, Eq b) => (PowerProduct -> b) -> Pol a -> [Pol a]}
\medskip
\\
{\tt PolVar} \ \ \ref{sec-upo.p} \ \ \ type PolVar = String \ \ 
                     type of polynomial variable (indeterminate)
\medskip
\\
{\tt polynomial} \ \ \ref{sec-pol} 

\verb#     # {\tt DoCon} represents a polynomial in \ {\tt UPol, Pol, RPol} \ forms, 

\verb#     # joining these kinds into the {\tt PolLike} constructor class
\medskip
\\
{\tt power} \ \ \ref{sec-smg.m} \ \ \ {\tt :: MulSemigroup a => a -> Z -> a}

     \verb#          (^n)# \ as composed \ \verb#power_m# \ and {\tt error}
\medskip
\\
{\tt PowerProduct} \ \ \ref{sec-pp} \ \ \ {\tt type PowerProduct = Vector Z}

\verb#     # 
       Power product for polynomial. {\tt DoCon} uses that its instance of an ordered

\verb#     # additive group. Admissible comparison functions are related to it.
\medskip
\\ 
\verb#power_m# \ \ \ref{sec-smg.m} \ \ \ {\tt :: a -> Z -> Maybe a}

\verb#    # 
        operation \verb#(^n)# from {\tt MulSemigroup} category. \  Examples: 

\verb#    # 
      {\tt (2::Z) 3 -> Just 8,  2 (-3) -> Nothing,  (1:/2) (-3) -> Just (8:/1)}
\medskip
\\
{\tt PPCoefRelationMode} \ \ \ref{sec-pol.f} 

\verb#      # 
           {\tt data PPCoefRelationMode = HeadPPRelatesCoef | TailPPRelatesCoef

\verb#                                                      # deriving (...)}
\medskip
\\
{\tt PPComp} \ \ \ref{sec-pp}, \ref{sec-pp.d} \ \ \
             {\tt type PPComp = Comparison PowerProduct}

\verb#      # Power product comparison. A part of {\tt PPOrdTerm},
 
\verb#      # and {\tt PPOrdTerm} is a part of polynomial data ({\tt Pol})
\medskip
\\
{\tt ppComplement} \ \ \ref{sec-pp.d} 

\verb#(\ u v -> (ppLcm u v)-u) :: PowerProduct -> PowerProduct -> PowerProduct#
\medskip
\\
\verb#ppComp_blockwise# \ \ \ref{sec-pp.d} \ \ compares power products

\verb#  # by the direct sum of two given comparisons:

\verb#  #
    {\tt :: Z -> PPComp -> PPComp -> PowerProduct -> PowerProduct -> CompValue}
\medskip
\\
{\tt ppDivides} \ \ \ref{sec-pp.d} \ \ \ 
                        {\tt :: PowerProduct -> PowerProduct -> Bool}

    \verb#           \p q -> all (>= 0) (vecRepr (q-p))# \ \ \ ``p divides q''
\medskip
\\              
{\tt ppLcm} \ \ \ref{sec-pp.d} \ \ \ 
                      {\tt :: Ord a => Vector a -> Vector a -> Vector a}
 
    Lcm of power products. \ 
    Example: \ {\tt (Vec [1,0,2]) (Vec [0,1,3]) -> Vec [1,1,3]}
\medskip
\\
{\tt ppMutPrime} \ \ \ref{sec-pp.d} \ \ \ 
                     {\tt :: PowerProduct -> PowerProduct -> Bool}

\verb#       # ``power products are mutually prime'' 
\medskip
\\
{\tt ppoComp} \ \ \ref{sec-pp.o} \ \ \
       {\tt = tuple32 :: PPOrdTerm -> PPComp} \ \ extracts pp comparison
\medskip
\\
{\tt ppoId} \ \ \ref{sec-pp.o} \ \ \ 
            {\tt = tuple31 :: PPOrdTerm -> PPOId} \ \ extracts identifier
\medskip
\\
{\tt PPOId} \ \ \ref{sec-pp.o} \ \ \ {\tt type PPOId = (String, Z)}
\medskip
\\
{\tt ppoWeights} \ \ \ref{sec-pp.o} \ \ \ 
                 {\tt = tuple33 :: PPOrdTerm -> [[Z]]} \ \ extract weights
\medskip
\\
{\tt pPPO} \ \ \ref{sec-pl} \ \ \ {\tt :: p a -> PPOrdTerm} 

\verb#  # operation from {\tt PolLike} constructor class: 
          pp ordering description
\medskip
\\
{\tt PPOrdTerm} \ \ \ref{sec-pp.o} \ \ \ 
                          {\tt type PPOrdTerm = (PPOId, PPComp, [[Z]])}

\verb#     # The power product ordering description (term) \ {\tt (id, cp, ws)} 

\verb#     # consists of identifier, pp comparison function, list of weights
\medskip
\\
{\tt ppToPrtt} \ \ \ref{sec-symmf.p.p} \ \ \ 
       {\tt :: PowerProduct -> Partition} \ \ power product to partition:

\verb#         # {\tt filter ((/=0) . snd) . reverse . zip [1..] . vecRepr}
\medskip
\\
{\tt prevHWBand} \ \ \ref{sec-symmf.p.p} \ \ \
                 {\tt :: Char -> Partition -> HBand -> Maybe HBand}

\verb#   # Previous (to the given) h-w-band. \ 
               Ordering and mode \ are as in \ {\tt maxHWBand}
\medskip
\\ 
{\tt prevSWHook} \ \ \ref{sec-symmf.p.p} \ \ \ 
                            {\tt :: Partition -> SHook -> Maybe SHook}

\verb#       # Previous sw-hook to the given one. \ The ordering is so that 

\verb#       # the greater is the hook which head starts higher.
\medskip
\\
\verb#prevPrttOfN_lex# \ \ \ref{sec-symmf.p.p} \ \ \ 
                       {\tt :: Partition -> Maybe Partition}

\verb#       # 
         Partition of weight \ {\tt k = |pt|} \ previous to \ {\tt pt} \ in

\verb#       # 
        {\tt pLexComp} order, \ {\tt Nothing} \ for {\tt [(1,k)]} or {\tt []}.
\medskip
\\
{\tt primeFieldToRational} \ \ \ref{sec-rg.sub} \ \ \ 
          {\tt :: a -> Fraction Z} \ \ \ Part of {\tt WithPrimeField} 

\verb#     # term of \ \verb#Operation_Subring#. \ \ For \ characteristic = 0, 

\verb#     # 
     it should present isomorphism \ Prime field $\rightarrow$ Rational numbers
\medskip
\\
{\tt primeFieldToZ} \ \ \ref{sec-rg.sub} \ \ \ 
                    {\tt :: a -> Z} \ \ \ Part of \ {\tt WithPrimeField} 

\verb#   # 
   term of \verb#Operation_Subring#. \ For \ characteristic = $p > 0$, the

restriction of {\tt primeFieldToZ} to prime field should be
inverse to {\tt fromi} on {\tt [0..p-1]}
\medskip
\\
{\tt primitiveOverPrime} \ \ \ref{sec-rg.sub} \ \ \ 

\verb#     # {\tt = (powers, mp, toPol) :: ([a], [UMon a], a -> [UMon a])}

\verb#     # 
        Part of \ {\tt WithPrimeField} \ term of \ \verb#Operation_Subring#.
\medskip
\\
{\tt Primary} \ \ \ref{sec-il.g} \ \ \ \verb#:: Property_Ideal# \ \ 
                                                 ``is a primary ideal''
\medskip
\\
{\tt Prime} \ \ \ref{sec-il.g} \ \ \ \verb#:: Property_Ideal# \ \ 
                                                   ``is a prime ideal''
\medskip
\\
{\tt primes} \ \ \ref{sec-ftr} \ \ \ {\tt :: a -> [a]} \ \ 
                           operation from {\tt FactorizationRing}:

\verb#       # infinite list of primes, free of repetitions, 
 
\verb#       # built from given sample element
\medskip
\\
{\tt product1} \ \ \ref{sec-dprel} \ \ {\tt :: Num a => [a] -> a} 

\verb#       # Product of a non-empty list of elements. 

\verb#       # 
       For a non-empty list, use \ {\tt product1} \ rather than \ {\tt product}
\medskip
\\
\verb#Properties_EucRing# \ \ \ref{sec-euc} 

   \verb#          type Properties_EucRing = [(Property_EucRing, PropValue)] #
\medskip
\\
\verb#Properties_FactrRing# \ \ \ref{sec-ftr} 

 \verb#         type Properties_FactrRing = [(Property_FactrRing, PropValue)]#
\medskip
\\
\verb#Properties_GCDRing# \ \ \ref{sec-gcd} 

    \verb#         type Properties_GCDRing = [(Property_GCDRing, PropValue)]#
\medskip
\\
\verb#Properties_LinSolvModule# \ \ \ref{sec-mod.lsm}

\verb#  type Properties_LinSolvModule = [(Property_LinSolvModule, PropValue)]#
\medskip
\\
\verb#Properties_LinSolvRing# \ \ \ref{sec-linr.t} 

\verb#      type Properties_LinSolvRing = [(Property_LinSolvRing, PropValue)]#
\medskip
\\
\verb#Properties_OSet# \ \ \ref{sec-set.o} \ \ \ 
                \verb#type Properties_OSet = [(Property_OSet, PropValue)]#
\medskip
\\
\verb#Properties_Submodule# \ \ \ref{sec-mod.s} 

 \verb#         type Properties_Submodule = [(Property_Submodule, PropValue)]#
\medskip
\\
\verb#Properties_SubmoduleGens# \ \ \ref{sec-mod.s} 

\verb#   type Properties_SubmoduleGens = [(Property_SubmoduleGens, PropValue)]#
\medskip
\\
{\tt property} \ \ \ref{sec-prp.skco.pr} \ \ An attribute stored in the 

\verb#     # property list of domain description together with its value.  

\verb#     # 
      {\tt DoCon} relates to each category a finite list of most valuable properties.
\medskip
\\
\verb#Property_EucRing# \ \ \ref{sec-euc} 

  \verb#         data Property_EucRing = Euclidean | DivRemCan | DivRemMin#
 
  \verb#                                 deriving (Eq, Ord, Enum, Show)#
\medskip
\\
\verb#Property_FactrRing# \ \ \ref{sec-ftr} 

\verb#  data Property_FactrRing = WithIsPrime | WithFactor | WithPrimeList#

\verb#                            deriving (Eq, Ord, Enum, Show)#
\medskip
\\
\verb#Property_GCDRing# \ \ \ref{sec-gcd} \ \ \ 
                        \verb#data Property_GCDRing =#

\verb#            # {\tt WithCanAssoc | WithGCG deriving (Eq,Ord,Enum,Show)}
\medskip
\\
\verb#Property_Ideal# \ \ \ref{sec-il.g} \ \ \
                      \verb#data Property_Ideal = #

\verb#             IsMaxIdeal | Prime | Primary  deriving (Eq,Ord,Enum,Show)#
\medskip
\\
\verb#Property_IdealGen# \ \ \ref{sec-il.g} 

\verb#       data Property_IdealGen = IsGxBasis deriving (Eq,Ord,Enum,Show)#

\verb#Property_LinSolvModule# \ \ \ref{sec-mod.lsm} \ \ \ 
                                   \verb#data Property_LinSolvModule =#

\verb#  IsCanAssocModule | ModuloBasisDetaching_M | ModuloBasisCanonic_M#

\verb#  | WithSyzygyGens_M | IsGxModule  deriving(Eq,Ord,Enum,Show)#
\medskip
\\ 
\verb#Property_LinSolvRing# \ \ \ref{sec-linr.t} \ \ \
                                      \verb#data Property_LinSolvRing =#

\verb#  ModuloBasisDetaching | ModuloBasisCanonic | WithSyzygyGens | # 

\verb#  IsGxRing  deriving(Eq, Ord, Enum, Show) #
\medskip
\\
\verb#Property_OSet# \ \ \ref{sec-set.o} \ \ \
                                           \verb#data Property_OSet =#

\verb#  Finite | FullType | IsBaseSet | OrderIsTrivial | OrderIsTotal |#

\verb#  OrderIsNoether | OrderIsArtin   deriving(Eq, Ord, Enum, Show) #
\medskip
\\
\verb#Property_Subgroup# \ \ \ref{sec-grp.sb} \ \ \ 
                                  \verb#data Property_Subgroup =#

\verb#  IsCyclicGroup | IsPrimeGroup | IsNormalSubgroup | IsMaxSubgroup# 

\verb#  | IsOrderedSubgroup  deriving (Eq, Ord, Enum, Show)#
\medskip
\\
\verb#Property_Submodule# \ \ \ref{sec-mod.s} \ \ \ 
                                       \verb#data Property_Submodule =#

\verb# IsFreeModule | IsPrimeSubmodule | IsPrimarySubmodule | #

\verb# | IsMaxSubmodule | HasZeroDivModule | IsGradedModule deriving...#
\medskip
\\
\verb#Property_SubmoduleGens# \ \ \ref{sec-mod.s} \ \ \ 
                                  \verb#data Property_SubmoduleGens =#

\verb#       IsFreeModuleBasis | IsGxBasisM  deriving(Eq,Ord,Enum,Show)#
\medskip
\\
\verb#Property_Subring# \ \ \ref{sec-rg.pr} \ \ \
                                  \verb#data Property_Subring =#

\verb#    IsField | HasZeroDiv | HasNilp | IsPrimaryRing | Factorial |#

\verb#    PIR | IsOrderedRing | IsRealField | IsGradedRing deriving...#
\medskip
\\ 
\verb#property_Subring_list# \ \ \ref{sec-rg.fn} \ \ \ 
                                            \verb#:: [Property_Subring]#
\medskip
\\
\verb#Property_Subsemigroup# \ \ \ref{sec-smg.sub} \ \ \ 
                                    \verb#data Property_Subsemigroup =#

\verb#  Commutative | IsCyclicSemigroup | IsGroup | IsMaxSubsemigroup#

\verb#  | IsOrderedSubsemigroup  deriving (Eq, Ord, Enum, Show) #
\medskip
\\
{\tt PropValue} \ \ \ref{sec-dprel} 

{\tt data PropValue = Yes | No | Unknown deriving (Eq,Ord,Enum,Show,Read)}
\medskip
\\
{\tt propVOverList} \ \ \ref{sec-dprel} 

\verb#     # 
        {\tt :: Eq a => [(a,PropValue)] -> a -> PropValue -> [(a,PropValue)]}

\verb#     # updates property value in association list
\medskip
\\
{\tt propVToBool} \ \ \ref{sec-dprel} \ \ \ 
                  \verb#(Yes -> True, _ -> False) :: PropValue -> Bool#
\medskip
\\
{\tt PrttComp} \ \ \ref{sec-symmf.p.p} \ \ \
                 {\tt type PrttComp = Comparison Partition}

\verb#            # {\tt PPComp} analog for partitions 
\medskip
\\
{\tt prttLength} \ \ \ref{sec-symmf.p.p} \ \ \
                     {\tt (sum . map snd) :: Partition -> Z}

\verb#     # 
        $l(\lambda)$ = height of Young diagram = number of ``actual variables''
\medskip
\\
\verb#prttLessEq_natural# \ \ \ref{sec-symmf.p.p} \ \ \
                          {\tt :: Partition -> Partition -> Bool}

\verb#     # natural partial ordering on partitions: \ 
             $\lambda \leq \mu \ \Longleftrightarrow$ 
 
\verb#     # for each $i > 0$ \ 
           $ sum_{j = 1}^i \lambda_j \ \leq \ sum_{j = 1}^i \mu_j $ \ 
         (in expanded form)
\medskip
\\
{\tt PrttParamMatrix} \ \ \ref{sec-symmf.t.i} \ \ \
                    {\tt type PrttParamMatrix a = Map.Map Partition [a]}

\verb#       # partition-parameterized matrix over {\tt a} (ptp-matrix)

\verb#       # is a table of pairs \ {\tt (Partition, Row)}
\medskip
\\
{\tt prttsOfW} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt :: Partition -> [Partition]}

\verb#      # 
         all partitions of the same weight, starting from \ {\tt pt}, \ listed 

\verb#      # 
        in {\tt pLexComp} -decreasing order. \ {\tt (pt -> [pt,\ldots,minPt])} 
\medskip
\\
{\tt prttToPP} \ \ \ref{sec-symmf.p.p} \ \ \ 
                                {\tt :: Z -> Partition -> PowerProduct}

\verb#       # converts partition to power product of given \ $length \geq l$

\verb#       # 
       Example: \ $ 7 \ [5^2, 4, 2^3] \rightarrow $ \ {\tt Vec [0,3,0,1,2,0,0]}
\medskip
\\ 
{\tt prttUnion} \ \ \ref{sec-symmf.p.p} \ \ \
                {\tt :: Partition -> Partition -> Partition} \ \ \ union,
   
\verb#  # with repeated diagram lines copied. 
         Example: \verb#[3,2,1] [3*2] -> [3*3,2,1]#
\medskip
\\
{\tt prttWeight} \ \ \ref{sec-symmf.p.p} \ \ \ 
                         {\tt :: Partition -> Z}  \ \ weight of partition
\medskip
\\
\\
\\
{\tt pTail} \ \ \ref{sec-pl} \ \ {\tt :: CommutativeRing a => p a -> p a}

\verb#         # operation from {\tt PolLike} constructor class:
  
\verb#         # tail of a non-zero pol-like thing 
\medskip
\\
{\tt pToVec} \ \ \ref{sec-pl} \ \ \ 
             {\tt :: CommutativeRing a => Z -> p a -> [a]}

  Operation from {\tt PolLike} constructor class 
  (so far, only for {\tt UPol}):

  list of given length of coefficients of pol-like data (0 for gaps)
\medskip
\\
{\tt ptpMatrRows} \ \ \ref{sec-symmf.t.i} \ \ \ 
                                     {\tt :: PrttParamMatrix a -> [[a]]}
\medskip
\\
{\tt pValue} \ \ \ref{sec-pl} \ \ \ 
                              {\tt :: CommutativeRing a => p a -> [a] -> a}

\verb#       # operation from {\tt PolLike} constructor class:

\verb#       # 
        value of pol-like thing at \ $x_i = a_i$, \ extra $a_i$ discarded
\medskip
\\
{\tt pVars} \ \ \ref{sec-pl} \ \ \ {\tt :: p a -> [PolVar]}

\verb#       #
       operation from {\tt PolLike} constructor class: \ list of variables 
\medskip
\\
{\tt PVecP} \ \ \ref{sec-pol.f} \ \ \ {\tt type PVecP a = (Pol a, [Pol a])}

\verb#     # 
     Polynomial-vector-polynomial {\tt (f,v)} is supplied with the polynomial 

\verb#     # 
  list {\tt v}. {\tt v} usually accumulates transformation coefficients \ldots
\medskip
\\
{\tt quotEuc} \ \ \ref{sec-euc} \ \ \ 
                           {\tt :: EuclideanRing a => Char -> a -> a -> a}

\verb#                     \ mode x -> fst . divRem mode x #
\medskip
\\
{\tt randomEPrtts} \ \ \ref{sec-symmf.p.p} \ \ \ 
                       {\tt :: [Z] -> Z -> [EPartition]}

\verb#     # infinite list of \ random expanded partitions of given weight $w$

\verb#     # 
           produced out of infinite list of random integers \ $0 \leq n \leq w$
\medskip
\\
{\tt rankFromIdeal} \ \ \ref{sec-il.g.fn} \ \ \ {\tt :: Ideal a -> InfUnn Z}

\verb#         \ iI -> case lookup IdealRank (idealOpers iI)  of #

\verb#                             {Just (IdealRank' v) -> v;  _ -> UnknownV} #
\medskip
\\
\verb#rank_euc# \ \ \ref{sec-lin.u} \ \ \ 
                                    {\tt :: EuclideanRing a => [[a]] -> Z}

\verb#                  # rank of matrix (Gauss method) 
\medskip
\\
{\tt read} \ \ \ref{sec-pars}
\medskip
\\
{\tt RealField} \ \ see~\ref{sec-fld}, \ notion {\tt IsRealField} 

\verb#          # 
    {\tt class Field a => RealField a} \ \ \ presumed: {\tt (IsRealField,Yes)}
\medskip
\\
\verb#reduceVec_euc# \ \ \ref{sec-lin.v} \ \ 
                     reduces vector by vector list \ {\tt us}:
           
\verb#            # 
             {\tt :: EuclideanRing a => Char -> [[a]] -> [a] -> ([a], [a])}

\verb#            #
      {\tt us} is staircase. Several $a_i u_i$ subtract to make zeroes \ldots
\medskip
\\
{\tt remEuc} \ \ \ref{sec-euc} \ \ \ 
                 {\tt :: EuclideanRing a => Char -> a -> a -> a}

\verb#                      \ mode x -> snd . divRem mode x #
\medskip
\\
{\tt removeFromAssocList} \ \ \ref{sec-dprel} \ \ \ 
                              {\tt :: Eq a => [(a,b)] -> a -> [(a,b)]}
\medskip
\\
{\tt reordEPol} \ \ \ref{sec-polv.e.i} \ \ \ 
                                {\tt :: EPPOTerm -> EPol a -> EPol a}

\verb#                # bring e-pol to given epp ordering
\medskip
\\
{\tt reordPol} \ \ \ref{sec-pol.f} \ \ \ 
                                   {\tt :: PPOrdTerm -> Pol a -> Pol a}

\verb#                # bring polynomial to given pp ordering
\medskip
\\
{\tt reordSymPol} \ \ \ref{sec-symmf.sp.i} 
                  \ \ \ {\tt :: PrttComp -> SymPol a -> SymPol a}

\verb#                # bring sym-pol to given partition ordering
\medskip
\\
{\tt resGDom} \ \ \ref{sec-res} \ \ \ 
                                {\tt :: r a -> (Subgroup a, Domains1 a)}

  operation from constructor class {\tt Residue}. \ For a residue group $G/H$,

  it extracts the subgroup term and domain bundle for $H$.
\medskip
\\ 
{\tt resIdeal} \ \ \ref{sec-res} \ \ \ 
                {\tt (fst . resIDom) :: Residue r => r a -> Ideal a}

\verb#                  # extracts ideal from \ {\tt ResidueI} \ data
\medskip
\\ 
{\tt resIDom} \ \ \ref{sec-res} \ \ \ {\tt :: r a -> (Ideal a, Domains1 a)}

  Operation from constructor class {\tt Residue}. \ For a residue ring \ 
  {\tt a/I},  

  it extracts the ideal term and domain bundle for {\tt I}.
\medskip
\\
{\tt resIIDom} \ \ \ref{sec-res} \ \ \  
                {\tt (snd . resIDom) :: (Residue r) => r a -> Domains1 a}

\verb#              # extracts ideal domain bundle from {\tt ResidueI} data
\medskip
\\ 
{\tt Residue} \ \ \ref{sec-res} \ \ {\tt DoCon} deals with commutative group

\verb#         # 
       residues ({\tt ResidueG}), Euclidean ring residues ({\tt ResidueE}),  

\verb#         # 
     generic residues ({\tt ResidueI}), joining them into {\tt class Residue}
\medskip
\\
{\tt ResidueE} \ \ \ref{sec-rse} \ \ \
           {\tt data ResidueE a = Rse !a !(PIRChinIdeal a) !(Domains1 a)}

\verb#        # 
    {\tt Rse x iI aD} \ is a residue in {\tt a/I} for Euclidean ring {\tt a}.

\verb#        # 
    {\tt aD} a bundle for base domain in {\tt a}, \ {\tt iI} ideal term \ldots
\medskip
\\
{\tt ResidueG} \ \ \ref{sec-rsg} 

\verb#     # 
         {\tt data ResidueG a = Rsg !a !(Subgroup a, Domains1 a) !(Domains1 a)}

  Element of quotient group {\tt a/H} is represented as
                                     {\tt Rsg x (gH,dH) dm :: ResidueG a}
\medskip
\\
{\tt ResidueI} \ \ \ref{sec-rsi}, \ \ref{sec-gx}

\verb#         # 
         {\tt data ResidueI a =  Rsi !a !(Ideal a, Domains1 a) !(Domains1 a)}

\verb#         # 
       {\tt Rsi x (iI,iD) aD} \ is a residue in {\tt a/I} for a gx-ring {\tt a}
\medskip
\\
{\tt Residue module} \ \ \ref{sec-dme}, \ref{sec-res}

\verb#          # {\tt DoCon} module exporting items for residue group, residue ring 
\medskip
\\
{\tt resPIdeal} \ \ \ref{sec-res} \ \ \ {\tt :: r a -> PIRChinIdeal a}

\verb#              # Operation from constructor class {\tt Residue} : 

\verb#              # extracts the ideal term from {\tt ResidueE} data
\medskip
\\
{\tt resRepr} \ \ \ref{sec-res} \ \ \ {\tt :: r a -> a}  

\verb#              # operation from constructor class {\tt Residue} : 

\verb#              # extracts representation from residue
\medskip
\\
{\tt resSubgroup} \ \ \ref{sec-res} \ \ \
                  {\tt (fst . resGDom) :: Residue r => r a -> Subgroup a}

\verb#              # extracts subgroup from {\tt ResidueG} data
\medskip
\\
{\tt resSSDom} \ \ \ref{sec-res} \ \ \
               {\tt (snd . resGDom) :: Residue r => r a -> Domains1 a}

\verb#              # extracts domain of subgroup from  ResidueG  data
\medskip
\\
{\tt resultantMt} \ \ \ref{sec-mt.f} \ \ \ 
                  {\tt :: AddGroup a => [a] -> [a] -> [[a]]}

\verb#         # 
       resultant matrix for the coefficient lists of two dense polynomials 
\medskip
\\
\verb#resultant_1_euc# \ \ \ref{sec-upo.i} \ \ \ 
                       {\tt :: EuclideanRing a => UPol a -> UPol a -> a}

\verb#            # resultant of univariate polynomials over an Euclidean ring
\medskip
\\
{\tt rFromHeadVarPol} \ \ \ref{sec-rpol.d} \ \ \ 
           {\tt :: AddSemigroup a=> RPolVar-> UPol (RPol a)-> RPol a}

\verb#          # 
   Inverse to {\tt rHeadVarPol}. The leading variable is given in argument, 

\verb#          # 
   in order not to convert it from string nor to search in {\tt ranges}
\medskip
\\
{\tt rHeadVarPol} \ \ \ref{sec-rpol.d} \ \ 
                               map r-polynomial $r$ from $R$ to $R[u]$.

\verb#         # $r$ \ is not constant, \ $u$ \ is its leading variable.

\verb#         # {\tt :: Set a => Domains1 (RPol a) -> RPol a -> UPol (RPol a)}
\medskip
\\  
{\tt Ring} \ \ \ref{sec-rg} \ \ a category

{\tt class (AddGroup a, MulSemigroup a, Num a, Fractional a) => Ring a where}

\verb#    {fromi_m :: a -> Z -> Maybe a;   baseRing :: a -> Domains1 a ...}#

Presumed: \ {\tt add, mul} \ obey the ring laws on base set \ldots
\medskip
\\
{\tt RingModule} \ \ \ref{sec-dme} \ \ 
                 {\tt DoCon} module exporting items for {\tt Ring, GCDRing} \ldots
\medskip
\\
{\tt root} \ \ \ref{sec-smg.m} \ \ \ {\tt :: Z -> a -> MMaybe a} \ \ 
                                                   root of n-th degree.

\verb#       # Operation from {\tt MulSemigroup} category. It may yield 

\verb#       # {\tt Just (Just r) | Just Nothing | Nothing}, \ \ 
               {\tt r} \ a root in given domain
\medskip
\\
{\tt rootOfNatural} \ \ \ref{sec-z.fn} 
{\footnotesize
\begin{verbatim} 
              :: Natural -> Natural -> Natural -> (Natural, Natural)
                 -- e       x          b           r        r^e
\end{verbatim} 
}
Integer part \ {\tt r} \ of the \ {\tt e} -th degree root of \ {\tt x} \ 
for {\tt e > 0}.

The root is searched in the segment {\tt [0, b]}.
\medskip
\\
{\tt rowMatrMul} \ \ \ref{sec-mt.f} \ \ \ 
                 {\tt :: CommutativeRing a => [a] -> [[a]] -> [a]}

\verb#              # product of a row by a matrix
\medskip
\\
{\tt RPol} \ \ \ref{sec-rpol.d}, \ref{sec-rpol} \ \ type ``r-polynomial''

\verb#     # {\tt data RPol a = RPol !(RPol' a) !a !RPolVarsTerm !(Domains1 a)}

\verb#     # 
     In \ {\tt RPol rpol' a vterm aDom, \ \ a} \ is sample coefficient, \ldots
\medskip
\\
{\tt rpolHeadVar} \ \ \ref{sec-rpol.d} \ \ \ extract head variable

\verb#             # {\tt (rp'HeadVar . rpolRepr) :: RPol a -> Maybe RPolVar}
\medskip
\\
{\tt rpolRepr} \ \ \ref{sec-rpol.d} \ \ \
                \verb#(\ RPol f _ _ _) -> f) :: RPol a -> RPol' a#

\verb#              # extract `representation' of r-pol
\medskip
\\
{\tt RPolVar} \ \ \ref{sec-rpol.d} \ \ \ 
                  {\tt type RPolVar = [Z]} \ \ \ r-pol variable
\medskip
\\
{\tt RPolVarComp} \ \ \ref{sec-rpol.d} \ \ \
                            {\tt type RPolVarComp = Comparison RPolVar}
\medskip
\\
{\tt rpolVars} \ \ \ref{sec-rpol.d} \ \ \ 
                                   {\tt :: Char -> RPol a -> [RPolVar]}

\verb#      # 
       variables {\tt v(i,j)} on which r-polynomial {\tt f} really depends.

\verb#      # The result is ordered by comparison from {\tt f}.
\medskip
\\
{\tt RPolVarsTerm} \ \ \ref{sec-rpol.d}, \ref{sec-rpol.e} \ \ \ 
                {\tt type RPolVarsTerm = (RPolVarComp, String, [(Z,Z)])}

\verb#     # variable ordering and variable set description for 
            {\tt [pref[$i_1,\ldots,i_n$] \ | \ldots]}
\medskip
\\
{\tt rpolVComp} \ \ \ref{sec-rpol.d} \ \ \
                {\tt (rvarsTermCp . rpolVTerm) :: RPol a -> RPolVarComp}

\verb#              # extract variable comparison function
\medskip
\\
{\tt rpolVPrefix} \ \ \ref{sec-rpol.d} \ \ \ 
                  {\tt (rvarsTermPref . rpolVTerm) :: RPol a -> String}

\verb#              # extract prefix for variables
\medskip
\\
{\tt rpolVRanges} \ \ \ref{sec-rpol.d} \ \ \
                  {\tt (rvarsTermRanges . rpolVTerm) :: RPol a -> [(Z,Z)]}

\verb#              # extract variable ranges 
\medskip
\\
{\tt rpolVTerm} \ \ \ref{sec-rpol.d} \ \ \
                  \verb#(\ RPol _ _ t _) -> t) :: RPol a -> RPolVarsTerm#

\verb#              # extract variable set description 
\medskip
\\
{\tt RPol'} \ \ \ref{sec-rpol.d}, \ref{sec-rpol} \ \ 
  inner representation of r-polynomial:

\verb#      # {\tt data RPol' a = CRP !a | NRP !RPolVar !Z (RPol' a) (RPol' a)}
  
\verb#                                       # {\tt deriving (Eq, Show, Read)}
\medskip
\\
{\tt rp'HeadVar} \ \ \ref{sec-rpol.d} \ \ \ 
                 {\tt :: RPol' a -> Maybe RPolVar} \ \ \ head variable

       \verb#                    {NRP v _ _ _-> Just v,  _ -> Nothing} #
\medskip
\\
{\tt rp'Vars} \ \ \ref{sec-rpol.d} \ \ \ 
                  {\tt :: Char -> RPol' a -> [RPolVar]}

\verb#      # Lists variables, listed first --- into depth, then to the right,

\verb#      # 
         repetitions cancelled. {\tt mode = 'l'} \ means f is linear \ldots
\medskip
\\
{\tt rvarsOfRanges} \ \ \ref{sec-rpol.d} \ \ \ {\tt :: [(Z,Z)] -> [RPolVar]}

\verb#  # all r-vars in the given ranges listed in
          lexicographic-increasing order
\medskip
\\
{\tt rvarsVolum} \ \ \ref{sec-rpol.d} \ \ \ {\tt :: [(Z,Z)] -> Z}

\verb#              # number of r-polynomial variables defined by ranges
\medskip
\\
{\tt Rse} \ \ \ data constructor for {\tt ResidueE}
\medskip
\\
{\tt Rsi} \ \ \ constructor for {\tt ResidueI}
\medskip
\\
{\tt rvarsTermCp} \ \ \ref{sec-rpol.d} \ \ \
                      {\tt = tuple31  :: RPolVarsTerm -> RPolVarComp}
\medskip
\\
{\tt rvarsTermPref} \ \ \ref{sec-rpol.d} \ \ \ 
                      {\tt = tuple32 :: RPolVarsTerm -> String}
\medskip
\\
{\tt rvarsTermRanges} \ \ \ref{sec-rpol.d} \ \ \
                          {\tt = tuple33 :: RPolVarsTerm -> [(Z,Z)]}
\medskip
\\
{\tt sample} \ \ \ref{sec-dd.dm} \ \ \ {\tt :: c a -> a} \ \
                                   sample element for argument domain

\verb#     # Operation from constructor class {\tt Dom}. \ Example: 

\verb#     # 
        for a polynomial {\tt f}, \ {\tt sample f} \ is sample for coefficient
\medskip
\\
{\tt scalarMt} \ \ \ref{sec-mt.f} \ \ \ 
               {\tt :: [a] -> b -> b -> [[b]]} \ \ scalar pre-matrix

\verb#    # $n \times n$ \ made from given elements {\tt c, z}.

\verb#   # 
     Example: \ {\tt scalarMt "xxx" 1 0 ->} \ integer unity matrix of size 3
\medskip
\\
{\tt scalProduct} \ \ \ref{sec-vec.f} \ \ \ 
                              {\tt :: CommutativeRing a => [a] -> [a] -> a}

         \verb#                        (\ u v -> sum1 (zipWith (*) u v)) #
\medskip
\\
{\tt semigroup} \ \ \ see \ {\tt Subsemigroup, AddSemigroup, MulSemigroup}
\medskip
\\
{\tt separate} \ \ \ref{sec-dprel} \ \ \ {\tt :: Eq a => a -> [a] -> [[a]]}

\verb#   # break list to lists separated by given separator

\verb#   # Example: \ \verb#  ';' "ab;cd;;e f " ->  ["ab", "cd", "", "e f "] #
\medskip
\\
{\tt sEPol} \ \ \ref{sec-polv.e.i} \ \ \
                       {\tt sEPol f g} \ differs from {\tt sPol}

\verb#    # in that it is in {\tt Maybe} format, returns {\tt Nothing} when the 

\verb#    # leading coordinates of {\tt f, g} differ, otherwise, 
            {\tt Just (s-epol,m1,m2)}
\medskip
\\
{\tt sEPVecP} \ \ \ref{sec-polv.e.i} \ \ \ similar to {\tt sPol, sPVecP}

{\tt :: GCDRing a => EPVecP a -> EPVecP a -> Maybe (EPVecP a, Mon a, Mon a)}
\medskip
\\
{\tt Set} \ \ \ref{sec-set.ct} \ \ category Partially Ordered Set:

\verb#      # {\tt class (Eq a, Show a) => Set a where}

\verb#                 {showsDomOf...fromExpr...compare_m...baseSet...} #
\medskip
\\
{\tt SetGroup} \ \ \ref{sec-dme} 

  {\tt DoCon} module exporting items for \ {\tt Set, AddGroup,} \ldots 
  --- before {\tt Ring}
\medskip
\\
{\tt SHook} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt type SHook = (Z, Z, Z, Z)}

\verb#    # 
     A {\it skew hook} known from combinatorics (see also {\tt Partition}):

\verb#    # weight of hook, No of starting block, No of row in block \ldots 
\medskip
\\
{\tt sHookHeight} \ \ \ref{sec-symmf.p.p} \ \ \ 
                                  {\tt :: Partition -> SHook -> Z} 

\verb#                             # {\tt numberOfRowsOccupied - 1}
\medskip
\\
{\tt showsDomOf} \ \ \ref{sec-set.ct}, \ \ref{sec-set.dpr} 
                                    \ \ \ {\tt :: a -> String -> String}

\verb#              # Operation of {\tt Set} category used in error messages
\medskip
\\
{\tt showsExpr} \ \ \ref{sec-pars} 
                \ \ \ {\tt :: Show a => Expression a -> String -> String}
\medskip
\\
{\tt showsPrtt} \ \ \ref{sec-symmf.p.p} 
                \ \ \ {\tt :: Partition -> String -> String}

\verb#         # Example: \ \verb# [(5,2),(4,1),(2,3)] "" -> "[5*2,4,2*3]" #
\medskip
\\
{\tt showsWithDom} \ \ \ see \ \verb#source/auxil/Set_.hs#

\verb#        # prints element and its domain, with their given string names
\medskip
\\
{\tt smParse} \ \ \ref{sec-prp.pars}, \ \ref{sec-pars} 
                               \ \ \ {\tt :: Set a => a -> String -> a}

\verb#            # Generic parsing from string by the sample element, 

\verb#            # a composition of \ {\tt lexLots, infixParse, fromExpr}
\medskip
\\
{\tt solveLinearTriangular} \ \ \ref{sec-lin.sl} 

\verb#          :: CommutativeRing a => [[a]] -> [a] -> Maybe [a]#

\verb#                               -- mA       row#

\verb#            # solves a system \ {\tt xRow x mA' = row}

\verb#            # for the upper-triangular matrix {\tt mA'} 
                    obtanained from {\tt mA} \ldots
\medskip
\\
\verb#solveLinear_euc# \ \ \ref{sec-lin.sl} 
            \ \ \ {\tt :: EuclideanRing a => [[a]] -> [a] -> ([a], [[a]])}

\verb#     # 
     solution of linear system \ {\tt M $\times$ (transp [x]) = (transp [v])}
\medskip
\\
{\tt sortE} \ \ \ref{sec-dprel} \ \ \ 
                                {\tt :: Comparison a -> [a] -> ([a], Char)}

\verb#         # Extended {\tt sort}: the sign {\tt '+' | '-'} of permutation 

\verb#         # is also accumulated. \ Method: `merge' algorithm. 
\medskip
\\
{\tt sPol} \ \ \ref{sec-pol.f} \ \ s-polynomial for non-zero $f, g$

\verb#       # {\tt :: GCDRing a => Pol a -> Pol a -> (Pol a, Mon a, Mon a)}

\verb#       # 
     (related to Gr\"obner basis). It is \ $ m_1 \cdot f - m_2 \cdot g $ \ldots
\medskip
\\
{\tt sPVecP} \ \ \ref{sec-pol.f} \ \ \ s-polynomial for \ {\tt PVecP a}

\verb#        #  
      {\tt :: GCDRing a => PVecP a -> PVecP a -> (PVecP a, Mon a, Mon a)}
\medskip
\\
{\tt sqMatrHead} \ \ \ref{sec-mt.f} 

\verb#         (\(SqMt rs d) -> matrHead (Mt rs d)) :: SquareMatrix a -> a#
\medskip
\\
{\tt sqMatrRows} \ \ \ref{sec-mt.f} \ \ \ 
                     \verb#(\ SqMt rs _ -> rs) :: SquareMatrix a -> [[a]]#
\medskip
\\
{\tt sqMatrSize} \ \ \ref{sec-mt.f} \ \ \ {\tt :: SquareMatrix a -> Z}
\medskip
\\
{\tt sqMatrTail} \ \ \ref{sec-mt.f} 

\verb#       (\(SqMt rs d) -> matrTail (Mt rs d)) :: SquareMatrix a -> [[a]]#
\medskip
\\
{\tt SquareMatrix} \ \ \ref{sec-mt.f} \ \ \
                   {\tt data SquareMatrix a = SqMt ![[a]] !(Domains1 a)}

\verb#        # The main difference to {\tt Matrix} is that 

\verb#        # the \ {\tt MulSemigroup, Ring} \ instances are defined too.
\medskip
\\
{\tt sub} \ \ \ref{sec-smg} \ \ \ {\tt :: AddSemigroup a => a -> a -> a}

\verb#          # subtraction: composed \ \verb#sub_m# \ and \ {\tt error}
\medskip
\\
{\tt subgrCanonic} \ \ \ref{sec-grp.sb} \ \ \ {\tt :: !(Maybe (a -> a))}

\verb#        # data field in description of \ {\tt Subgroup H} \ in \ {\tt a} 
\medskip
\\
{\tt subgrConstrs} \ \ \ref{sec-grp} \ \ \ 
                              \verb#:: ![Construction_Subgroup a]#

\verb#            # data field in {\tt Subgroup} description
\medskip
\\
{\tt subgrGens} \ \ \ref{sec-grp.sb} \ \ \ {\tt :: !(Maybe [a])}

\verb#      # data field in {\tt Subgroup} description: \ generator list.

\verb#      # 
  {\tt Just gs} \ means {\tt gs} is a finite list of subgroup generators \ldots
\medskip
\\
{\tt subgrOpers} \ \ \ref{sec-grp.sb} \ \ \ 
                                      \verb#:: !(Operations_Subgroup a)#

\verb#             # data field in {\tt Subgroup} description
\medskip
\\
{\tt Subgroup} \ \ \ref{sec-grp.sb} \ \ \ {\tt data Subgroup a =}

\verb#                 Subgroup {subgrType...subgrGens...subgrCanonic ...} #
  
\verb#               # description of subgroup of base group on \ {\tt a}
\medskip
\\
{\tt subgrProps} \ \ \ref{sec-grp.sb} \ \ \ \verb#:: Properties_Subgroup#

\verb#            # data field in {\tt Subgroup} description
\medskip
\\
{\tt Submodule} \ \ \ref{sec-mod.s} \ \ \ {\tt data Submodule r a =}

\verb#           Submodule {moduleRank ... moduleGens ... moduleProps ... }#

\verb#      # 
         description of submodule in a module \ {\tt a} \ over a ring \ {\tt r}
\medskip
\\
{\tt Subring} \ \ \ref{sec-rg.sub} \ \ \ {\tt data Subring a =}

\verb#           Subring {subringChar ... subringGens ... subringProps ...}#

\verb#         # description of a subring of a base ring on \ {\tt a}
\medskip
\\
{\tt subringChar} \ \ \ref{sec-rg.sub} \ \ \ 
                      {\tt :: !(Maybe Z)} \ \ characteristic of ring.

\verb#        # Data field in {\tt Subring} description. 

\verb#        # 
         {\tt Nothing} means it is unknown, \ {\tt Just n: \ char = n} $\geq 0$
\medskip
\\
{\tt subringConstrs} \ \ \ref{sec-rg.sub} \ \ \ 
                         \verb#:: ![Construction_Subring a]#

\verb#              # data field in {\tt Subring} description
\medskip
\\
{\tt subringGens} \ \ \ref{sec-rg.sub} \ \ \ 
                  {\tt :: !(Maybe [a])} \ \ subring generator list.

Data field in {\tt Subring} term:   
{\tt Just gs} \ means {\tt gs} is a finite generator list for subring
\medskip
\\
{\tt subringOpers} \ \ \ref{sec-rg.sub} \ \ \ 
                       \verb#:: !(Operations_Subring a)#

\verb#              # data field in {\tt Subring} description
\medskip
\\
{\tt subringProps} \ \ \ref{sec-rg.pr} \ \ \ \verb#:: Properties_Subring#

\verb#             # data field in Subring description
\medskip
\\
{\tt Subsemigroup} \ \ \ref{sec-smg.sub} \ \ \ {\tt data Subsemigroup a =}

\verb#            Subsemigroup {subsmgType ... subsmgUnity ... subsmgGens ...}# 

\verb#         # description of subsemigroup of the base semigroup on \ {\tt a}
\medskip
\\
{\tt subsmgConstrs} \ \ \ref{sec-smg.sub}
                    \ \ \ \verb#:: ![Construction_Subsemigroup a]#

\verb#             # data field in {\tt Subsemigroup} description     
\medskip
\\
{\tt subsmgGens} \ \ \ref{sec-smg.sub} \ \ \ 
                 {\tt :: !(Maybe [a])} \ \ list of generators.

\verb#      # 
       Data field in {\tt Subsemigroup} description. \ \ {\tt Just gs} \ means 

\verb#      # {\tt gs} is a finite list of subsemigroup generators \ldots
\medskip
\\
{\tt subsmgOpers} \ \ \ref{sec-smg.sub} \ \ \ 
                      \verb#:: !(Operations_Subsemigroup a)#

\verb#           # data field in {\tt Subsemigroup} description     
\medskip
\\
{\tt subsmgProps} \ \ \ref{sec-smg.sub} \ \ \ 
                      \verb#:: !Properties_Subsemigroup#
                  
\verb#            # data field in {\tt Subsemigroup} description
\medskip
\\ 
{\tt subsmgType} \ \ \ref{sec-smg.sub} \ \ \ {\tt :: !AddOrMul} \ \ 
                                 data field in {\tt Subsemigroup} term
\medskip
\\
{\tt subsmgUnity} \ \ \ref{sec-smg.sub} \ \ \ {\tt :: !(MMaybe a)} \ \ 
                                                    neutral element.

\verb#     # 
        Data field in {\tt Subsemigroup} description. \ {\tt Just (Just z)}

\verb#     # 
      means {\tt z} is a neutral (zero | unity), \ {\tt Just Nothing} \ldots
\medskip
\\     
{\tt subset} \ \ \ see \ {\tt OSet}
\medskip
\\
{\tt substValsInRPol} \ \ \ref{sec-rpol.d} \ \
             substitutes $[v_1=a_1,\ldots,v_n=a_n]$ to r-polynomial:

\verb#     # 
     {\tt :: CommutativeRing a => Char -> [(RPolVar, a)] -> RPol a -> RPol a}

\verb#     # 
       Required: \ $v_1 > \ldots > v_n$ \ by comparison from given polynomial
\medskip
\\
{\tt subtrHBand} \ \ \ref{sec-symmf.p.p} \ \ \ 
                         {\tt :: Partition -> HBand -> Partition} 

        \verb#                         partition \ h-band#
\medskip
\\
{\tt subtrSHook} \ \ \ref{sec-symmf.p.p} 
                 \ \ \ {\tt :: Partition -> SHook -> Partition}

                 \verb#                                      partition \ sHook#
\medskip
\\
\verb#sub_m# \ \ \ref{sec-smg.a} \ \ \ {\tt a -> a -> Maybe a} 

\verb#             # subtraction operation from {\tt AddSemigroup} category
\medskip
\\
{\tt sum1} \ \ \ref{sec-dprel} \ \ \ {\tt :: Num a => [a] -> a} \ \  
                                                 sums non-empty list 
\medskip
\\
{\tt SymFTransTab} \ \ \ref{sec-symmf.t.i} \ \ \ {\tt type SymFTransTab =}

\verb#          Map.Map Z ([Partition], PrttParamMatrix Z, PrttParamMatrix Z)#

\verb#    # 
    Table of pairs {\tt (w, (pts,tC,tK))}, \ {\tt w} the integer weight, \ldots
\medskip
\\
{\tt symLdPrtt} \ \ \ref{sec-symmf.sp.i}
                \ \ \ {\tt :: CommutativeRing a => SymPol a -> Partition}

\verb#           # leading partition of a non-zero sym-polynomial
\medskip
\\
{\tt symLm} \ \ \ref{sec-symmf.sp.i} 
            \ \ \ {\tt :: CommutativeRing a => SymPol a -> SymMon a}

\verb#           # leading sym-monomial of a non-zero sym-polynomial
\medskip
\\
\verb#SymmDecBasisId# \ \ \ref{sec-symmf.t} \ \ \ \ 
                                      {\tt type SymmDecBasisId = String}
\medskip
\\
\verb#SymmDecMessageMode# \ \ \ref{sec-symmf.t} 

{\footnotesize
\verb#           # 
{\tt data SymmDecMessageMode = DoSymmDecMessages Integer | NoSymmDecMessages}
  
\verb#                                     # {\tt deriving (Eq, Show)}
}
\medskip
\\
{\tt symmetrizePol} \ \ \ref{sec-symmf.sp.cv}, {\tt symmSumPol} 
          
\verb#    # {\tt :: CommutativeRing a => PrttComp -> Pol a -> Maybe (SymPol a)}

\verb#    # 
     converts polynomial to symmetric polynomial under given partition ordering
\medskip
\\
{\tt SymMon} \ \ \ref{sec-symmf.sp.i} \ \ \ 
                                     {\tt type SymMon a = (a, Partition)}

       analog for \ {\tt Mon a}, \ with partition instead of power product
\medskip
\\
{\tt symmSumPol} \ \ \ref{sec-symmf.sp.cv} \ \ \ 
                                    $symF = n! \cdot (symmetrize \ f)$, 

\verb#        # {\tt :: CommutativeRing a => PrttComp -> Pol a -> SymPol a}

\verb#        # 
           $n =$ {\tt length vars}, \ $symF$ under given partition ordering
\medskip
\\
\\
\\
{\tt SymPol} \ \ \ref{sec-symmf.sp.i} \ \ Symmetric polynomial: 

\verb#    # {\tt data SymPol a = SymPol ![SymMon a] !a !PrttComp !(Domains1 a)}

\verb#    # 
       Mainly, it is a list of sym-monomials. It is similar to {\tt Pol}, only 

\verb#    # 
       the variables skipped (presumed to be an infinite set $x_1,x_2$,\ldots)
\medskip
\\
{\tt symPolHomogForms} \ \ \ref{sec-symmf.sp.i} \ \ \ 
                       {\tt :: AddGroup a => SymPol a -> [SymPol a]}

\verb#      # 
         homogeneous parts {\tt hs} of {\tt f}, \ empty for zero {\tt f}, \ 

\verb#      # 
         otherwise, {\tt h(1)} is the homogeneous form of \ {\tt lm f}, \ldots
\medskip
\\ 
{\tt symPolMons} \ \ \ref{sec-symmf.sp.i} 

\verb#              (\(SymPol ms _ _ _) -> ms) :: SymPol a -> [SymMon a]#
\medskip
\\
{\tt symPolPrttComp} \ \ \ref{sec-symmf.sp.i}

\verb#              (\(SymPol _ _ cp _) -> cp) :: SymPol a -> [SymMon a]#
\medskip
\\
{\tt syzygyGens} \ \ \ref{sec-linr.s} \ \ \ {\tt :: String -> [a] -> [[a]]}

\verb#     # operation of {\tt LinSolvRing} category: \ linear relation module 

\verb#     # 
    generators for given list. \ {\tt mode = "g"} is for polynomial ring \ldots
\medskip
\\
{\tt syzygyGensM} \ \ \ref{sec-mod.ls}, \ref{sec-mod.lsm}, \ref{sec-gx} 

\verb#        # {\tt :: r  -> String -> [a] -> [[r]]}

\verb#        # Operation from \ {\tt LinSolvLModule r a} \ category:
\medskip
\\
{\tt takeAsMuch} \ \ \ref{sec-dprel} \ \ \ {\tt :: [a] -> [b] -> [b]}

\verb#        #  {\tt takeAsMuch xs ys ==  \ take |xs| ys}, \ \ 
                 only it is better implemented.
\medskip
\\
{\tt test} \ \ \ see~\ref{sec-demot}, \ file \ {\tt install.txt}

\verb#              T_.test "log"# \ runs automatic test for DoCon, 

\verb#               # copying the result to the file \ \verb#./log#
\medskip
\\
\verb#testFactorUPol_finField# \ \ \ {\tt :: Field k => UPol k -> [Bool]}

\verb#        # Tests partially factorization for polynomial from \ $k[x]$,  

\verb#        # $k$ \ a finite field \ldots
\medskip
\\
{\tt times} \ \ \ref{sec-smg.fn} \ \ \ 
                                 {\tt :: AddSemigroup a => a -> Z -> a}

\verb#     # product by integer:  composed \ \verb#times_m# \ and \ {\tt error}
\medskip
\\
\verb#times_m# \ \ \ref{sec-smg.a} \ \ \ {\tt :: a -> Z -> Maybe a}
     
\verb#      # 
          multiplication by integer operation from {\tt AddSemigroup} category
\medskip
\\
\verb#toDiagMatr_euc# \ \ \ref{sec-lin.dg} \ \ 
                          Diagonal form {\tt d} of matrix {\tt m} 

{\tt :: EuclideanRing a => [[a]] -> [[a]] -> [[a]] -> ([[a]], [[a]], [[a]])}

\verb#      # 
   {\tt d} is obtained by elementary transformations of rows and columns \ldots
\medskip
\\
{\tt toEPermut} \ \ \ref{sec-pm.d} \ \ \ 
                \verb#(\ Pm xs -> zip (sort xs) xs) :: Permutation -> EPermut#
\medskip
\\
{\tt toEPrtt} \ \ \ref{sec-symmf.p.p} \ \ \ {\tt :: Partition -> EPartition}

          \verb#              concat . map (\ (j,m) -> genericReplicate m j)#
\medskip
\\
{\tt toOverHeadVar} \ \ \ref{sec-pol.f} \ \ 
                               Bring polynomial to tail variables:

\verb#      # 
      {\tt :: CommutativeRing a => Domains1 (UPol a) -> Pol a -> Pol (UPol a)}
 
  
\verb#      # $ a[x_1,x2,\ldots,x_n] \ \rightarrow \ (a[x_1])[x_2,\ldots,x_n] $
\medskip
\\
{\tt toPolOverPol} \ \ \ \ref{sec-pol.f} \ \ 

\verb#      # 
         from \ {\tt a[xs \ ys]} \ to {\tt a[xs][ys]} \ or to \ {\tt a[ys][xs]}
\medskip
\\
{\tt toRPol} \ \ \ref{sec-rpol.d} \ \ converts polynomial to r-polynomial

{\tt :: 
CommutativeRing a => Char-> RPolVarsTerm-> [RPolVar]-> Pol a-> RPol a}

\verb#       # r-variable set description and variable correspondence are given
\medskip
\\
{\tt toRPol'} \ \ \ref{sec-rpol.d} \ \ converts polynomial to r-pol'

\verb#      # 
          {\tt :: CommutativeRing a => Char -> [RPolVar] -> Pol a -> RPol' a}

\verb#      # a bijective variable correspondence is given 
\medskip
\\
{\tt toSqMt} \ \ \ref{sec-mt} \ \ \ 
             \verb#(\Mt xs d -> SqMt xs) :: Matrix a -> SquareMatrix a#

\verb#               # a square matrix should be given
\medskip
\\
{\tt toSquareFree} \ \ \ref{sec-gcd} \ \ \ {\tt :: a -> Factorization a}

\verb#      # operation from the category {\tt GCDRing}. Returns \ 
              $[(a_1,1),\ldots,(a_m,m)]$ : 

\verb#      # 
          {\tt canAssoc a = } $a_1^1 \ldots a_m^m$, \ $a_i$ square free, \ldots
\medskip
\\
\verb#toStairMatr_euc# \ \ \ref{sec-lin.s} \ \ staircase form of matrix:

  {\tt :: EuclideanRing a => String -> [[a]] -> [[a]] -> ([[a]], [[a]], Char)}

  Gauss method modification with repeated remainder division.
\medskip
\\
{\tt toSymPol} \ \ \ref{sec-symmf.sp.cv} 
            \ \ \ {\tt :: Eq a => PrttComp -> Pol a -> Maybe (SymPol a)}

\verb#      # 
       given a symmetric polynomial, form sym-polynomial by gathering each

\verb#      # 
     monomial orbit into sym-monomial. Yields {\tt Just sF} for symmetric f
\medskip
\\
{\tt totient} \ \ \ref{sec-z.fn} \ \ \ \ \ \ \ {\tt :: Natural -> Natural}

  the number of the {\it totitive} numbers {\tt k} for \ {\tt n > 1}

  (that is \ {\tt 0 < k < n} \ and \ {\tt gcd n k = 1}).
\medskip
\\
{\tt toUPol} \ \ \ref{sec-pol.f} \ \ \ {\tt :: Ring a => Pol a -> UPol a}

\verb#      # convert to univariate polynomial: remove pp-ordering term, 

\verb#      # 
            take the head variable only and head of each power product, \ldots 
\medskip
\\
{\tt toZ} \ \ \ref{sec-dprel} \ \ \ 
                              {\tt = toInteger :: Integral a => a -> Z}
\medskip
\\
\verb#to_e# \ \ see \ \verb#to_<v>#
\medskip
\\
\verb#to_h# \ \ see \ \verb#to_<v>#
\medskip
\\
\verb#to_m# \ \   see \ \verb#to_<v>#
\medskip
\\
\verb#to_p# \ \   see \ \verb#to_<v>#
\medskip
\\
\verb#to_s# \ \   see \ \verb#to_<v>#
\medskip
\\
\verb#to_e_pol# \ \ see \ \verb#to_<v>_pol#
\medskip
\\
\verb#to_h_pol# \ \ see \ \verb#to_<v>_pol#
\medskip
\\
\verb#to_m_pol# \ \ see \ \verb#to_<v>_pol#
\medskip
\\
\verb#to_p_pol# \ \ see \ \verb#to_<v>_pol#
\medskip
\\
\verb#to_s_pol# \ \ see \ \verb#to_<v>_pol#
\medskip
\\
\verb#to_<v># \ \ \ref{sec-symmf.t} \ \ \ 
                                    \verb#to_e, to_h, to_m, to_s ::#

{\footnotesize
{\tt :: CommutativeRing a =>

\ \ \ SymmDecMessageMode -> SymmDecBasisId -> SymFTransTab -> SymPol a ->

\ \ \ (SymFTransTab, SymPol a) }
}
\medskip
\\
\verb#to_p# \ \ \ref{sec-symmf.t} \ \ \ 
 
{\footnotesize
{\tt :: Field k => \ \ \  -- REQUIRED is  char(k) = 0

\ \ \ SymmDecMessageMode -> SymmDecBasisId -> SymFTransTab -> SymPol k ->

\ \ \ (SymFTransTab, SymPol k) }
}
\medskip
\\
\verb#to_<v>_pol# \ \ \ref{sec-symmf.t} \ \ \
                  \verb#to_e_pol, to_h_pol, to_m_pol, to_s_pol ::#

{\footnotesize
{\tt :: CommutativeRing a =>

\ \ \ SymmDecMessageMode -> SymmDecBasisId ->
 
\ \ \ SymFTransTab -> PPOrdTerm -> SymPol a -> (SymFTransTab, Pol a) }
}
\medskip
\\
\verb#to_p_pol# \ \ \ref{sec-symmf.t} \ \ \

{\footnotesize
{\tt :: Field k => \ \ \ \ -- REQUIRED is \ char(k) = 0
    
\ \ \ SymmDecMessageMode -> SymmDecBasisId ->

\ \ \ SymFTransTab -> PPOrdTerm -> SymPol k -> (SymFTransTab, Pol k) }
}
\medskip
\\
{\tt transp} \ \ \ref{sec-mt.f} \ \ \ {\tt :: Matrix a -> Matrix a} \ \ \
                                                       transpose matrix
\medskip
\\
{\tt transpPtP} \ \ \ref{sec-symmf.t.i} \ \ \ 
                          {\tt :: PrttParamMatrix a -> PrttParamMatrix a}
\medskip
\\
{\tt trivialSubgroup} \ \ \ref{sec-grp.fn} 
                   \ \ \ {\tt :: a -> Subgroup a -> Subgroup a}

\verb#              # makes trivial subgroup in non-trivial base group
\medskip
\\ 
{\tt trivialSubsemigroup} \ \ \ref{sec-smg.fn} 
                          \ \ \ {\tt :: Subsemigroup a -> Subsemigroup a}

\verb#   # make trivial subsemigroup ($\{0\}$ or $\{1\}$) 
           inside non-trivial base monoid
\medskip
\\
\verb#tuple<i><j># \ \ \ref{sec-dprel} \ \  selects the field No {\tt i}

\verb#      # in an tuple of {\tt j} elements, \ {\tt i, j = [3,4,5]}.

\verb#      # Example: \ \verb#tuple32 (_, x, _) = x#
\medskip
\\
{\tt UMon} \ \ \ref{sec-upo.p} \ \ \ 
                      {\tt type UMon a = (a,Z)} \ \ \ univariate monomial
\medskip
\\
{\tt umonLcm} \ \ \ref{sec-upo.i} \ \ \ 
                      {\tt :: GCDRing a => UMon a -> UMon a -> UMon a}

\verb#         # lcm of u-monomials over a gcd-ring.

\verb#            \ (a,p) (b,q) -> case gcD[a,b] of g -> (a*(b/g), lcm p q)#
\medskip
\\
{\tt underPPs} \ \ (\ref{sec-pol.a.gr} \{und\})  
               \ \ \ {\tt :: [PowerProduct] -> (InfUnn Z, [PowerProduct])}

\verb#    # 
     A power product {\tt p} is called `under' power product with respect to 

\verb#    #
     power product list {\tt pps} if none of {\tt pps} divides {\tt p} \ \ldots
\medskip
\\
{\tt unfactor} \ \ \ref{sec-ftr.op} \ \ \ 
                   {\tt :: MulSemigroup a => Factorization a -> a}

\verb#            # example: \ {\tt [$(a,1),(b,2)$] -> a b}$^2$
\medskip
\\ 
{\tt unity} \ \ \ref{sec-smg.m} \ \ \ {\tt :: MulSemigroup a => a -> a}

\verb#      # unity of semigroup given by sample:

\verb#      # composition of \ \verb#unity_m# \ and \ {\tt error}
\medskip
\\
{\tt unityFr} \ \ \ref{sec-fr.i} \ \ \ 
              \verb#\x -> (unity x):/(unity x) :: Ring a => a -> Fraction a#
\medskip
\\
{\tt unityIdeal} \ \ \ref{sec-il.g.fn} \ \ \ {\tt :: a -> Subring a -> Ideal a}

\verb#              # unity ideal in a given base ring
\medskip
\\
\verb#unity_m# \ \ \ref{sec-smg.m} \ \ \ {\tt :: a -> Maybe a} \ \ 
                                   operation from {\tt MulSemigroup} category: 

\verb#      # builds unity from the sample element. Relies on {\tt subsmgUnity}
\medskip
\\
{\tt unparse} \ \ \ref{sec-pars} \ \ \ 
              In unparsing, {\tt DoCon} relies on the {\tt Show} class
\medskip
\\
{\tt upAddGroup} \ \ \ref{sec-up} \ \ \ {\tt :: AddGroup a => ADomDom a}

         \verb#              \a -> fst . baseAddGroup a . upAddSemigroup a#
\medskip
\\
{\tt upAddSemigroup} \ \ \ref{sec-up} \ \ \ 
                         {\tt :: AddSemigroup a => ADomDom a}

    \verb#             \a -> fst . baseAddSemigroup a . fst . baseSet a#
\medskip
\\
{\tt updateProps} \ \ \ref{sec-dprel} \ \ repeated {\tt propVOverList}:

\verb#     # 
        {\tt :: Eq a => [(a,PropValue)] -> [(a,PropValue)] -> [(a,PropValue)]}
\medskip
\\
{\tt upEucFactrRing} \ \ \ref{sec-up} \ \ \ 
             {\tt :: (EuclideanRing a, FactorizationRing a) => ADomDom a}
\medskip
\\
{\tt upEucRing} \ \ \ref{sec-up} \ \ \ {\tt :: EuclideanRing a => ADomDom a}
\medskip
\\
{\tt upFactorizationRing} \ \ \ref{sec-up} \ \ \ 
                              {\tt :: FactorizationRing a => ADomDom a}
\medskip
\\
{\tt upFactrLinSolvRing} \ \ \ref{sec-up} \ \ \ 
                 {\tt :: (FactorizationRing a, LinSolvRing a) => ADomDom a}
\medskip
\\
{\tt upField} \ \ \ref{sec-up} \ \ \ {\tt :: Field a => ADomDom a}
\medskip
\\
{\tt upGCDLinSolvRing} \ \ \ref{sec-up} \ \ \ 
                       {\tt :: (GCDRing a, LinSolvRing a) => ADomDom a}
\medskip
\\
{\tt upGCDRing} \ \ \ref{sec-up} \ \ \ {\tt :: GCDRing a => ADomDom a}
\medskip
\\
{\tt upLinSolvRing} \ \ \ref{sec-up} \ \ \ {\tt :: LinSolvRing a => ADomDom a}
\medskip
\\
{\tt upMulGroup} \ \ \ref{sec-up} \ \ \ {\tt :: MulGroup a => ADomDom a}
\medskip
\\
{\tt upMulSemigroup} \ \ \ref{sec-up} \ \ \ 
                         {\tt :: MulSemigroup a => ADomDom a}
\medskip
\\
{\tt UPol} \ \ \ref{sec-upo.p} \ \ Sparse univariate polynomial 

{\tt data UPol a = UPol ![UMon a] !a !PolVar !(Domains1 a)}

         In \ \ {\tt UPol mons c v aD}, \ \ 
         {\tt mons} \ are ordered decreasingly by {\tt deg} \ldots
\medskip
\\
{\tt upolInterpol} \ \ \ref{sec-upo.i} \ \
                   Interpolates (rebuilds) polynomial

\verb#        # $y = y(x)$ \ from table, \ $x, y \in$ {\tt a}:
 
\verb#        # {\tt :: CommutativeRing a => UPol a -> [(a,a)] -> UPol a}
\medskip
\\
{\tt upolMons} \ \ \ref{sec-upo.i} \ \ \
               \verb#(\ UPol ms _ _ _ -> ms) :: UPol a -> [UMon a]#
\medskip
\\
{\tt upolPseudoRem} \ \ \ref{sec-upo.i} \ \ \ Pseudodivision in $R[x]$

\verb#      # {\tt :: CommutativeRing a => UPol a -> UPol a -> UPol a}

\verb#      # The remainder is returned as described in 
              (\cite{Kn}, Volum 2, section 4.6.1).
\medskip
\\
{\tt upolSubst} \ \ \ref{sec-upo.i} \ \ Substitutes $g$ into $f$

\verb#     # 
         {\tt :: CommutativeRing a => UPol a -> UPol a -> [UPol a] -> UPol a}

\verb#     # Powers [$g^2, g^3$, \ldots] either are given or computed by 
             Horner scheme.
\medskip
\\
{\tt upRing} \ \ \ref{sec-up} \ \ \ {\tt :: Ring a => ADomDom a}
\medskip
\\
{\tt up-function} \ \ (\ref{sec-prp.ske}, UP), \ref{sec-up}

\verb#     # function that builds a base bundle from initial bundle composing

\verb#     # 
        several base-operations. Example: {\tt upRing (1,1) Map.empty -> (dD,rR)}
\medskip
\\
{\tt vandermondeMt} \ \ \ref{sec-mt.f} \ \ \ 
                        {\tt :: MulMonoid a => [a] -> [[a]]}

\verb#      # Vandermonde matrix: \ 
              $ [a_0,\ldots,a_n] \rightarrow \ [[a_i^j \ldots] | \ldots]] $
\medskip
\\
{\tt varP} \ \ \ref{sec-pl} \ \ (usable for univariate case)

\verb#        # {\tt :: (PolLike p, CommutativeRing a) => a -> p a -> p a}

\verb#             \a f -> head . varPs a f #       
\medskip
\\ 
{\tt varPs} \ \ \ref{sec-pl} \ \ \ 
                {\tt :: CommutativeRing a => a -> p a -> [p a]}

\verb#      # 
        operation from constructor class {\tt PolLike}: convert variables from 

\verb#      # {\tt f} \ multiplied by given non-zero coefficient to \ {\tt p a}
\medskip
\\
{\tt varToRPol} \ \ \ref{sec-rpol.d} 

\verb#      # {\tt :: AddSemigroup a => RPol a -> a -> RPolVar -> RPol a}

\verb#      # 
        makes r-pol $a \cdot v$ after given r-pol sample, coefficient, variable
\medskip
\\  
{\tt varToRPol'} \ \ \ref{sec-rpol.d} \ \  makes r-pol' \ $a \cdot v$ 

\verb#         # {\tt :: AddSemigroup a => a -> RPolVar -> RPol' a}
\medskip
\\
{\tt vecHead} \ \ \ref{sec-vec.f} \ \ \ {\tt :: Vector a -> a}

       \verb#           \v -> case vecRepr v of {x:_ -> x;  _ -> error ...}#
\medskip
\\
{\tt VecMatr} \ \ \ref{sec-dme}, \ref{sec-vec}, \ref{sec-mt} \ \ 
                  {\tt DoCon} module exporting items for vectors, maetrices
\medskip
\\
{\tt vecMax} \ \ \ref{sec-pp.d} \ \ \ 
             {\tt :: Ord a => Vector a -> Vector a -> Vector a}

  \verb#              \v -> Vec . (zipWith max) (vecRepr v) . vecRepr#
\medskip
\\
{\tt vecMutPrime} \ \ \ref{sec-pp.d} \ \ \ 
                  {\tt :: AddMonoid a => Vector a -> Vector a -> Bool}

\verb#      \v -> case zeroS $ vecHead v of#
 
\verb#      z -> and . (zipWith (\x y -> (x==z||y==z))) (vecRepr v) . vecRepr#
\medskip
\\
{\tt VecPol} \ \ \ref{sec-polv.i.vp} \ \ \
                             {\tt data VecPol a = VP ![Pol a] !EPPOTerm}

\verb#     # 
        representation for \ {\tt Vector (Pol a)}. \ It provides a field for 

\verb#      # extended pp ordering. This makes a free module with grading.
\medskip
\\
{\tt vecPolToEPol} \ \ \ref{sec-polv.e.i} \ \ Inverse to {\tt epolToVecPol}

\verb#      # 
             {\tt :: CommutativeRing a => EPPOTerm -> Vector (Pol a) -> EPol a}
\medskip
\\  
{\tt vecRepr} \ \ \ref{sec-vec.f} \ \ \ 
                  \verb#(\ Vec xs -> xs) :: Vector a -> [a]#
\medskip
\\
{\tt vecSize} \ \ \ref{sec-vec.f} \ \ \ 
                      {\tt (genericLength . vecRepr) :: Vector a -> Z}
\medskip
\\
{\tt vecTail} \ \ \ref{sec-vec.f} \ \ \ {\tt :: Vector a -> [a]}

       \verb#           \v -> case vecRepr v of {_:xs -> xs;  _ -> error ...}#
\medskip
\\
{\tt Vector} \ \ \ref{sec-vec} \ \ \ Direct power of a domain

\verb#     # 
    {\tt newtype Vector a = Vec [a] deriving (Eq)}  \ \ non-empty list required

\verb#     # 
         {\tt Vector a} \ denotes a parametric family of vector domains \ldots
\medskip
\\
{\tt WithCanAssoc} \ \ \ref{sec-gcd} \ \ \ \verb#:: Property_GCDRing#

{\tt (WithCanAssoc, Yes)}  means  {\tt canAssoc, canInv}, are correct 

\verb#   # 
   algorithms for the canonical associated element, canonical invertible factor
\medskip
\\
{\tt WithFactor} \ \ \ref{sec-ftr} \ \ \ \verb#:: Property_FactrRing#

{\tt (WithFactor, Yes)} means {\tt factor} is correct factorization
\medskip
\\
{\tt WithGCD} \ \ \ref{sec-gcd} \ \ \ \verb#:: Property_GCDRing#

\verb#           # {\tt (WithGCD, Yes)} means  {\tt (Factorial, Yes)} and 

{\tt gcD} a correct algorithm for greatest common divisor of a list
\medskip
\\
{\tt WithIsPrime} \ \ \ref{sec-ftr} \ \ \ \verb#:: Property_FactrRing#

{\tt (WithIsPrime,Yes)} means {\tt isPrime} is a correct primality test
\medskip
\\
{\tt WithPrimeField} \ \ see \ref{sec-rg.sub}, \verb#Operation_Subring#

\verb#             # name for one of items in \verb#Operations_Subring#.
\medskip
\\
{\tt WithPrimeField'} \ \ see \ref{sec-rg.sub}, \verb#Operation_Subring#

\verb#           # data constrtuctor for {\tt WithPrimeField}
\medskip
\\
{\tt WithPrimeList} \ \ \ref{sec-ftr} \ \ \ \verb#:: Property_FactrRing#

         {\tt (WithPrimeList, Yes)} means \verb#(primes _)# is correct 
         method for list of primes
\medskip
\\ 
{\tt WithSyzygyGens} \ \ \ref{sec-linr.t} \ \ \
                     \verb#:: Property_LinSolvRing#

\verb#      # {\tt (WithSyzygyGens, Yes)} means \verb#(syzygyGens <anyMode>)#

\verb#      # is a correct algorithm for the linear relation generators
\medskip
\\
{\tt Z} \ \ \ref{sec-dprel} \ \ \ {\tt type Z = Integer} \ \ ignore {\tt Int}

\verb#      # 
          {\tt DoCon} treats this {\tt Haskell} type as model of Ring of Integers, 

\verb#      # 
       supplies it with the instances \ {\tt EuclideanRing, OrderedRing} \ldots
\medskip
\\ 
{\tt zeroEPol} \ \ \ref{sec-polv.e.i} \ \ \ 
               \verb#(\t f -> EPol [] t f) :: EPPOTerm -> Pol a -> EPol a#
\medskip
\\
{\tt zeroFr} \ \ \ref{sec-fr.i} \ \ \ 
             \verb#(\x-> (zeroS x):/(unity x)) :: Ring a => a -> Fraction a#
\medskip
\\
{\tt zeroIdeal} \ \ \ref{sec-il.g.fn} \ \ \
                \verb#:: Properties_Ideal -> Subring a -> Ideal a#

\verb#     # 
      Zero ideal in non-zero base ring. Some ideal properties given in argument
\medskip
\\
{\tt zeroS} \ \ \ref{sec-smg.fn} \ \ \ {\tt :: AddSemigroup a => a -> a}

\verb#      # 
         makes zero from sample: \ composed \ \verb#zero_m# \ and \ {\tt error}
\medskip
\\
{\tt zeroSubring} \ \ \ref{sec-rg.fn} \ \ \ 
                      {\tt :: a -> Subring a -> Subring a}

\verb#               # zero subring in a non-zero base ring
\medskip
\\
\verb#zero_m# \ \ \ref{sec-smg.a} \ \ \ 
              {\tt :: a -> Maybe a} \ \ makes zero from sample.

\verb#      # 
        Operation from {\tt AddSemigroup} category. Relies on {\tt subsmgUnity}
\medskip
\\
{\tt zipRem} \ \ \ref{sec-dprel} \ \ \ 
                 {\tt :: [a] -> [b] -> ([(a,b)], [a], [b])}

\verb#              # version of {\tt zip} that preserves remainders
\medskip
\\
{\tt Z module} \ \ \ref{sec-dme}, \ref{sec-z} 

\verb#       #  
{\tt DoCon}  module exporting operations and instances for \ 
{\tt Z = Integer}


\end{document}

