<?xml version="1.0" encoding="us-ascii"?>
<!-- XML document for the CoCoA online help system -->
<!-- last modified 28 March 2014 -->
<!-- STRUCTURE:  -->
<!--  help         -->
<!--    version    -->
<!--    command    -->
<!--    command    -->
<!--     ...   (a separate entry for each CoCoA command -->
<!--    command    -->
<!--    part       -->
<!--    part       -->
<!--     ...   (a separate entry for each manual part -->
<!--    part       -->

<!-- TODO LIST -->
<!-- 1. Make TODO list. -->

<help>

<!--The 'version' appears in a few places in the manual. -->
<!--It would be nice to have to change only the version stuff here, -->
<!--i.e., just once, when revising the manual -->
  <version>
    <man_version>3.0</man_version>
    <cocoa_version>5.1.1</cocoa_version>
    <date>July 2014</date>
  </version>

<!--A description of the structure of the help system-->
  <description>

-- This package provides online help for CoCoA.  The online help
-- consists of two parts: a manual and a list of commands.
-- Each section of the manual and each command is uniquely identified
-- by a set of keywords.  The online help command <tt>H.Man</tt> takes a string from
-- the user and searches for a match among the keywords.  If a match
-- is found, the corresponding description is sourced from the
-- appropriate file, kept in the directory <tt>man</tt> inside the CoCoA
-- directory.  The set of keywords always includes the title of the
-- section or the title of the command.
-- Each command is associated with a list of topics.  (This applies
-- only to commands, not to sections of the manual.)
-- The online help function <tt>H.Commands</tt> takes a string from
-- the user and searches for all matches among these topics.  For each
-- match, the title of the command and a brief description is
-- displayed.  For instance, the user may give the string <em>poly</em> to
-- find all commands having to do with polynomials.  Information about
-- a specific command can then be retrieved with <tt>H.Man</tt>.
--
-- Information about the other online help functions and more details
-- concerning <tt>H.Man</tt> and <tt>H.Commands</tt> can be found through the online
-- help system itself.  To get started, set up the help package as
-- described below,  start CoCoA, and enter <tt>H.Man()</tt>, with no arguments.
--
-- Note: in a CoCoA session, the command <tt>Man</tt> is synonymous with
-- <tt>H.Man</tt>.  When one of these commands is first issued, CoCoA
-- automatically loads the help package.
--
-- TABLE OF CONTENTS FOR THE PACKAGE
-- * Create the manual
--     initializes the global variable, MEMORY.Doc
-- * CoCoA Commands
--     Comms() defined; it creates the commands part of online help
-- * Chapters of the Manual
--     functions ChapM_N() defined; they create the online manual
-- * The Online Help Functions
--     Functions for searching and displaying the manual
--
-- STRUCTURE OF THE VARIABLE, MEMORY.Doc
-- MEMORY.Doc is a record.
--   &quot;.Parts: a list of the parts of the manual.
--     &quot;[K].Name: a string naming part K.
--     &quot;[K].Chapters: a list of chapters in part K.
--       &quot;[L]: a record of the sections of Chapter L.
--       &quot;[L].Name: name for Chapter L.
--       &quot;[L].Sections: a list of sections in chapter L.
--         &quot;[M].SectionType: integer used for nesting sections.
--         &quot;[M].Title: the Title of section M.
--         &quot;[M].Keys: keywords for search, *must be lower-case*!
--         &quot;[M].Descr: main contents of section M.
--         &quot;[M].See: list of strings for related topics in the manual.
--   &quot;.ChapterTitles: a list of decapped chapter titles (speeds up searching)
--   &quot;.Commands: a list of CoCoA commands and functions.
--     &quot;[K].Title: name of the command.
--     &quot;[K].ShortDescr: short description for the command.
--     &quot;[K].Syntax: syntax for the command.
--     &quot;[K].Descr: description of the command.
--     &quot;[K].See: list of strings for related topics in the manual.
--     &quot;[K].Types: a list of strings giving the types for the arguments,
--               for use with the functions Commands();
--     &quot;[K].Keys: keywords with which to find this command.
--                The keys must uniquely define this entry among
--                the commands *and* among the Sections above.
--   &quot;.Pointer: a list used by the Browse function to determine which
--              section of the manual or which command to
--              print.  The format is: [<em>manual</em>, [P,C,S]]
--              or [<em>commands</em>, Com]
--              where P, C, S are the part, chapter, and section numbers,
--              respectively, and Com is the command number.
--
--
</description>
<!--The following section records changes to the manual with each version.-->
  <changes>
-- VERSION 0.2
-- 1. <tt>Man</tt> now also checks chapter titles for matches.  If an exact
-- match is made, the first section of the chapter is displayed.
-- 2. A new field has been added to MEMORY.Doc called
-- MEMORY.Doc.ChapterTitles consisting of the decapped chapter
-- titles.  It is used to speed up the search for matches among chapter
-- titles.  Otherwise, the decap function slows the search down too
-- much.
--
-- IMPORTANT NOTE: <type>I</type>f a chapter is added, then its title must be added
-- to this field.
--
-- 3. Various typos have been fixed and clarifications have been
-- made.  Some new commands have been documented.
-- 4. <tt>H.Toc</tt> has been changed so that <tt>H.Toc()</tt>; displays only
-- chapter titles.  To see the full table of contents, one must now
-- type <tt>H.Toc(<quotes>all</quotes>)</tt>.
-- 5. <tt>H.Chapters</tt> is hidden from view, and its entry is removed from
-- the manual.
-- 6. <tt>Decap</tt> checks for type.
--
-- VERSION 0.3
-- 1. Corrected miscellaneous typos.
-- 2. Added documentation for the new functions dealing with ideals of
--    points.  Added documentation for <tt>EvalHilbertFn</tt>.
--
-- VERSION 0.4
-- 1. corrected typos, added documentation for miscellaneous new
--    functions.
--
-- VERSION 0.5
-- 1. corrected typos, added documentation for miscellaneous new
--    functions.
--
-- VERSION 0.6
-- 1. usual stuff
-- 2. fixed bug in search function (adding <tt>PotentialFlag</tt> variable).
--
-- VERSION 1.0, 1.1
-- 1. updated entries
--
-- VERSION 1.2
-- 1. updated entries
-- 2. Replace GetEnv(<quotes>COCOA_LIBRARY</quotes>) with CocoaLibrary() (and changed
--    <tt>lib</tt> to <tt>/lib/</tt>).
--
-- VERSION 1.3
-- 1. updated entries
-- 2. <tt>Man</tt> is now called with ?
--
-- VERSION 1.4
-- 1. updated entries
  </changes>

<!-- **************************************** -->
<!-- A big list of CoCoA commands appear next -->
<!-- **************************************** -->
<cocoa_commands>

 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>Special Characters</title>

<!-- ===  COMMAND  =============================================== -->
<command>
<title>operators, shortcuts</title>
<short_description>Special characters equivalent to commands</short_description>

<syntax>
A := B   A:variable, B:OBJECT
A = B    A,B:OBJECT
A &lt;&gt; B   A,B:OBJECT
[...]    LIST
[..|..]  LIST
L[N]     N: <type>INT</type>, L: <type>LIST</type>
A..B     A,B: <type>INT</type>  or  A,B:indeterminates
R.F      R:RECORD and F field name
R ::= ... R:variable
A &gt;&lt; B   A,B: LIST
M : N    M, N: <type>MODULE</type> or <type>IDEAL</type>
R/I      R: <type>RING</type>, I: <type>IDEAL</type>
S[N]     N: <type>INT</type>, S: <type>STRING</type>
***E***  E:expression
?S       S: <type>STRING</type>
&lt;&lt; S     S: <type>STRING</type>
</syntax>
<description>
<tt>A := B;</tt> compute <tt>B</tt> then assign the result to <tt>A</tt>
<tt>A = B</tt>   test whether <tt>A</tt> and <tt>B</tt> are equal
<tt>A &lt;&gt; B</tt>  test whether <tt>A</tt> and <tt>B</tt> are not equal
<tt>[...]</tt>   build a new list (see <ttref>List Constructors</ttref>)
<tt>[..|..]</tt>   build a new list (see <ttref>List Constructors</ttref>)
<tt>L[N]</tt>    access <tt>N</tt>-th entry of list <tt>L</tt> (indexes start from 1)
<tt>A..B</tt>    is the <ref>Range Operator</ref>
<tt>R.F</tt>     <ref>record field selector</ref> for field named <tt>F</tt> of record <tt>R</tt>
<tt>R ::= </tt>  for the special ring syntax (<ref>NewPolyRing</ref>)
<par/>
<tt>A &gt;&lt; B</tt>  equivalent to <tt>CartesianProduct(A, B)</tt>, <tt>CartesianProductList([A,B])</tt>
<tt>M : N</tt>   equivalent to <tt>colon(M, N)</tt>
<tt>R/I</tt>     equivalent to <tt>NewQuotientRing(R,I)</tt>

<tt>S[N]</tt>    access <tt>N</tt>-th char of string <tt>L</tt> (indexes start from 1)
<tt>***E***</tt>   interpret <tt>E</tt> in <ttref>CoCoA-4 mode</ttref>

<tt><formula>&lt;&lt; S</formula></tt>  OBSOLESCENT equivalent to <tt>source(S)</tt>
<par/>
<tt>? string</tt> prints the manual page for <tt>string</tt>, or a list of matching manual pages
</description>

<seealso>
  <see>colon</see>
  <see>List Constructors</see>
  <see>CartesianProduct, CartesianProductList</see>
  <see>NewPolyRing</see>
  <see>NewQuotientRing</see>
  <see>record field selector</see>
  <see>Range Operator</see>
  <see>source</see>
  <see>Manual</see>
  <see>Character Set and Special Symbols</see>
  <see>CoCoA Operators</see>
</seealso>

<keys>
  <key>operator</key>
  <key>:</key>
  <key>:=</key>
  <key>::=</key>
  <key>/</key>
  <key>&lt;&lt;</key>
</keys>
</command>

<!--   <title>..</title> -->
<!--   <title>:</title> -->
<!--   <title><formula>&lt;&lt;</formula></title> -->
<!--   <title><formula>&gt;&lt;</formula></title> -->
<!--   <title>?</title> -->
<!--   <title>@</title> -->

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>A</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>abs</title>
  <short_description>absolute value of a number</short_description>

<syntax>
abs(N: <type>INT</type>): <rtn>INT</rtn>
abs(N: <type>RAT</type>): <rtn>RAT</rtn>
abs(N: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the absolute value of <tt>N</tt>.
If <tt>N</tt> is a <tt>RINGELEM</tt> then it must belong to an ordered ring.
<example>
/**/  abs(-3);
3

/**/  abs(-2/3);
2/3
</example>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>adjoint</title>
  <short_description>adjoint matrix</short_description>
<syntax>
adjoint(M: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the adjoint matrix of the square matrix <tt>M</tt>.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  adjoint(mat([[x,y,z],[t,y,x],[x,x^2,x*y]]));
matrix([
 [-x^3 +x*y^2, -x*y^2 +x^2*z, x*y -y*z],
 [-t*x*y +x^2, x^2*y -x*z, -x^2 +t*z],
 [t*x^2 -x*y, -x^3 +x*y, -t*y +x*y]
]

/**/   Z5 := NewRingFp(5);
/**/   adjoint(matrix(Z5, [[1,2],[3,1]])); 
matrix( /*FFp(5)*/
 [[1, -2],
  [2, 1]])
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AffHilbert</title>
  <short_description>the affine Hilbert function</short_description>
<syntax>
AffHilbert(R: <type>RING</type> or TAGGED("Quotient")): TAGGED("$hp.Hilbert")
AffHilbert(R: <type>RING</type> or TAGGED("Quotient"), N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
Same as <ttref>AffHilbertFn</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AffHilbertFn</title>
  <short_description>the affine Hilbert function</short_description>
<syntax>
AffHilbertFn(R: <type>RING</type>): TAGGED("$hp.Hilbert")
AffHilbertFn(R: <type>RING</type>, N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
The first form of this function computes the affine Hilbert function for R.
The second form computes the N-th value of the affine Hilbert function.  The
weights of the indeterminates of R must all be 1.  For repeated
evaluations of the Hilbert function, use <ttref>EvalHilbertFn</ttref>
instead of <tt>AffHilbertFn(R, N)</tt> in order to speed up execution.
<par/>
The coefficient ring must be a field.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  AffHilbert(R/ideal(z^4-1, x*z^4-y-3));
H(0) = 1
H(1) = 3
H(t) = 4t - 2   for t >= 2
</example>
</description>
<seealso>
  <see>AffHilbertSeries</see>
  <see>EvalHilbertFn</see>
  <see>HilbertPoly</see>
  <see>HVector</see>
  <see>HilbertSeries</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AffHilbertSeries</title>
  <short_description>the affine Hilbert-Poincare series</short_description>
<syntax>
AffHilbertSeries(TAGGED("Quotient")):TAGGED("$hp.PSeries")
</syntax>
<description>
This function computes the affine Hilbert-Poincare series of M.
The grading must be a positive <formula>Z^1</formula>-grading (i.e. <ttref>GradingMat</ttref>
must have a single row with positive entries), and the ordering must
be degree compatible.
In the standard case, i.e. the weights of all
indeterminates are 1, the result is simplified so that the power
appearing in the denominator is the dimension of M + 1.
<par/>
It is exactly the same as <ttref>AffPoincare [OBSOLESCENT]</ttref>.
<par/>
NOTES:
<par/>
(i) the coefficient ring must be a field.
<par/>
(ii) these functions produce tagged objects: they cannot safely be
     (non-)equality to other values.
<par/>
For further details on affine Hilbert functions see the book:
Kreuzer, Robbiano <quotes>Computer Commutative Algebra II</quotes>, Section 5.6.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  AffHilbertSeries(R/ideal(z^4-1, x*z^4-y-3));
(1 +x +x^2 +x^3) / (1-x)^2
</example>
</description>
<seealso>
  <see>AffHilbertFn</see>
  <see>HilbertSeries</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AffPoincare [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT]the affine Hilbert-Poincare series</short_description>
<syntax>
[OBSOLESCENT] AffPoincare(TAGGED("Quotient")):TAGGED("$hp.PSeries")
</syntax>
<description>
Same as <ttref>AffHilbertSeries</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>alias</title>
  <short_description>define aliases for package names</short_description>

<syntax>
alias B_1,...,B_r

where each B_i is a <em>binding</em> of the form: Identifier := $PackageName
</syntax>
<description>
This function is for declaring both global and local aliases for
package names.  Recall that package names are meant to be long in
order to avoid conflicts between the names of functions that are read
into a CoCoA session.  However, it is inconvenient to have to type out
the long package name when referencing a function.  So the user
chooses an alias to take the place of the package name; the alias is
just a means to avoid typing.
<par/>
1.  Global aliases.  To avoid typing the full package name as a prefix
to package functions, one may declare a short global alias during a
CoCoA session.  A list of the global aliases is produced by the
function <ttref>aliases</ttref>.  For examples, see the chapter on packages in the
manual, in particular the section, <ref>Global Aliases</ref>.  Online, enter
<tt>?global aliases</tt>.
<par/>
2.  Local aliases.  A local alias has the same syntax as a global
alias, however it appears inside a package definition.  The local
aliases work only inside the package and do not conflict with any
global aliases already defined.  In fact, in order to avoid conflicts,
global aliases are not recognized within a package.  For examples,
again look in the chapter for packages.

<example>
/**/  alias LL := $abcd;
/**/  aliases();

Coclib       = $coclib
Approx       = $approx
(...) 
TP           = $contrib/thmproving
TV           = $contrib/typevectors
LL           = $abcd
</example>
</description>


<seealso>
  <see>aliases</see>
  <see>Introduction to Packages</see>
</seealso>

<types>
  <type>packages</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>aliases</title>
  <short_description>list of global aliases</short_description>

<syntax>
aliases():TAGGED("aliases")
</syntax>
<description>
This function prints a list of global aliases for packages. Aliases
are formed with the function <ttref>alias</ttref>.

<example>
/**/  alias LL := $abcd;
/**/  aliases();

Coclib       = $coclib
Approx       = $approx
(...)
TP           = $contrib/thmproving
TV           = $contrib/typevectors
LL           = $abcd
</example>
</description>


<seealso>
  <see>alias</see>
  <see>Introduction to Packages</see>
</seealso>

<types>
  <type>packages</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<!-- <command> -->
<!--   <title>All CoCoA commands</title> -->
<!-- <description> -->
<!-- This is a (work in progress) complete list of all CoCoA commands: -->
<!-- <commands_and_functions_for type="command"></commands_and_functions_for> -->
<!-- </description> -->
<!-- <keys> -->
<!--   <key>allcommands</key> -->
<!--   <key>allcocoacommands</key> -->
<!-- </keys> -->
<!-- </command> -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AlmostQR</title>
  <short_description>QR decomposition of a matrix</short_description>

<syntax>
AlmostQR(M: <type>MAT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function computes the decomposition of the matrix into an
orthogonal and an upper triangular matrix with 1 on the diagonal.
[<em>orthogonal</em> meaning that <formula>Q<sup>T</sup> * Q</formula> is a diagonal matrix]

<par/>
The auxiliary (possibly slow!) function <tt>Mat.SimplifySquareFactorsInAQR</tt>
modifies Q and R in the decomposition so that the entries of the diagonal
matrix <formula>Q<sup>T</sup> * Q</formula> are squarefree rationals.

<example>
/**/  M := matrix(QQ, [ [4, -2, 3],  [3, 2, -2],  [0, 0, 3] ]);
/**/  Dec := AlmostQR(M);
/**/  Dec;
record[Q := matrix(QQ,
 [[4, -42/25, 0],
  [3, 56/25, 0],
  [0, 0, 3]])
, R := matrix(QQ,
 [[1, -2/25, 6/25],
  [0, 1, -17/14],
  [0, 0, 1]])
]

/**/  $mat.SimplifySquareFactorsInAQR(ref Dec);
/**/  Dec;
record[Q := matrix(QQ,
 [[4/5, -3/5, 0],
  [3/5, 4/5, 0],
  [0, 0, 1]])
, R := matrix(QQ,
 [[5, -2/5, 6/5],
  [0, 14/5, -17/5],
  [0, 0, 3]])
, SqDiag := [1, 1, 1]]
</example>
</description>


<seealso>
  <see>Matrix Normal Form</see>
</seealso>

<keys>
  <key>qr decomposition</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>and</title>
  <short_description>boolean "and" operator</short_description>
<syntax>
A and B       (where A, B: <type>BOOL</type>, return <rtn>BOOL</rtn>)
</syntax>
<description>
This operator represents the logical conjunction of <tt>A</tt> and <tt>B</tt>.
CoCoA first evaluates <tt>A</tt>; if that gives <tt>false</tt> then the result
is <tt>false</tt>, and <tt>B</tt> is not evaluated.  Otherwise if <tt>A</tt> gives <tt>true</tt>
then <tt>B</tt> is evaluated, and its value is the final result.
<example>
/**/  A := -1;
/**/  A >= 0 and isqrt(A) &lt; 10;  --> calls isqrt only if A >= 0
false
</example>
</description>

<keys>
  <key>&amp;</key>
  <key>&amp;&amp;</key>
  <key>boolean operator</key>
  <key>logical operator</key>
  <key>logical and</key>
  <key>conjunction</key>
</keys>

<seealso>
  <see>or</see>
  <see>not</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>append</title>
  <short_description>append an object to a list</short_description>
<syntax>
append(ref L: <type>LIST</type>, E: <type>OBJECT</type>)
</syntax>
<description>
Append the object <tt>E</tt> to the list <tt>L</tt>; this call returns nothing!
<par/>
NOTE: the old CoCoA-4 syntax <tt>Append(L, E)</tt> is still allowed, but
produces a warning; replace the call by <tt>append(ref L, E)</tt>.
<example>
  /**/  Use R ::= QQ[t,x,y,z];
  /**/  L := [1,2,3];
  /**/  append(ref L, 4);
  /**/  L;
  [1, 2, 3, 4]
</example>
</description>
<seealso>
  <see>ref</see>
  <see>concat</see>
  <see>ConcatLists</see>
  <see>remove</see>
</seealso>

</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>apply</title>
  <short_description>apply homomorphism</short_description>

<syntax>
apply(phi: <type>RINGHOM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
apply(phi: <type>RINGHOM</type>, X: <type>LIST</type>): <rtn>LIST</rtn>
apply(phi: <type>RINGHOM</type>, X: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
Apply homomorphism <tt>phi</tt> to all elements in second argument <tt>X</tt>
(<tt>RINGELEM</tt>, <tt>LIST</tt>, or <tt>MAT</tt>)
<par/>
When <tt>X</tt> is of type <tt>RINGELEM</tt> this is equivalent to the
natural syntax <tt>phi(X)</tt>.
<example>
/**/ Use R ::= QQ[x,y,z];
/**/ S ::= QQ[x[1..3]];
/**/ phi := PolyAlgebraHom(R, S, indets(S));
/**/ apply(phi, [x^2-y, z-2]);
[x[1]^2 -x[2], x[3] -2]

/**/ apply(phi, x^2-y);  -- same as phi(x^2-y)
x[1]^2 -x[2]
/**/ phi(x^2-y);
x[1]^2 -x[2]
</example>
</description>


<seealso>
  <see>PolyAlgebraHom</see>
  <see>CanonicalHom</see>
</seealso>

<keys>
  <key>map</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ApproxSolve</title>
  <short_description>Approximate real solutions for polynomial system</short_description>
<syntax>
ApproxSolve(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of LIST of <rtn>RAT</rtn>
</syntax>
<description>
This function returns the list of real solutions (points) of a
0-dimensional polynomial system <tt>L</tt>.
Works only if with rational coefficients.
Approximate coordinates are given for non-rational solutions.
<par/>
See also <ttref>RationalSolve</ttref>
<example>
/**/ Use QQ[x,y,z];
/**/ L := [x^3-y^2+z-1, x-2, (y-3)*(y+2)];
/**/ RationalSolve(L);
[[2, -2, -3], [2, 3, 2]]
/**/ ApproxSolve(L);
[[2, -2, -3], [2, 3, 2]]

/**/ L := [x^3-y^2+1, (y-3)*(y+2), z];
/**/ indent(ApproxSolve(L));
[
  [167001090947516369641767378634802431634869700965461961120334511774287062707365/115792089237316195423570985008687907853269984665640564039457584007913129639936, -3105036184601417870297958976925005110513772034233393222278104076052101905372785086417905610616594068048936176388754598241094647389028646910227375835339689773298904914910878292075930186409206203488239052651022151060681311443956437155/1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816057856, 0],
  [2, 3, 0]
]

/**/ L := [x^3-y^2+z-1, x^2-2, (y-3)*(y+2)];
/**/ Pts := ApproxSolve(L);
--> [[17564737135690137373...
/**/ indent([[ DecimalStr(coord,10) | coord in pt] | pt in Pts]);
[
  ["1.4142135624", "-2.0000000000", "2.1715728753"],
  ["1.4142135624", "3.0000000000", "7.1715728753"],
  ["-1.4142135624", "-2.0000000000", "7.8284271247"],
  ["-1.4142135624", "3.0000000000", "12.8284271247"]
]

-- Verify we have an approximate answer:
/**/ indent([ [ FloatStr(eval(f, pt)) | f In L ] | pt In Pts]);
[
  ["-3.2567*10^(-76)", "-6.2932*10^(-77)", "2.3668*10^(-76)"],
  ["-1.3971*10^(-77)", "8.1808*10^(-78)", "2.5541*10^(-77)"],
  ["-3.7110*10^(-77)", "8.1808*10^(-78)", "2.5541*10^(-77)"],
  ["7.7208*10^(-77)", "3.2902*10^(-77)", "-1.2374*10^(-76)"]
]
</example>
</description>
<seealso>
  <see>LinSolve</see>
  <see>RationalSolve</see>
</seealso>
<keys>
  <key>polynomial system solving</key>
  <key>polynomialsystemsolving</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ascii</title>
  <short_description>convert between characters and ascii code</short_description>

<syntax>
ascii(N: <type>INT</type>): <rtn>STRING</rtn>
ascii(L: <type>LIST</type> of <type>INT</type>): <rtn>STRING</rtn>
ascii(S: <type>STRING</type>): <rtn>LIST</rtn> of <type>INT</type>
</syntax>
<description>
In the first form, <tt>ascii</tt> returns the character whose ASCII code is <tt>N</tt>.
<par/>
In the second form, <tt>ascii</tt> returns the string whose characters, in
order, have the ASCII codes listed in <tt>L</tt>.
<par/>
The third form is the inverse of the second: it returns the ASCII codes
of the characters in <tt>S</tt>.

<example>
/**/  ascii(97);
a

/**/  C := ascii("hello world");
/**/  C;
[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

/**/  ascii(C);
hello world
</example>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AsINT</title>
  <short_description>convert into an INT</short_description>
<syntax>
AsINT(N: <type>INT</type>): <rtn>INT</rtn>
AsINT(N: <type>RAT</type>): <rtn>INT</rtn>
AsINT(N: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
If the argument is an integer value this function returns this value as
an INT, otherwise it throws an error.
<example>
/**/  Use P ::= QQ[x,y];
/**/  type(LC(3*x-y));
RINGELEM
/**/ type(AsINT(LC(3*x-y)));
INT
-- /**/ type(AsINT(LC((3/2)*x-y)));  --> !!! ERROR !!!
</example>
</description>
<seealso>
  <see>AsRAT</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convertto</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>AsRAT</title>
  <short_description>convert into a RAT</short_description>
<syntax>
AsRAT(N: <type>INT</type>): <rtn>RAT</rtn>
AsRAT(N: <type>RAT</type>): <rtn>RAT</rtn>
AsRAT(N: <type>RINGELEM</type>): <rtn>RAT</rtn>
</syntax>
<description>
If the argument is a rational value this function returns this value as
a RAT, otherwise it throws an error.  Note that if the argument is
actually an integer the result is nevertheless a RAT (with denominator 1).
<example>
/**/  Use P ::= QQ[x,y];
/**/  type(LC(3*x-y));
RINGELEM
/**/ type(AsRAT(LC(3*x-y)));
RAT
</example>
</description>
<seealso>
  <see>AsINT</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convertto</key>
</keys>
</command>

</chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>B</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BaseRing</title>
  <short_description>the base ring of a ring</short_description>

<syntax>
BaseRing(RmodI: (Quotient)<type>RING</type>: <rtn>RING</rtn>
BaseRing(K: (Fraction Field)<type>RING</type>): <rtn>RING</rtn>
</syntax>
<description>
This function gives the "base ring" of a given ring; <i>e.g.</i> if <tt>K</tt>
was constructed as the fraction field of <tt>R</tt> then <tt>BaseRing(K)</tt>
produces <tt>R</tt>.  All rings in CoCoA are derived from <tt>ZZ</tt> via
various steps; <tt>BaseRing</tt> gives the ring which is one step closer to
<tt>ZZ</tt>.

<example>
/**/  Fpx ::= ZZ/(7)[x];
/**/  Fp := BaseRing(Fpx); --> ZZ/(7)
/**/  BaseRing(Fp) = ZZ;
true
</example>
</description>

<seealso>
  <see>NewFractionField</see>
  <see>NewQuotientRing</see>
  <see>NewPolyRing</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BBasis5</title>
  <short_description>Border Basis of zero dimensional ideal</short_description>

<syntax>
BBasis5(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function is implemented in ApCoCoALib by Stefan Kaspar.
<par/>
The function <tt>BBasis5</tt> calls the CoCoAServer to compute
a Border Basis of zero dimensional ideal I.

<example>
  Use QQ[x, y], DegLex;
  I := ideal([x^2, xy + y2]);
  BBasis := BBasis5(I);
</example>
</description>


<seealso>
</seealso>
<keys>
  <key>apcocoalib</key>
  <key>border basis</key>
  <key>author: kaspar</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BettiDiagram</title>
  <short_description>the diagram of the graded Betti numbers</short_description>
<syntax>
BettiDiagram(X: <type>IDEAL</type> or (quotient)<type>RING</type> or <type>MODULE</type>)
</syntax>
<description>
This function computes the (<quotes>Macaulay-style</quotes>) Betti
diagram for <tt>M</tt>.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  I := ideal(x^2-y*t, x*y-z*t, x*y);
/**/  RES := res(I);
/**/  PrintRes(RES);
0 --&gt; R(-5)^2 --&gt; R(-4)^4 --&gt; R(-2)^3
/**/  B := BettiDiagram(RES);  indent(B);
Record[
  Diagram := matrix(ZZ,
 [[3, 0, 0],
  [0, 4, 2]]),
  FirstShift := 2
]
/**/  PrintBettiDiagram(B);
        0    1    2
--------------------
 2:     3    -    -
 3:     -    4    2
--------------------
Tot:    3    4    2
</example>
</description>
<seealso>
  <see>BettiMatrix</see>
  <see>PrintRes</see>
  <see>PrintBettiDiagram</see>
  <see>PrintBettiMatrix</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BettiMatrix</title>
  <short_description>the matrix of the graded Betti numbers</short_description>

<syntax>
BettiMatrix(M: <type>IDEAL</type>|<type>MODULE</type>|<type>LIST</type>Resolution)
</syntax>
<description>
This function returns the Betti matrix for <tt>M</tt>.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  I := ideal(x^2-y*t, x*y-z*t, x*y);
/**/  PrintRes(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
/**/  BettiMatrix(I);
matrix(ZZ,
 [[0, 0, 0],
  [3, 0, 0],
  [0, 0, 0],
  [0, 4, 0],
  [0, 0, 2]])
/**/  PrintBettiMatrix(I);
--   --&gt;  --&gt;   --
    0    0    0
    0    0    3
    0    0    0
    0    4    0
    2    0    0
--   --&gt;  --&gt;   --
</example>
</description>
<seealso>
  <see>PrintRes</see>
  <see>PrintBettiDiagram</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>binomial</title>
  <short_description>binomial coefficient</short_description>

<syntax>
binomial(N: <type>INT</type>, K: <type>INT</type>): <rtn>INT</rtn>
binomial(N: <type>RINGELEM</type>, K: <type>INT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function computes the binomial coefficient, <em>N choose K</em>
according to the formula <formula>(N)(N-1)(N-2)...(N-K+1) / K!</formula>
<par/>
The same formula is used if N is a polynomial.  The integer K cannot
be negative.

<example>
/**/  binomial(4,2);
6

/**/  binomial(-4,3);
-20

/**/  binomial(x^2+2*y,3);
(1/6)*x^6 +x^4*y +(-1/2)*x^4 +2*x^2*y^2 -2*x^2*y +(4/3)*y^3 +(1/3)*x^2 -2*y^2 +(2/3)*y

/**/  It = ***(x^2+2y)*(x^2+2y-1)*(x^2+2y-2)/6***;
true
</example>
</description>


<seealso>
  <see>BinomialRepr, BinomialReprShift</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BinomialRepr, BinomialReprShift</title>
  <short_description>binomial representation of integers</short_description>
  
<syntax>
BinomialRepr(N: <type>INT</type>, K: <type>INT</type>): <rtn>LIST</rtn> of <type>INT</type>
BinomialReprShift(N: <type>INT</type>, K: <type>INT</type>, Up: <type>INT</type>, Down: <type>INT</type>): <rtn>INT</rtn>

where N and K are positive.
</syntax>
<description>
The function <tt>BinomialRepr</tt> computes the <tt>K</tt>-binomial
representation of <tt>N</tt>, also called <i>Macaulay representation</i>,
<i>i.e.</i> the unique expression
<verbatim>
  N = binomial(N(K),K) + binomial(N(K-1),K-1) + ... + binomial(N(L),L)
</verbatim>
where <formula>N(K) &gt; ... &gt; N(L) &gt;= 1</formula>, for some L.
The value returned is the list <tt>[N(t) | t in 1..K]</tt>
where N(t)=0 for all <formula>t &lt; L</formula>.

<par/>
The function call <tt>BinomialReprShift(N,K,up,down)</tt> computes the integer
<verbatim>
  binomial(N(K)  +up,    K+down) +
  binomial(N(K-1)+up,(K-1)+down) +
  ... +
  binomial(N(L)  +up,    L+down)
</verbatim>
It is useful in generalizations of Macaulay&apos;s theorem characterizing
Hilbert functions.

<example>
/**/  BinRep := BinomialRepr(13,4);
/**/  BinRep;
[1, 3, 4, 5]

/**/  BinomialReprShift(13,4,1,1);
16
</example>
</description>

<seealso>
  <see>binomial</see>
</seealso>

<keys>
  <key>binexp</key>
  <key>binomial expansion</key>
  <key>macaulay expansion</key>
  <key>macaulay representation</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>block</title>
  <short_description>group several commands into a single command</short_description>

<syntax>
block C_1; ... ; C_n EndBlock;

where each C_i is a command.
</syntax>
<description>
The <tt>block</tt> command executes the commands as if they where one
command.  What this means in practice is that CoCoA will not print a
string of dashes after executing each <tt>C_i</tt>.  Thus, <tt>Block</tt> is used
on-the-fly and not inside user-defined functions.  (It has nothing to
do with declaration of local variables, for instance, as one might
infer from some other computer languages.)  The following example
should make the use of <tt>Block</tt> clear:

<example>
/**/  Print "hello "; Print "world";
hello world
-------------------------------
/**/  Block
/**/    Print "hello ";
/**/    Print "world";
/**/  EndBlock;
hello world
-------------------------------
/**/  Block
/**/    PrintLn GCD([12, 24, 96]);
/**/    PrintLn LCM([12, 24, 96]);
/**/    PrintLn GCD([x+y, x^2-y^2]);
/**/    Print LCM([x+y, x^2-y^2]);
/**/  EndBlock;

12
96
x + y
x^2 - y^2
-------------------------------
</example>
</description>


<types>
  <type>io</type>
  <type>miscellaneous</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BlockMat</title>
  <short_description>create a block matrix</short_description>
  
<syntax>
BlockMat(LIST of LIST of <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function creates a block matrix from a LIST of rows of matrices.

The following restrictions on the sizes of the matrices apply:
  in each row of matrices <tt>NumRows(M)</tt> must be constant,
and
  for all rows of matrices the total number of columns must be the same.
<par/>
The function <ttref>BlockMat2x2</ttref> has a simpler syntax for a
2x2 block matrix.
<example>
/**/  A := RowMat([1,2,3,4]);   B := RowMat([0,0]);
-- /**/  BlockMat2x2(A,B, B,A);   --> !!! ERROR !!! as expected
/**/  BlockMat([[A,B], [B,A]]);
matrix(QQ,
 [[1, 2, 3, 4, 0, 0],
  [0, 0, 1, 2, 3, 4]])
</example>
</description>

<keys>
  <key>MultiBlockMatrix</key>
</keys>

<seealso>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
  <see>ConcatHorList</see>
  <see>ConcatVerList</see>
  <see>ConcatDiag</see>
  <see>ConcatAntiDiag</see>
  <see>BlockMat2x2</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BlockMat2x2</title>
  <short_description>create a block matrix with 4 matrices</short_description>

<syntax>
BlockMat2x2(A: <type>MAT</type>,B: <type>MAT</type>,C: <type>MAT</type>,D: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function creates a block matrix.  Each entry is a matrix.
Given A, B, C, D matrices, then <tt>BlockMat(A,B,C,D)</tt> returns the matrix
<verbatim>
                | A B |
                | C D |
</verbatim>
The obvious restrictions on the sizes of the matrices apply:
<par/>
<tt>NumRows(A) = NumRows(B)</tt>  and  <tt>NumRows(C) = NumRows(D)</tt>,
and
<tt>NumCols(A) = NumCols(C)</tt>  and  <tt>NumCols(B) = NumCols(D)</tt>.
<par/>
The function <ttref>BlockMat</ttref> offers more flexibility, but
with a heavier syntax.

<example>
/**/    A := matrix([[1,2,3], [4,5,6]]);
/**/    B := matrix([[1,2], [3,4]]);
/**/    C := matrix([[1,1,1], [2,2,2], [3,3,3]]);
/**/    D := matrix([[4,4], [5,5], [6,6]]);
/**/    BlockMat2x2(A,B, C,D);
matrix(QQ,
 [[1, 2, 3, 1, 2],
  [4, 5, 6, 3, 4],
  [1, 1, 1, 4, 4],
  [2, 2, 2, 5, 5],
  [3, 3, 3, 6, 6]])
</example>
</description>

<keys>
  <key>BlockMatrix</key>
</keys>

<seealso>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
  <see>ConcatDiag</see>
  <see>ConcatAntiDiag</see>
  <see>BlockMat</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Bool01</title>
  <short_description>Convert a boolean to an integer</short_description>

<syntax>
Bool01(B: <type>BOOL</type>): <rtn>INT</rtn>
</syntax>
<description>
This function converts a boolean to an integer using the convention:
<tt>false</tt> becomes 0, and <tt>true</tt> becomes 1.

<example>
/**/  Id4 := matrix([[Bool01(i=j) | i in 1..4] | j in 1..4]);
/**/  Id4;
matrix(QQ,
 [[1, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 1, 0],
  [0, 0, 0, 1]])
</example>
</description>


</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>break</title>
  <short_description>break out of a loop</short_description>

<syntax>
break
</syntax>
<description>
This command must be used inside a loop statement (<tt>for</tt>, <tt>foreach</tt>,
<tt>repeat</tt>, or <tt>while</tt>).
When executed, the current loop statement is terminated and control
passes to the command following the loop statement.
Thus, in the case of nested loops <tt>break</tt> does <em>not</em> break
out of all loops back to the <em>top level</em> (see <tt>Return</tt>).

<example>
/**/  For I := 5 To 1 Step -1 Do
/**/    For J := 1 To 100 Do
/**/      Print J, " ";
/**/      If J = I Then PrintLn; Break; EndIf;
/**/    EndFor;
/**/  EndFor;
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
</example>
</description>


<seealso>
  <see>return</see>
</seealso>

<types>
  <type>command</type>
  <type>loops</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>BringIn</title>
  <short_description>bring in objects from another ring</short_description>

<syntax>
BringIn(E: <type>OBJECT</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
This function maps a polynomial (or a list, matrix of these) into the
current ring, preserving the names of the indeterminates.
<par/>
This function is not implemented on ideals because might be
misleading: one might expect that bringing an ideal from <tt>R[x,y]</tt>
into <tt>R[x]</tt> means eliminating <tt>y</tt>, while others might
expect the ideal generated by mapping the generators.
For example in the first case <formula>(x-y, x+y)</formula> returns the
ideal <formula>(x)</formula>, in the second case returns an error.
So, if you want to map the generators of the ideal type
<tt>ideal(BringIn(gens(I)))</tt>.
<par/>
-- Changing characteristic from non-0 to 0 is NOT YET IMPLEMENTED in CoCoA-5
When mapping from a ring of finite characteristic to one of zero
characteristic then consistent choices of image for the coefficients
are made (i.e. if two coefficients are equal mod p then their images
will be equal).
<example>
/**/  RR ::= QQ[x[1..4],z,y];
/**/  SS ::= ZZ[z,y,x[1..2]];
/**/  Use RR;
/**/  F := (x[1]-y-z)^2;  F;
x[1]^2 -2*x[1]*z +z^2 -2*x[1]*y +2*z*y +y^2

/**/  Use SS;
/**/  BringIn(F);
z^2 +2*z*y +y^2 -2*z*x[1] -2*y*x[1] +x[1]^2

/**/  Use R ::= QQ[x,y,z];
/**/  F := (1/2)*x^3 + (34/567)*x*y*z - 890; -- poly with rational coefficients
/**/  Use S ::= ZZ/(101)[x,y,z];
/**/  BringIn(F);
-50*x^3 -19*x*y*z +19
</example>
</description>
<seealso>
  <see>PolyAlgebraHom</see>
  <see>apply</see>
  <see>QZP</see>
  <see>ZPQ</see>
</seealso>

</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>C</title>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Call [OBSOLETE]</title>
  <short_description>[OBSOLETE] apply a function to given arguments</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
OBSOLETE: in CoCoA-5 functions can be used directly.
See <ref>FUNCTIONs are first class objects</ref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CanonicalHom</title>
  <short_description>canonical homomorphism</short_description>

<syntax>
CanonicalHom(R: <type>RING</type>, S: <type>RING</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
CanonicalHom(R, S) -- where R and S are rings, gives the
canonical homomorphism from R to S.
Currently it works only on the most natural constructions:
<verbatim>
ZZ -> S    QQ -> S
R -> R/I   R -> FractionFiels(R)
R -> R[x[1..N]]
</verbatim>

<example>
/**/ Use R ::= QQ[x,y];
/**/ RmodI := NewQuotientRing(R, ideal(x^2-1));

/**/ phi := CanonicalHom(R, RmodI);
/**/ phi(x^3*y);
(x*y)
/**/ RingOf(It) = RmodI;
true

/**/ RingElem(RmodI, x^3*y);  -- same as phi(x^3*y)
			      -- internally computes CanonicalHom
</example>
</description>


<seealso>
  <see>NewFractionField</see>
  <see>NewQuotientRing</see>
  <see>NewPolyRing</see>
  <see>CanonicalHom</see>
  <see>PolyAlgebraHom</see>
  <see>PolyRingHom</see>
</seealso>
<keys>
  <key>canonical homomorphism</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CartesianProduct, CartesianProductList</title>
  <short_description>Cartesian product of lists</short_description>
  
<syntax>
CartesianProduct(L1: <type>LIST</type>, L2: <type>LIST</type>, L3: <type>LIST</type>, ..): <rtn>LIST</rtn>
CartesianProductList(L: <type>LIST</type> of LIST): <rtn>LIST</rtn>
L1 &gt;&lt; L2
L1 &gt;&lt; L2 &gt;&lt; ... &gt;&lt; Ln

where each Li is a LIST
</syntax>
<description>
This command returns the list whose elements form the Cartesian product
of <formula>L_1,...,L_n</formula>.
<par/>
For the N-fold product of a list with itself, one may use <ttref>tuples</ttref>.

<example>
/**/  L1 := [1,2,3];
/**/  L2 := ["a","b"];
/**/  L1 &gt;&lt; L2 &gt;&lt; [5];  -- same as
/**/  CartesianProduct(L1, L2, [5]);  -- same as
/**/  CartesianProductList([L1, L2, [5]]);  -- this takes a list of lists
[[1, "a", 5], [1, "b", 5], [2, "a", 5], [2, "b", 5], [3, "a", 5], [3, "b", 5]]
-------------------------------
/**/  ChessBoard := (1..8)&gt;&lt;(1..8);  -- Need brackets around 1..8 otherwise
                                           -- we get a parse error.
</example>
Note that only <tt>&lt;&gt;</tt> is used for <em>not equal</em> in CoCoA.
</description>

<seealso>
  <see>CoCoA Operators</see>
  <see>operators, shortcuts</see>
  <see>tuples</see>
</seealso>

<keys>
  <key>&gt;&lt;</key>
  <key>cartesian product</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Cast [OBSOLETE]</title>
  <short_description>[OBSOLETE] type conversion</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
To cast INT, RAT, STRING to a polynomial (and more in general
to a RINGELEM) use <ttref>RingElem</ttref>.
<par/>
To cast RINGELEM to INT, RAT use <ttref>AsINT</ttref>, <ttref>AsRAT</ttref>.
<par/>
To cast LIST to MAT use <ttref>matrix</ttref>.
To cast MAT to LIST use <ttref>GetRows</ttref>, <ttref>GetCols</ttref>.
</description>
<seealso>
  <see>AsINT</see>
  <see>AsRAT</see>
  <see>gens</see>
  <see>GensAsCols, GensAsRows</see>
  <see>GetCols</see>
  <see>GetRows</see>
  <see>ideal</see>
  <see>matrix</see>
  <see>ModuleElem</see>
  <see>RingElem</see>
  <see>SubmoduleCols, SubmoduleRows</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ceil</title>
  <short_description>round rational up to integer</short_description>

<syntax>
ceil(X: <type>RAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the least integer greater than or equal to <tt>X</tt>.

<example>
/**/  ceil(0.99);
1

/**/  ceil(0.01);
1

/**/  ceil(1);
1

/**/  ceil(-0.99);
0
</example>
</description>

<seealso>
  <see>floor</see>
  <see>round</see>
  <see>num</see>
  <see>den</see>
</seealso>

<keys>
  <key>ceiling</key>
  <key>round up</key>
  <key>rounding</key>
  <key>integer part</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CFApprox</title>
  <short_description>continued fraction approximation</short_description>
<syntax>
CFApprox(X: <type>RAT</type>, MaxRelErr: <type>RAT</type>): <rtn>RAT</rtn>
</syntax>
<description>
<tt>CFApprox</tt> finds the <em>simplest</em> continued fraction approximant
to <tt>X</tt> which is within the maximum specified <em>relative error</em>.
<example>
/**/  CFApprox(1.414213, 10^(-2));
17/12
</example>
</description>

<seealso>
  <see>CFApproximants</see>
  <see>ContFrac</see>
  <see>SimplestRatBetween</see>
</seealso>

<keys>
  <key>rational approximation</key>
  <key>continued fraction</key>
  <key>convergent</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CFApproximants</title>
  <short_description>continued fraction approximants</short_description>

<syntax>
CFApproximants(X: <type>RAT</type>): <rtn>LIST</rtn> of <rtn>RAT</rtn>
</syntax>
<description>
<tt>CFApproximants</tt> returns a list of all continued fraction approximants
to the rational <tt>X</tt>.

<example>
/**/  CFApproximants(1.414213);
[1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 816/577, 1393/985,
 6388/4517, 7781/5502, 14169/10019, 21950/15521, 36119/25540, 58069/41061,
 152257/107662, 210326/148723, 1414213/1000000]
</example>
</description>

<seealso>
  <see>CFApprox</see>
  <see>ContFrac</see>
</seealso>

<keys>
  <key>continued fraction</key>
  <key>convergent</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>characteristic</title>
  <short_description>the characteristic of a ring</short_description>

<syntax>
characteristic(R: <type>RING</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the characteristic of the current ring, in the
first case, or of the ring R, in the second.

<example>
/**/   Use R ::= ZZ/(3)[t];
/**/   S ::= QQ[x,y];
/**/   characteristic(CurrentRing);
3

/**/  characteristic(S);
0
</example>
</description>


<seealso>
  <see>IsFiniteField</see>
  <see>LogCardinality</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CharPoly</title>
  <short_description>characteristic polynomial of a matrix</short_description>
<syntax>
CharPoly(M: <type>MAT</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the characteristic polynomial of <tt>M</tt>, 
square matrix, in the indeterminate <tt>X</tt>.
<par/>
See also <ttref>MinPoly</ttref>.
<example>
/**/  Use R ::= QQ[x];
/**/  CharPoly(matrix([[1,2,3],[4,5,6],[7,8,9]]), x);
x^3 -15*x^2 -18*x
</example>
</description>
<seealso>
  <see>MinPoly</see>
</seealso>
<keys>
  <key>characteristic polynomial</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CheckArgTypes</title>
  <short_description>Check types in a list</short_description>
<syntax>
CheckArgTypes(Ltype: <type>LIST</type> of TYPE, Larg: <type>LIST</type>)
</syntax>
<description>
This function provides a basic type checking for user defined functions:
it checks whether the types of the elements in the third 
argument, a list, correspond to the types in the second list.
If so, it returns nothing, otherwise returns an error.

<example>
/**/  -- the following returns an error for the 2nd argument (INT)
/**/  -- CheckArgTypes([RAT, RINGELEM, MAT], [2/3, 20, LexMat(3)]); --> ERROR
--> ERROR: Arg 2 is INT but must be RINGELEM

/**/  -- the following returns nothing
/**/  CheckArgTypes([RAT, [INT,RAT,RINGELEM], MAT], [2/3, 20, LexMat(3)]);

/**/  -- an example of use for type checking
/**/  Define Pow(F, N)
/**/    CheckArgTypes([[INT,RAT,RINGELEM,IDEAL,MAT], INT], [F, N]);
/**/    Return F^N;
/**/  EndDefine; -- Pow
/**/  Pow(x, 3);
x^3
/**/  -- Pow(2, x); --> ERROR
--> ERROR: Arg 2 is RINGELEM but must be INT
</example>
</description>


<keys>
  <key>argument</key>
  <key>checking</key>
  <key>CurrentTypes</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ciao</title>
  <short_description>quit CoCoA</short_description>

<syntax>
ciao
</syntax>
<description>
This command is used to quit CoCoA.  It may be used only at top level.
</description>


<seealso>
  <see>quit</see>
</seealso>

<types>
  <type>system</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ClearDenom</title>
  <short_description>clear common denominator of a polynomial with rational coeffs</short_description>

<syntax>
ClearDenom(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function clears the denominators of the coefficients in a
polynomial over QQ.  It simply multiplies by the least common multiple of
the denominators.

<example>
/**/  Use QQ[x,y];
/**/  F := (2/3)*x + (4/5)*y;
/**/  ClearDenom(F);
10*x +12*y
</example>
</description>


<keys>
  <key>clearing denominator</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>close</title>
  <short_description>close a device</short_description>

<syntax>
close(D: <type>DEVICE</type>)
</syntax>
<description>
This function closes the device D.

<example>
  D := OpenOFile("my-test"); -- open file for output from CoCoA
  Print "test" On D;  -- write to my-file
  Close(D);  -- close the file
  Close(DEV.STDIN);  -- close the standard input device
-- Bye

(Close(DEV.OUT) suppresses all output to the CoCoA window.)
</example>
</description>


<seealso>
  <see>Introduction to IO</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CloseLog</title>
  <short_description>close a log of a CoCoA session</short_description>

<syntax>
CloseLog(D: <type>DEVICE</type>)
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function <ttref>OpenLog</ttref> opens the output device D and
starts to record the output from a CoCoA session on D.
<par/>
This function closes the device D and stops recording the CoCoA session on D.
</description>


<seealso>
  <see>OpenLog</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoCoA-4 mode</title>
  <short_description>Backward compatibility mode for CoCoA-4</short_description>

<syntax>
  *** E ***

where <tt>E</tt> is a CoCoA-4 expression.
</syntax>
<description>
CoCoA-5 is not fully backward compatible with CoCoA-4, <i>i.e.</i> some CoCoA-4
programs will be rejected by CoCoA-5.  CoCoA-4 mode helps ease the transition to
CoCoA-5.
<par/>
In CoCoA-4 it was not necessary to write explicitly the product between two
indeterminates; in CoCoA-5 this is obligatory.
<par/>
The expression <tt>E</tt> may also contain function calls, but only if the function
names begin with a capital letter.

<example>
/**/ Use QQ[x,y,z];
/**/ f := 2*x^2*y - 3*x*y*z - 4*y^2*z + 5*y*z^2 + 6*z^3;
/**/ g := ***2x^2y - 3xyz - 4y^2z + 5yz^2 + 6z^3***; --> C4 mode, more compact!
/**/ f = g;
true
</example>
</description>

<seealso>
  <see>Migrating from CoCoA-4 and keeping up-to-date</see>
  <see>not</see>
  <see>and</see>
  <see>or</see>
</seealso>
<keys>
  <key>*</key>
  <key>***</key>
  <key>multiplication by juxtaposition</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CocoaLimits</title>
  <short_description>limits on exponents and ring characteristics</short_description>

<syntax>
CocoaLimits(): <rtn>RECORD</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function returns the maximum allowable characteristic of a CoCoA
ring and the maximum allowable exponent in a CoCoA expression.  These
numbers may vary depending on the platform on which CoCoA is run.

<example>
  CocoaLimits();
record[MaxChar := 32767, MaxExp := 2147483647]
-------------------------------
</example>
</description>


<types>
  <type>system</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CocoaPackagePath</title>
  <short_description>returns the path to the CoCoA packages</short_description>

<syntax>
CocoaPackagePath(): <rtn>STRING</rtn>
</syntax>
<description>
This function returns the path name of the directory containing the CoCoA
libraries. It is platform dependent.

<example>
/**/  CocoaPackagePath();
/Applications/CoCoA-5/packages
</example>
</description>


<types>
  <type>system</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoeffEmbeddingHom</title>
  <short_description>returns the coefficient embedding homomorphism of a polynomial ring</short_description>
<syntax>
CoeffEmbeddingHom(P: <type>RING</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
This function returns the coefficient embedding homomorphism of the
polynomial ring <tt>P</tt>.
<example>
/**/ Use P ::= QQ[x,y];
/**/ phi := CoeffEmbeddingHom(P);  -- phi: QQ -> P
/**/ f := 2*x+3*y;
/**/ f/phi(LC(f));
x + (3/2)*y
</example>
</description>
<keys>
  <key>homomorphism</key>
</keys>
<seealso>
  <see>CanonicalHom</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>coefficients</title>
  <short_description>list of coefficients of a polynomial</short_description>

<syntax>
coefficients(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
coefficients(F: <type>RINGELEM</type>, S: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list of coefficients of F in <tt>CoeffRing(RingOf(F))</tt>.
<par/>
Called with one argument F it returns the list of all non-zero
coefficients; the order being decreasing on the terms in F as
determined by the term-ordering of <tt>RingOf(F)</tt>.
<par/>
Called with two arguments F it returns the coefficients of the
list of specified terms S; their order is determined by the list S.
<par/>
The old form (CoCoA-4) <tt>Coefficients(F,x)</tt> for the coefficients
of F w.r.t an indeterminate x is now implemented
as <ttref>CoefficientsWRT</ttref> and <ttref>CoeffListWRT</ttref>.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := 3*x^2*y + 5*y^2 - x*y;
/**/  Coeffs := coefficients(F);  Coeffs;  -- with one argument
[3, -1, 5]
/**/  phi := CoeffEmbeddingHom(RingOf(F));
/**/  F = ScalarProduct(apply(phi,Coeffs), support(F));
true

/**/  Skeleton := [1, x, y, z, x^2, x*y, y^2, y*z, z^2];
/**/  Coeffs := coefficients(F, Skeleton);  Coeffs;  -- with two arguments
[0, 0, 0, 0, 0, -1, 5, 0, 0]
/**/  ScalarProduct(apply(phi,Coeffs), Skeleton);
-x*y +5*y^2

/**/  L := CoefficientsWRT(F,[x,y,z]);  indent(L);  -- similar function
[
  record[PP := y^3, coeff := 5],
  record[PP := x^2*y, coeff := 3],
  record[PP := x*y^5, coeff := -1]
]
/**/  F = sum([X.coeff * X.PP | X In L]);
true

/**/  L := CoeffListWRT(F, y);  L;  -- similar function
[0, 3*x^2 -x, 5]
/**/  F = sum([L[d+1]*y^d | d in 0..(len(L)-1)]);
true

/**/  R3 := NewFreeModule(R,3);
/**/  V := ModuleElem(R3, ***[3x^2+y, x-5z^3, x+2y]***);
/**/  ConcatLists([coefficients(V[i]) | i In 1..NumCompts(V)]);
[3, 1, -5, 1, 1, 2]
</example>
</description>


<seealso>
  <see>Coefficient Rings</see>
  <see>CoefficientsWRT</see>
  <see>CoeffListWRT</see>
  <see>LC</see>
  <see>monomials</see>
  <see>support</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoefficientsWRT</title>
  <short_description>list of coeffs and PPs of a polynomial wrt an indet or a list of indets</short_description>

<syntax>
CoefficientsWRT(F: <type>RINGELEM</type>, F: <type>RINGELEM</type>): <rtn>LIST</rtn>
CoefficientsWRT(F: <type>RINGELEM</type>, S: <type>LIST</type> of RINGELEM): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of the coefficients and PPs of F seen
as a polynomial in X, and indeterminate or a list of indeterminates.
All entries in the returned list are RingElem in RingOf(F). 

<example>
/**/ Use R ::= QQ[x,y,z]; 
/**/ f := x^3*z+x*y+x*z+y+2*z;
/**/ Cx :=  CoefficientsWRT(f, x);  -- same as...
/**/ Cx :=  CoefficientsWRT(f, [x]);
/**/ indent(Cx);
[
  record[PP := 1, coeff := y +2*z],
  record[PP := x, coeff := y +z],
  record[PP := x^3, coeff := z]
]
/**/ f = sum([M.coeff * M.PP | M In Cx]);
true
/**/ Foreach M In Cx Do Print "  +(", M.coeff, ")*", M.PP; EndForeach;
  +(y +2*z)*1  +(y +z)*x  +(z)*x^3

/**/ Cxz :=  CoefficientsWRT(f, [x,z]);
/**/ indent(Cxz);
[
  record[PP := 1, coeff := y],
  record[PP := z, coeff := 2],
  record[PP := x, coeff := y],
  record[PP := x*z, coeff := 1],
  record[PP := x^3*z, coeff := 1]
]
</example>
</description>

<seealso>
  <see>Coefficient Rings</see>
  <see>CoeffOfTerm</see>
  <see>ContentWRT</see>
  <see>LC</see>
  <see>monomials</see>
  <see>support</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoeffListWRT</title>
  <short_description>list of coefficients of a polynomial wrt and indet</short_description>

<syntax>
CoeffListWRT(F: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the list of the coefficients of <tt>F</tt> seen as a univariate
polynomial in <tt>X</tt>, and indeterminate or a list of indeterminates. 
All entries in the returned list are RingElem belonging to <tt>RingOf(F)</tt>. 
<par/>
Note that the returned list is <em>reversed</em> from the CoCoA-4 analogue
<tt>Coefficients(F,X)</tt> thus to re-use old code you should call
<tt>reversed(CoeffListWRT(F,X))</tt>.

<example>
/**/  Use R ::= QQ[x,y,z]; 
/**/  F := 5*y^2 + (3*x^2-x)*y;
/**/  L := CoeffListWRT(F, y);  Print L;
[0, 3*x^2 -x, 5]
/**/  F = sum([L[d+1]*y^d | d in 0..(len(L)-1)]);
true
</example>
</description>

<seealso>
  <see>coefficients</see>
  <see>CoefficientsWRT</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoeffOfTerm</title>
  <short_description>coefficient of a term of a polynomial</short_description>
  
<syntax>
CoeffOfTerm(F: <type>RINGELEM</type>, T: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the coefficient of the term <tt>T</tt> occurring in <tt>F</tt>.
NB: In CoCoA 4 the order of the arguments was different.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := 5*x*y^2 - 3*z^3;
/**/  CoeffOfTerm(F, x*y^2);
5
/**/  CoeffOfTerm(F, x^3);
0
/**/  CoeffOfTerm(F, z^3);
-3
</example>
</description>

<seealso>
  <see>coefficients</see>
  <see>LC</see>
  <see>log</see>
  <see>LogToTerm</see>
  <see>monomials</see>
  <see>support</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CoeffRing</title>
  <short_description>the ring of coefficients of a polynomial ring</short_description>

<syntax>
CoeffRing(R: <type>RING</type>): <rtn>RING</rtn>
</syntax>
<description>
This function returns the ring of coefficients of a polynomial ring.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  S ::= ZZ/(2)[a,b,c];
/**/  CoeffRing(R);
QQ

/**/  CoeffRing(S);
FFp(2)
</example>
</description>


<seealso>
  <see>characteristic</see>
  <see>coefficients</see>
  <see>CurrentRing</see>
  <see>indets</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ColMat</title>
  <short_description>single column matrix</short_description>

<syntax>
ColMat(L: <type>LIST</type>): <rtn>MAT</rtn>
ColMat(R: <type>RING</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the matrix whose only column consists of the
elements of the list L.

<example>
/**/  ColMat([3,4,5]);
matrix(QQ,
 [[3],
  [4],
  [5]])

/**/  RingOf(It);  -- default ring is QQ
QQ

/**/  ColMat(ZZ, [3,4,5]);
matrix(ZZ,
 [[3],
  [4],
  [5]])
/**/  RingOf(It);
ZZ
</example>
</description>


<seealso>
  <see>matrix</see>
  <see>BlockMat</see>
  <see>DiagMat</see>
  <see>RowMat</see>
  <see>GensAsCols, GensAsRows</see>
</seealso>

<keys>
  <key>column matrix</key>
  <key>columnmatrix</key>
  <key>colmatrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>colon</title>
  <short_description>ideal or module quotient</short_description>

<syntax>
colon(M: <type>IDEAL</type>, N: <type>IDEAL</type>): <rtn>IDEAL</rtn>
colon(M: <type>MODULE</type>, N: <type>MODULE</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the quotient of M by N: the ideal of all
polynomials F such that F*G is in M for all G in N. The command
<tt>M : N</tt> is a shortcut for <tt>colon(M, N)</tt>.
<par/>
See also  <ttref>HColon</ttref> for non-homogeneous input.

<example>
/**/  Use R ::= QQ[x,y];
/**/  ideal(x*y, x^2) : ideal(x);
ideal(y, x)

/**/  colon(ideal(x^2, x*y), ideal(x, x-y^2));
ideal(x)
</example>
</description>


<seealso>
  <see>saturate</see>
  <see>HSaturation</see>
  <see>HColon</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>quotient</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ColumnVectors [OBSOLETE]</title>
  <short_description>[OBSOLETE] list of module elements</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
Essentially replaced by <ttref>GensAsCols, GensAsRows</ttref>
and <ttref>SubmoduleCols, SubmoduleRows</ttref>
</description>
<seealso>
  <see>GensAsCols, GensAsRows</see>
  <see>SubmoduleCols, SubmoduleRows</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Comp [OBSOLETE]</title>
  <short_description>[OBSOLETE] access a component</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] please use <tt>[...]</tt> for accessing
entries in a list by index, or the record field selector operator.
</description>
<seealso>
  <see>operators, shortcuts</see>
  <see>record field selector</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Comparison Operators</title>
  <short_description>less than, greater than, ...</short_description>

<syntax>
A &lt; B
A &gt; B
A &lt;= B
A &gt;= B
  return <rtn>BOOL</rtn>
</syntax>
<description>
These operators perform the corresponding comparison between <tt>A</tt> and <tt>B</tt>
returning <tt>true</tt> or <tt>false</tt>; they will signal an error if <tt>A</tt> and <tt>B</tt>
are not comparable.
<example>
/**/ "abc" &lt; "def"; -- lex ordering for strings
true
</example>
</description>

<seealso>
  <see>Equality Test</see>
  <see>operators, shortcuts</see>
</seealso>
<keys>
  <key>&lt;</key>
  <key>&lt;=</key>
  <key>&gt;</key>
  <key>&gt;=</key>
  <key>inequalities</key>
  <key>compare</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CompleteToOrd</title>
  <short_description>completes a matrix to an ordering matrix</short_description>

<syntax>
CompleteToOrd(M: <type>MAT</type>): <rtn>MAT</rtn>
CompleteToOrd(M1, M2: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns an ordering matrix (i.e. with non-zero
determinant) completing the first matrix.

Given two matrices M1 and M2, it just concatenates of M1 and M2 and
makes it square removing the redundant rows.

Given only one matrix M it completes M to an ordering matrix; if
M is suitable the resulting matrix defines a term-ordering.

<example>
/**/  M := matrix([[1,2,3,4]]);
/**/  CompleteToOrd(M);
 [[1, 2, 3, 4],
  [0, 0, 0, -1],
  [0, 0, -1, 0],
  [0, -1, 0, 0]])

/**/  CompleteToOrd(M, LexMat(4));
matrix(QQ,
 [[1, 2, 3, 4],
  [1, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 1, 0]])

/**/  CompleteToOrd(matrix([[1,2,0,0]]));
 [[1, 2, 0, 0],
  [0, 0, 1, 1],
  [0, 0, 0, -1],
  [0, -1, 0, 0]])

/**/  CompleteToOrd(matrix([[1,2,0,0],[0,0,3,0]]));
matrix(QQ,
 [[1, 2, 0, 0],
  [0, 0, 3, 0],
  [0, 0, 0, 1],
  [0, -1, 0, 0]])

/**/  CompleteToOrd(matrix([[1,2,0,0],[0,0,3,0]]), RevLexMat(4));
matrix(QQ,
 [[1, 2, 0, 0],
  [0, 0, 3, 0],
  [0, 0, 0, -1],
  [0, -1, 0, 0]])
--> not a term-ordering
</example>
</description>


<keys>
  <key>term-ordering</key>
  <key>termordering</key>
  <key>NewMatCompleteOrd</key>
</keys>

<seealso>
  <see>LexMat</see>
  <see>RevLexMat</see>
  <see>StdDegLexMat</see>
  <see>StdDegRevLexMat</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>compts</title>
  <short_description>list of components of a ModuleElem</short_description>
  
<syntax>
compts(V: <type>MODULEELEM</type>): <rtn>LIST</rtn>
Comps(V: <type>MODULEELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
<par/>
This function returns the list of components of a ModuleElem V.
It is like converting a ModuleElem into a generic list.
Note that a ModuleElem is a more structured object than a generic
list.
<example>
/**/  use R ::= QQ[x,y,z];
/**/  R3 := NewFreeModule(R,3);
/**/  V := ModuleElem(R3, ***[3x^2+4y, 2x-5z^3, 2x+2y]***);  V;
[3*x^2 +4*y, -5*z^3 +2*x, 2*x +2*y]
/**/  type(V);
MODULEELEM

/**/  compts(V);
[3*x^2 +4*y, -5*z^3 +2*x, 2*x +2*y]
/**/ type(compts(V));
LIST
</example>
</description>
    
<seealso>
  <see>NumCompts</see>
</seealso>
<keys>
  <key>components</key>
  <key>comps</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>concat</title>
  <short_description>concatenate lists</short_description>


<syntax>
concat(L_1: <type>LIST</type>,...,L_n: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list obtained by concatenating the lists
<tt>L_1,...,L_n</tt>.
<par/>
NOTE: to concatenate strings just use <tt>+</tt>.
<example>
/**/  concat([1,2,3],[4,5],[],[6]);
[1, 2, 3, 4, 5, 6]
</example>
</description>

<seealso>
  <see>append</see>
  <see>ConcatLists</see>
  <see>String Operations</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatAntiDiag</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatAntiDiag(A: <type>MAT</type>, B: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function creates a simple block matrix.  The two entries are
matrices.
ConcatAntiDiag(A, B) will return a matrix of the form
<verbatim>
                | 0 A |
                | B 0 |
</verbatim>

<example>
/**/  A := mat([[1,2,3],   [4,5,6]]);
/**/  B := mat([[101,102], [103,104]]);
/**/  ConcatAntiDiag(A, B);
matrix([
  [0, 0, 1, 2, 3],
  [0, 0, 4, 5, 6],
  [101, 102, 0, 0, 0],
  [103, 104, 0, 0, 0]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>ConcatDiag</see>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatDiag</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatDiag(A: <type>MAT</type>, B: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function creates a simple block matrix.  The two entries are
matrices.
ConcatDiag(A, B) will return a matrix of the form
<verbatim>
                | A 0 |
                | 0 B |
</verbatim>

<example>
/**/  A := mat([[1,2,3],   [4,5,6]]);
/**/  B := mat([[101,102], [103,104]]);
/**/  ConcatDiag(A, B);
matrix([
  [1, 2, 3, 0, 0],
  [4, 5, 6, 0, 0],
  [0, 0, 0, 101, 102],
  [0, 0, 0, 103, 104]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>ConcatAntiDiag</see>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
  <see>DiagMat</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatHor</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatHor(A: <type>MAT</type>, B: <type>MAT</type>): <rtn>MAT</rtn>

where A and B have the same number of rows
</syntax>
<description>
This function creates a simple block matrix.  The two entries are
matrices with the same number of rows. 
ConcatHor(A, B) will return a matrix of the form
<verbatim>
                | A B |
</verbatim>

<example>
/**/  A := mat([[1,2,3],   [4,5,6]]);
/**/  B := mat([[101,102], [103,104]]);
/**/  ConcatHor(A, B);
matrix([
  [1, 2, 3, 101, 102],
  [4, 5, 6, 103, 104]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>MakeMatByRows, MakeMatByCols</see>
  <see>ConcatAntiDiag</see>
  <see>ConcatDiag</see>
  <see>ConcatHorList</see>
  <see>ConcatVer</see>
  <see>RowMat</see>
</seealso>

<keys>
  <key>extend rows</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatHorList</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatHorList(L: <type>LIST</type> of <type>MAT</type>): <rtn>MAT</rtn>

where the matrices in L have the same number of rows
</syntax>
<description>
This function creates a simple block matrix.  The entries in the list are
matrices with the same number of rows.
ConcatHorList(L) will return a matrix of the form
<verbatim>
                | L[1] L[2] .. L[N] |
</verbatim>

<example>
/**/  L := [ mat([[1,2,3], [4,5,6]]), mat([[101,102], [103,104]]) ];
/**/  ConcatHorList(L);
matrix([
  [1, 2, 3, 101, 102],
  [4, 5, 6, 103, 104]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>MakeMatByRows, MakeMatByCols</see>
  <see>ConcatAntiDiag</see>
  <see>ConcatDiag</see>
  <see>ConcatHor</see>
  <see>ConcatVerList</see>
  <see>RowMat</see>
</seealso>
<keys>
  <key>extend rows</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatLists</title>
  <short_description>concatenate a list of lists</short_description>
<syntax>
ConcatLists(L: <type>LIST</type> of LISTs): <rtn>LIST</rtn>
</syntax>
<description>
This function takes 1 argument, a list whose entries are lists, and
returns the concatenation of its entries.

<example>
/**/  L := [[1,2],["abc","def"],[3,4]];
/**/  ConcatLists(L);
[1, 2, "abc", "def", 3, 4]
</example>
</description>

<seealso>
  <see>append</see>
  <see>concat</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatVer</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatVer(A: <type>MAT</type>, B: <type>MAT</type>): <rtn>MAT</rtn>

where A and B have the same number of columns
</syntax>
<description>
This function creates a simple block matrix.  The two entries are
matrices with the same number of columns. 
ConcatVer(A, B) will return a matrix of the form
<verbatim>
                | A |
                | B |
</verbatim>

<example>
/**/  A := mat([[1,2,3], [4,5,6]]);
/**/  B := mat([[101,102,103]]);
/**/  ConcatVer(A, B);
matrix([
  [1, 2, 3],
  [4, 5, 6],
  [101, 102, 103]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>ColMat</see>
  <see>MakeMatByRows, MakeMatByCols</see>
  <see>ConcatAntiDiag</see>
  <see>ConcatDiag</see>
  <see>ConcatHor</see>
  <see>ConcatVerList</see>
</seealso>

<keys>
  <key>extend columns</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ConcatVerList</title>
  <short_description>create a simple block matrix</short_description>

<syntax>
ConcatVerList(L: <type>LIST</type> of <type>MAT</type>): <rtn>MAT</rtn>

where the matrices in L have the same number of columns
</syntax>
<description>
This function creates a simple block matrix.  The entries in the list are
matrices with the same number of columns. 
ConcatVer(L) will return a matrix of the form
<verbatim>
                | L[1] |
                | L[2] |
                |  ..  |
</verbatim>

<example>
/**/  L := [ mat([[1,2,3], [4,5,6]]), mat([[101,102,103]]) ];
/**/  ConcatVerList(L);
matrix([
  [1, 2, 3],
  [4, 5, 6],
  [101, 102, 103]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>ColMat</see>
  <see>MakeMatByRows, MakeMatByCols</see>
  <see>ConcatAntiDiag</see>
  <see>ConcatDiag</see>
  <see>ConcatVer</see>
  <see>ConcatHorList</see>
</seealso>

<keys>
  <key>extend columns</key>
</keys>
</command>
<!-- ===  COMMAND-rm cond  =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>content</title>
  <short_description>content of a polynomial</short_description>

<syntax>
content(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the content of F (i.e. a gcd of its coefficients).
<par/>
The returned value is a RingElem in RingOf(F). 

<example>
/**/ Use R ::= QQ[x,y,z]; 
/**/ F := *** 1234x^3z + 3456xyz^3 + 5678y^2z ***;
/**/ content(F);
2
/**/ RingOf(It);
QQ
</example>
</description>


<seealso>
  <see>ContentWRT</see>
  <see>coefficients</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ContentFreeFactor</title>
  <short_description>factorization of multivariate polynomial into content-free factors</short_description>

<syntax>
ContentFreeFactor(F: <type>RINGELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns a factorization of the multivariate polynomial F into
content-free factors; it works by calling <code>ContentWRT</code> repeatedly.
The multiplicities will always be 1.

<example>
/**/ Use R ::= QQ[x,y,z]; 
/**/ F := 2*(x+1)*(y+2)*(x+y);
/**/ indent(ContentFreeFactor(F));
record[
  RemainingFactor := 2,
  factors := [y +2, x +1, x +y],
  multiplicities := [1, 1, 1]
]
</example>
</description>

<seealso>
  <see>ContentWRT</see>
  <see>factor</see>
  <see>SqFreeFactor</see>
</seealso>
<keys>
  <key>factorization</key>
  <key>content</key>
  <key>primitive</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ContentWRT</title>
  <short_description>content of a polynomial wrt and indet or a list of indets</short_description>

<syntax>
ContentWRT(F: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
ContentWRT(F: <type>RINGELEM</type>, L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the content of F (i.e. a gcd of its
coefficients) seen as a polynomial in X, indet or list of
indeterminates. 
The returned value is a RingElem in RingOf(F). 

<example>
/**/ Use R ::= QQ[x,y,z]; 
/**/ F := x^3*z + x*y*z^3 + 2*z;
/**/ Cx :=  CoefficientsWRT(F, x);
/**/ indent(Cx);
[
  record[PP := 1, coeff := 2*z],
  record[PP := x, coeff := y*z^3],
  record[PP := x^3, coeff := z]
]
/**/ ContentWRT(F, x);
z
/**/ ContentWRT(F, [x]);
z
</example>
</description>


<seealso>
  <see>CoefficientsWRT</see>
  <see>content</see>
  <see>monomials</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ContFrac</title>
  <short_description>continued fraction quotients</short_description>

<syntax>
ContFrac(X: <type>RAT</type>): <rtn>LIST</rtn> of <rtn>INT</rtn>
</syntax>
<description>
<tt>ContFrac</tt> returns a list of the continued fraction <em>quotients</em>
for the given rational number <tt>X</tt>.

<example>
/**/  ContFrac(1.414213);
[1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 4, 1, 1, 1, 1, 1, 2, 1, 6]
</example>
</description>

<seealso>
  <see>CFApprox</see>
  <see>CFApproximants</see>
  <see>ContFracToRat</see>
</seealso>

<keys>
  <key>continued fraction</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ContFracToRat</title>
  <short_description>convert continued fraction to rational</short_description>

<syntax>
ContFracToRat(L: <type>LIST</type> of <type>INT</type>): <rtn>RAT</rtn>
</syntax>
<description>
<tt>ContFracToRat</tt> returns the rational number equal to the continued
fraction whose quotients are given as input.  The quotients must all be
integers, only the very first may be non-positive.

<example>
/**/  ContFracToRat([1, 2, 2, 2, 2, 2, 2, 2]);
577/408
</example>
</description>

<seealso>
  <see>ContFrac</see>
  <see>CFApprox</see>
  <see>CFApproximants</see>
</seealso>
<keys>
  <key>continued fraction</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<!-- <command> -->
<!--   <title>Contrib</title> -->
<!--   <short_description>list of contributors to CoCoA</short_description> -->

<!-- <syntax> -->
<!-- Contrib():NULL -->
<!-- </syntax> -->
<!--     <description> -->
<!-- This function returns a list of contributors to the main CoCoA -->
<!-- system.  In addition to these contributions, there are many other -->
<!-- contributions which are not part of the standard distribution.  For -->
<!-- pointers to these, see the CoCoA homepage at -->
<!-- <tt>http://cocoa.dima.unige.it</tt> or one of its mirrors. -->
<!-- </description> -->

<!--   <type>misc</type> -->
<!--   <type>system</type> -->

<keys>
<!--   <key>contrib</key> -->
</keys>
<!--   </command> -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>count</title>
  <short_description>count the objects in a list</short_description>

<syntax>
count(L: <type>LIST</type>, E: <type>OBJECT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function counts the number of occurrences of the object E in the
list L.

<example>
/**/  L := [1,2,3,2,[2,3]];
/**/  count(L,2);
2

/**/  count(L,[2,3]);
1

/**/  count(L,"a");
0
</example>
</description>


<seealso>
  <see>distrib</see>
  <see>len</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CpuTime</title>
  <short_description>Counts cpu time</short_description>
<syntax>
CpuTime(): <rtn>RAT</rtn>
</syntax>
<description>
This function returns a <tt>RAT</tt> whose value is the user CPU usage in
seconds since the start of the program: this is the amount of time the
processor has dedicated to your computation, and may be rather less than
the real elapsed time if the computer is also busy with other tasks.
<par/>
The most common usage is with <ttref>TimeFrom</ttref> as shown in the example.
<example>
/**/ StartTime := CpuTime(); -- time in seconds since the start (a RAT)
/**/ --
/**/ -- .... long computation ....
/**/ --
/**/ PrintLn "Computation time: ", TimeFrom(StartTime);
</example>
You can use <ttref>DecimalStr</ttref> to see the value of <tt>CpuTime</tt> in a more easily
comprehensible form.
</description>

<seealso>
  <see>TimeFrom</see>
  <see>DecimalStr</see>
</seealso>
<keys>
  <key>cpu time</key>
  <key>timing</key>
  <key>set timer</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CRT</title>
  <short_description>Chinese Remainder Theorem</short_description>

<syntax>
CRT(R1: <type>INT</type>, M1: <type>INT</type>, R2: <type>INT</type>, M2: <type>INT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function combines two residue-modulus pairs <tt>(R1,M1)</tt> and <tt>(R2,M2)</tt>
using the Chinese Remainder Theorem to produce a single
residue-modulus pair <tt>(R,M)</tt> such that <tt>R = R1 mod M1</tt> and <tt>R = R2 mod M2</tt>,
and <tt>|R| &lt; M</tt>.  The moduli <tt>M1</tt> and <tt>M2</tt> must be coprime (hence <tt>M = M1*M2</tt>).

<example>
/**/  CRT(2,3,4,5);
record[modulus := 15, residue := -1]
</example>
</description>

<seealso>
  <see>RatReconstructByContFrac, RatReconstructByLattice</see>
</seealso>

<keys>
  <key>chinese remaindering</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CurrentRing</title>
  <short_description>the current ring</short_description>

<syntax>
CurrentRing
</syntax>
<description>
This is a top-level SYSTEM VARIABLE containing the current ring.
<par/>
NB in CoCoA-4 it used to be a function (namely <tt>CurrentRing()</tt>),
now it is a top-level <em>variable</em> which needs to be imported in
functions... but beware: this is to be considered BAD STYLE ;-)

<example>
/**/  Use R ::= QQ[x,y];
/**/  Use S ::= ZZ/(3)[t];
/**/  CurrentRing;
RingDistrMPolyClean(FFp(3), 1)

/**/  Use R;
/**/  CurrentRing;
RingDistrMPolyClean(QQ, 2)

/**/  Define MyIndets1()
/**/    TopLevel CurrentRing; -- importing a top-level (global) variable
/**/    Return indets(CurrentRing);
/**/  EndDefine;

/**/  Define MyIndets2(val)
/**/    Return indets(RingOf(val));  -- cleaner: depends only on the argument
/**/  EndDefine;

/**/ MyIndets1();
[x, y]

/**/ MyIndets2(ideal(x));
[x, y]
</example>
</description>


<seealso>
  <see>RingOf</see>
  <see>TopLevel</see>
</seealso>
<keys>
  <key>system variable</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>CurrentTypes</title>
  <short_description>lists all data types</short_description>
<syntax>
CurrentTypes(): <rtn>LIST</rtn> of <rtn>TYPE</rtn>
</syntax>
<description>
This function lists all CoCoA data types.
<example>
/**/  CurrentTypes();
[BOOL, ERROR, FUNCTION, ...]
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>cyclotomic</title>
  <short_description>n-th cyclotomic polynomial</short_description>

<syntax>
cyclotomic(n: <type>INT</type>, x: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function computes the n-th cyclotomic polynomial (in the indeterminate x).

<example>
/**/  Use QQ[z];
/**/  cyclotomic(4,z);
z^2 + 1
</example>
</description>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>D</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>dashes</title>
  <short_description>returns string of dashes</short_description>
<syntax>
dashes()
</syntax>
<description>
This function returns a string of dashes:
<example>
/**/  dashes(); 1+1;
-------------------------------
2
</example>
</description>
<types>
  <type>miscellaneous</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>date</title>
  <short_description>the date</short_description>

<syntax>
date() : <type>INT</type>
</syntax>
<description>
This function returns the date.
<par/>
Note that from version 5.0.4 the result is an INT and the date is in
the form YYYYMMDD.
See also <ttref>TimeOfDay</ttref>.

<example>
/**/  date();
20130530
</example>
</description>

<seealso>
  <see>TimeOfDay</see>
</seealso>

<types>
  <type>miscellaneous</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DecimalStr</title>
  <short_description>convert rational number to decimal string</short_description>


<syntax>
DecimalStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>): <rtn>STRING</rtn>
DecimalStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, NumDigits: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function produces a decimal string representation of a rational number
with up to <tt>NumDigits</tt> digits after the decimal point.  If not specified,
the default number of digits is 3.
<par/>
If <tt>X</tt> is a <tt>RINGELEM</tt>, it is automatically converted to a <tt>RAT</tt>.
<example>
/**/  DecimalStr(1/3);
0.333

/**/  DecimalStr(1/3, 60);
0.333333333333333333333333333333333333333333333333333333333333

/**/  DecimalStr(123.456789);
123.457
</example>
</description>

<seealso>
  <see>FloatStr</see>
  <see>ScientificStr</see>
  <see>MantissaAndExponent10</see>
</seealso>
<keys>
  <key>printing rational numbers</key>
  <key>decimal</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>define</title>
  <short_description>define a function</short_description>
<syntax>
Define F(X_1,...,X_n)   C   EndDefine
  return <rtn>FUNCTION</rtn>
</syntax>
<description>
1. INTRODUCTION. This command adds the user-defined function F to the
library. The function F can be called in the following way:
<verbatim>
    F(E_1,...,E_n)
</verbatim>
where the <tt>E_i</tt>&apos;s are expressions.
The result of the evaluation of each expression <tt>E_i</tt> is
assigned to the respective formal parameter <tt>X_i</tt>, and
the command sequence <tt>C</tt> is executed.
If, during the execution of <tt>C</tt>, a statement <tt>Return E</tt> is
executed, then the result of the evaluation of <tt>E</tt> is the return-value
of the function <tt>F</tt>.
If no <tt>Return</tt> command is executed, or <tt>Return</tt> is
executed without argument, then the return-value is <tt>Null</tt>.
<example>
/**/  Define square(X)
/**/    Return X^2;
/**/  EndDefine;

/**/  square(5);
25
</example>

2. SCOPE.  Every variable defined or modified by the command sequence
<tt>C</tt> is considered local to the function unless the variable is global or
relative to a <tt>ref</tt> parameter.
See <ttref>TopLevel</ttref> for the use of global variables.
See <tt>ref</tt> to learn about calling a function <em>by reference</em>,
i.e. so that the function can change the value of an existing variable.
<example>
/**/  Define Example_1(L)
/**/    L := L + 5;
/**/    Return L;
/**/  EndDefine;

/**/  L := 0;
/**/  Example_1(L);
5
/**/  L;  -- L is unchanged despite the function call.
0
</example>

3. VARIABLE NUMBER OF PARAMETERS.  It is also possible to have a
variable number of parameters using the syntax
<verbatim>
    Define F(...) C EndDefine;
</verbatim>
In this case the special variable <tt>ARGV</tt> will contain the list of
the arguments passed to the function.
<example>
/**/  Define MySum(...)
/**/    If len(ARGV) = 0 Then Return 12345;
/**/    Else
/**/      ans := 0;
/**/      Foreach N In ARGV Do ans := ans+N; EndForeach;
/**/    EndIf;
/**/    Return ans;
/**/  EndDefine;

/**/  MySum(1,2,3,4,5);
15
/**/  MySum();
12345
</example>
The old statement, <tt>Help S;</tt> is OBSOLETE!
</description>
<seealso>
  <see>return</see>
  <see>TopLevel</see>
  <see>ref</see>
</seealso>
<types>
  <type>programming</type>
</types>
<keys>
  <key>argv</key>
  <key>...</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DefiningIdeal</title>
  <short_description>defining ideal of a quotient ring</short_description>

<syntax>
DefiningIdeal(S: <type>RING</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
When <tt>S</tt> is a quotient ring, say <tt>S = R/I</tt>, this function returns
<tt>T</tt>, the ideal which defines <tt>S</tt>.

<example>
/**/ Use R ::= QQ[x,y,z];
/**/ S := R/ideal(x);
/**/ DefiningIdeal(S);
ideal(x)
</example>

</description>
<seealso>
  <see>NewQuotientRing</see>
</seealso>
<keys>
  <key>quotient ring</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>deg</title>
  <short_description>the standard degree of a polynomial or moduleelem</short_description>
<syntax>
deg(F: <type>RINGELEM</type>): <rtn>INT</rtn>
deg(F: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
The first form of this function returns the <em>standard degree</em> of <tt>F</tt>
(see <ttref>wdeg</ttref> for the <em>weighted degree</em>).
The second form returns the exponent of the indeterminate <tt>X</tt> in <tt>F</tt>.
<par/>
For the degree of a ring or quotient, see <ttref>multiplicity</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  deg(x*y^2+y);
3

/**/  deg(x*y^2+y, x);
1

/**/  Ws := RowMat([2,3,1]);
/**/  P := NewPolyRing(QQ, ["x","y","z"], CompleteToOrd(Ws), 1);
/**/  Use P;
/**/  deg(x*y^2+y);
3
/**/  wdeg(x*y^2+y);
[8]
/**/  deg(x*y^2+y, x);
1
/**/  deg(x*y^2+y, x);
2
</example>
</description>
<seealso>
  <see>wdeg</see>
  <see>NewPolyRing</see>
  <see>multiplicity</see>
</seealso>
<keys>
  <key>degree</key>
</keys>
</command>
<!-- ===  COMMAND-rm delete =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>den</title>
  <short_description>denominator</short_description>

<syntax>
den(X: <type>INT</type>|<type>RAT</type>): <rtn>INT</rtn>
den(X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
These function returns the denominator of the argument <tt>X</tt>.
If <tt>X</tt> is a <tt>RINGELEM</tt> in <tt>FractionField(R)</tt>, then <tt>den(X)</tt> is a RingElem in <tt>R</tt>.
<par/>
NB In CoCoA 4 the numerator and denominator could also be found
using the suffixes <tt>.Num</tt> and <tt>.Den</tt>; this fragile syntax is
now obsolete.

<example>
/**/  den(3);
1

/**/  P ::= QQ[x,y];
/**/  F := NewFractionField(P);
/**/  Use F;
/**/  den(x/(x+y));
x +y
/**/ RingOf(It);
RingDistrMPolyClean(QQ, 2)
</example>
</description>


<seealso>
  <see>num</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DensePoly</title>
  <short_description>the sum of all power-products of a given degree</short_description>

<syntax>
DensePoly(R: <type>RING</type>, N: <type>INT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the sum of all power-products of (standard) degree N.

<example>
/**/  Use R ::= QQ[x,y];
/**/  DensePoly(R,3);
x^3 + x^2*y + x*y^2 + y^3

/**/  Ws := RowMat([2,3]);
/**/  P := NewPolyRing(QQ, ["x","y"], CompleteToOrd(Ws), 1);
/**/  Use P;
/**/  DensePoly(P,1);  // NB standard degree!!
y +x
</example>
</description>


<seealso>
  <see>randomize</see>
  <see>randomized</see>
</seealso>

</command>
<!--  ===  COMMAND  =============================================== -->
<command>
  <title>Depth</title>
  <short_description>Depth of a module</short_description>
<syntax>
Depth(I: <type>IDEAL</type>, M: TAGGED("Quotient")): <rtn>INT</rtn>
Depth(M: TAGGED("Quotient")): <rtn>INT</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function calculates the depth of M in the ideal I, i.e. the
length of a maximal I-regular sequence in M. In the second form,
where I is not specified, it assumes that I is the maximal ideal
generated by the indeterminates, i.e. <tt>ideal(Indets())</tt>.
<par />
Note that if M is homogeneous and I is the maximal ideal, then it uses
the Auslander-Buchsbaum formula <tt>depth_I(M) = N - pd(M)</tt>
where N is the number of indeterminates and pd is the projective
dimension, otherwise it returns <tt>min{N | Ext^N(R/I, M)&lt;>0}</tt>
using the function <ttref>Ext</ttref>.
<example>
  Use R ::= QQ[x,y,z];
  Depth(R/ideal(0)); -- the (x,y,z)-depth of the entire ring is 3
3
-------------------------------
  I := ideal(x^5,y^3,z^2);
  -- one can check that it is zerodimensional and CM this way
  dim(R/I);
0
-------------------------------
  Depth(R/I);
0
-------------------------------

  N := Module([x^2,y], [x+z,0]);
  Depth(I, R^2/N);  --- a max reg sequence would be (z^2,y^3)
2
-------------------------------
  Use R ::= QQ[x,y,z,t,u,v];
  -- Cauchy-Riemann system in three complex vars!
  N := Module([x,y], [-y,x], [z,t], [-t,z], [u,v], [-v,u]);
  --- is it CM?
  Depth(R^2/N);
3
-------------------------------
  dim(R^2/N);
3
-------------------------------
  --- yes!

  M := Module([x,y,z],[t,v,u]);
  Res(R^3/M);
0 --> R^2(-1) --> R^3
-------------------------------
  Depth(R^3/M); -- using Auslander Buchsbaum 6-1=5
5
-------------------------------
  dim(R^3/M);  -- not CM
6
-------------------------------
  Depth(ideal(x,y,z,t), R^2/N);
2
-------------------------------
</example>
</description>

<seealso>
  <see>res</see>
  <see>Ext</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>deriv</title>
  <short_description>the derivative of a polynomial or rational function</short_description>

<syntax>
deriv(F: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the derivative of F with respect to the
indeterminate X.

<example>
/**/  Use R ::= QQ[x,y];
/**/  deriv(x*y^2, x);
y^2

/**/  Define Jac(F)  --> The Jacobian matrix for a polynomial.
/**/    Return matrix([[deriv(F, X) | X In Indets(RingOf(F))]]);
/**/  EndDefine;

/**/  Jac(x*y^2);
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[y^2, 2*x*y]])

/**/  FrF := NewFractionField(R);
/**/  Use FrF;
/**/  deriv((x*y^2)/(x-1), x);
(-y^2)/(x^2 -2*x +1)
</example>
</description>

<seealso>
  <see>jacobian</see>
</seealso>


<keys>
  <key>der</key>
  <key>derivative</key>
  <key>differentiate</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DerivationAction</title>
  <short_description>Action of a derivation</short_description>

<syntax>
DerivationAction(D: <type>RINGELEM</type>, P: <type>RINGELEM</type>)
</syntax>
<description>
Thanks to Enrico Carlini.
<par/>
Given the polynomial <tt>P</tt> and the derivation <tt>D</tt>, this function
computes the action of <tt>D</tt> on <tt>P</tt>.
<par/>
For the sake of simplicity Forms/Polynomials and Derivations live in
the same ring, the distinction between them is purely formal.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  DerivationAction(x*y*z, x^3+x*y*z);
1
</example>
</description>
<seealso>
  <see>InverseSystem</see>
  <see>PerpIdealOfForm</see>
</seealso>
<keys>
  <key>author: enrico carlini</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>describe</title>
  <short_description>information about an object</short_description>

<syntax>
describe X: <type>OBJECT</type>
</syntax>
<description>
This command gives some information about the object <tt>X</tt>.  For instance,
if <tt>X</tt> is a CoCoA-5 function, it prints out the definition, and if <tt>X</tt>
is a package name (prefixed with a <tt>$</tt>), it prints out the exported names.
<example>
/**/  Define succ(N) Return N+1; EndDefine;
/**/  describe succ;
Define succ(N) Return N+1 EndDefine

/**/  describe $chebyshev;
The package $chebyshev exports the following names:
* ChebyshevPoly
* ChebyshevPoly2
</example>
</description>
<types>
  <type>print</type>
  <type>TYPE</type>
  <type>miscellaneous</type>
</types>
</command>
<!-- ===  COMMAND-rm Destroy  =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>det</title>
  <short_description>the determinant of a matrix</short_description>


<syntax>
det(M: <type>MAT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the determinant of the matrix <tt>M</tt>.
<example>
/**/  Use R ::= QQ[x];
/**/  M := mat(R,[[x,x^2], [x,x^3]]);
/**/  det(M);
x^4 -x^3

/**/ det(mat(QQ,[[1,2], [0,5]]));
5
</example>
</description>

<seealso>
  <see>minors</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DF</title>
  <short_description>the degree form of a polynomial</short_description>

<syntax>
DF(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
Same as <ttref>LF</ttref>, but does not throw an error if the argument
is zero or if the <ttref>GradingDim</ttref> of the polynomial ring is 0.
As defined in Kreuzer-Robbiano book II (Definition 4.2.8).

<example>
/**/  Use R ::= QQ[x,y];
/**/  DF(x^2 -x*y +2*x -1);
x^2 -x*y

/**/  Use R ::= QQ[x,y], Lex;  -- GradingDim is 0: everything is homogeneous
/**/  DF(x^2 -x*y +2*x -1);
x^2 -x*y +2*x -1

/**/ P := NewPolyRing(QQ, IndetSymbols(R), mat([[1,4],[1,0]]), 1);
/**/ Use P;
/**/ DF(x^2 -x*y);
-x*y
/**/ DF(x^4 +x^2 -y);
 x^4 -y
</example>
</description>


<keys>
  <key>degree-form</key>
  <key>degreeform</key>
  <key>degree form</key>
</keys>

<seealso>
  <see>LF</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DiagMat</title>
  <short_description>matrix with given diagonal</short_description>

<syntax>
DiagMat(L: <type>LIST</type>): <rtn>MAT</rtn>
DiagMat(R: <type>RING</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the diagonal matrix whose diagonal are the
elements of the list L.

<example>
/**/  DiagMat([3,4,5]);
matrix(
[
  [3, 0, 0],
  [0, 4, 0],
  [0, 0, 5]
])

/**/ DiagMat(QQ,[5,6,7]);
matrix(
[
  [5, 0, 0],
  [0, 6, 0],
  [0, 0, 7]
])

-- fast implementation for high powers of a diagonal matrix
/**/  Define PowerDiag(M, Exp)
/**/    If not(IsDiagonal(M)) Then
/**/      error("PowerDiag: matrix must be diagonal");
/**/    EndIf;
/**/    Return DiagMat([ M[I, I]^Exp | I In 1..NumRows(M) ]);
/**/  EndDefine;

/**/ PowerDiag(IdentityMat(QQ,3), 200000000);
matrix(QQ,
 [[1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]])
</example>
</description>


<keys>
  <key>PowerDiag</key>
</keys>

<seealso>
  <see>BlockMat</see>
  <see>IsDiagonal</see>
  <see>ColMat</see>
  <see>RowMat</see>
</seealso>

<keys>
  <key>diagmat</key>
  <key>power</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>diff</title>
  <short_description>returns the difference between two lists</short_description>
<syntax>
diff(L: <type>LIST</type>, M: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list obtained by removing all the elements
of M from L.

<example>
/**/  L := [1,2,3,2,[2,3]];
/**/  M := [1,2];
/**/  diff(L, M);
[3, [2, 3]]
</example>
</description>


<seealso>
  <see>remove</see>
</seealso>
<keys>
  <key>difference</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>dim</title>
  <short_description>the dimension of a ring or quotient object</short_description>

<syntax>
dim(R: <type>RING</type> or TAGGED("Quotient")): <rtn>INT</rtn>
</syntax>
<description>
This function computes the dimension of R.
<par/>
The coefficient ring must be a field.

<example>
/**/ Use R ::= QQ[x,y,z];
/**/ dim(R/ideal(x));
2

/**/ dim(R/ideal(y^2-x, x*z-y^3));
1
</example>
</description>


<types>
  <type>groebner</type>
</types>

<keys>
  <key>dimension</key>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>discriminant</title>
  <short_description>the discriminant of a polynomial</short_description>

<syntax>
discriminant(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
discriminant(F: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function computes the discriminant of a polynomial F (with
respect to a given indeterminate X, if the polynomial is multivariate).
If the polynomial is univariate then there is no need to specify
which indeterminate to use.
<par/>
The discriminant is defined as
<verbatim>
(-1)^(N*(N-1)/2)*det(M)/M[1,1]
</verbatim>
where <code>M := Sylvester(F, deriv(F,X), X)</code>
and  <code>N := deg(F, X)</code>.

<example>
/**/ Use R ::= QQ[x,y];
/**/ discriminant(x^2+3*y^2, x);
-12*y^2

/**/ discriminant(x^2+3*y^2, y);
-12*x^2

/**/ discriminant((x+1)^20+2);
54975581388800000000000000000000
</example>
</description>


<seealso>
  <see>resultant</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>distrib</title>
  <short_description>the distribution of objects in a list</short_description>

<syntax>
distrib(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
For each object E of a list L, let N(E) be the number of times E
occurs as a component of L.  Then Distrib(L) returns the list whose
components are [E, N(E)].

<example>
/**/  distrib(["b","a","b",4,4,[1,2]]);
[["b", 2], ["a", 1], [4, 2], [[1, 2], 1]]
</example>
</description>


<seealso>
  <see>count</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>div</title>
  <short_description>quotient for integers</short_description>
  
<syntax>
div(N: <type>INT</type>, D: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
We define the quotient <tt>Q</tt> and remainder <tt>R</tt> to be integers which
satisfy <formula>N = Q*D + R</formula> with <formula>0 <less_eq/> R &lt; |D|</formula>.
Then <tt>div(N, D)</tt> returns <tt>Q</tt> while <tt>mod(N, D)</tt> returns <tt>R</tt>.
<par/>
NOTE: To perform the division algorithm on a polynomial
use <ttref>NR</ttref> (normal remainder) to find the remainder,
or <ttref>DivAlg</ttref> to get both quotients and remainder.
To determine if a polynomial is in a given ideal or a vector is in a
given module, use <ttref>NF</ttref> or <ttref>IsIn</ttref>, and to
find a representation in terms of the generators <ttref>GenRepr</ttref>.

<example>
/**/ div(10,3);
3
/**/ mod(10,3);
1
</example>
</description>

<seealso>
  <see>DivAlg</see>
  <see>GenRepr</see>
  <see>NF</see>
  <see>NR</see>
  <see>mod</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>DivAlg</title>
  <short_description>division algorithm</short_description>
  
<syntax>
DivAlg(X: <type>RINGELEM</type>, L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>RECORD</rtn>
DivAlg(X: <type>MODULEELEM</type>, L: <type>LIST</type> of <type>MODULEELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function performs the division algorithm on X with respect to L.
It returns a record with two fields: <tt>Quotients</tt> holding a list of
polynomials, and <tt>Remainder</tt> holding the remainder of X upon division
by L.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := x^2*y +x*y^2 +y^2;
/**/  L := [x*y-1, y^2-1];
/**/  DivAlg(F, L);
record[quotients := [x +y, 1], remainder := x +y +1]

/**/  D := It;
/**/  D.quotients;
[x +y, 1]
/**/  D.remainder;
x +y + 1
/**/  ScalarProduct(D.quotients, L) + D.remainder = F;
true

/**/  R2 := NewFreeModule(R,2);
/**/  V := ModuleElem(R2, [x^2+y^2+z^2, x*y*z]);
/**/  L := gens(SubmoduleRows(R2, mat([[x,y], [y,z], [z,x]])));
/**/  D := DivAlg(V, L);
/**/  indent(D);
record[
  quotients := [x, -z^2 +y +z, y*z -y],
  remainder := [z^2, z^3 -y*z -z^2]
]
/**/ sum([D.quotients[i]*L[i] | i in 1..len(L)]) + D.remainder;
[x^2 +y^2 +z^2, x*y*z]
</example>
</description>

<seealso>
  <see>div</see>
  <see>mod</see>
  <see>GenRepr</see>
  <see>NF</see>
  <see>NR</see>
</seealso>
<keys>
  <key>division algorithm</key>
</keys>
</command>

</chapter_letter>
<!-- ===  CHAPTER  =============================================== -->
<chapter_letter>
  <title>E</title>
  
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>E_ [OBSOLETE]</title>
  <short_description>[OBSOLETE] vector of the canonical basis</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] Essentially replaced by <ttref>gens</ttref> of a FreeModule.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  R5 := NewFreeModule(R,5);
/**/  e := gens(R5);
/**/  e[2];
[0, 1, 0, 0, 0]
</example>
</description>
<seealso>
  <see>gens</see>
  <see>GensAsCols, GensAsRows</see>
</seealso>
<keys>
  <key>canonical basis</key>
  <key>canonicalbasis</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>eigenvectors</title>
  <short_description>eigenvalues and eigenvectors of a matrix</short_description>
<syntax>
eigenvectors(M: <type>MAT</type>, X: <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RECORD</rtn>
</syntax>
<description>
<par/>
<tt>M</tt> must be a matrix of numbers, and <tt>X</tt> an indeterminate.
<par/>
This function determines the eigenvalues of <tt>M</tt>, and for each eigenvalue
gives a basis of the corresponding eigenspace -- note that the basis is
probably not orthogonal.  For irrational eigenvalues, the minimal
polynomial of the eigenvalue is given (as a polynomial in <tt>X</tt>), along with
the eigenvectors expressed in terms of a root of the minimal polynomial
(represented as <tt>X</tt>).

<example>
/**/  Use R ::= QQ[x];
/**/  M := mat([[1,2,3],[4,5,6],[7,8,9]]);
/**/  eigenvectors(M, x);
[record[MinPoly := x, eigenspace := matrix(QQ,
 [[-1],
  [2],
  [-1]])], 
record[MinPoly := x^2 -15*x -18,
eigenspace := [[1, (1/8)*x +1/4, (1/4)*x -1/2]]]
]

/**/  M := mat([[0,2,0,0],[1,0,0,0],[0,0,0,2],[0,0,1,0]]);
  eigenvectors(M, x); -- two irrational eigenvalues, each with eigenspace of dimension 2
[record[MinPoly := x^2 -2, eigenspace := [[1, (1/2)*x, 0, 0], [0, 0, 1, (1/2)*x]]]]
</example>
</description>


<keys>
  <key>eigenvalues</key>
  <key>eigenspace</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>elim</title>
  <short_description>eliminate variables</short_description>

<syntax>
elim(X: <type>RINGELEM</type>, M: <type>IDEAL</type>): <rtn>IDEAL</rtn>
elim(L: <type>LIST</type>, M: <type>IDEAL</type>): <rtn>IDEAL</rtn>
elim(X: <type>RINGELEM</type>, M: <type>MODULE</type>): <rtn>MODULE</rtn>
elim(L: <type>LIST</type>, M: <type>MODULE</type>): <rtn>MODULE</rtn>
</syntax>
<description>
This function returns the ideal or module obtained by eliminating the
indeterminate <tt>X</tt>, or all indeterminates in <tt>L</tt>, from <tt>M</tt>.  The coefficient
ring needs to be a field.
<par/>
As opposed to this function, there is also the <em>modifier</em>, <tt>elim</tt>,
used when constructing a ring (see <ref>Orderings</ref>).

<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  E := elim(t, ideal(t^15+t^6+t-x, t^5-y, t^3-z));
/**/ indent(E);
ideal(
  -z^5 +y^3,
  -y^4 -y*z^2 +x*y -z^2,
  -x*y^3*z -y^2*z^3 -x*z^3 +x^2*z -y^2 -y,
  -y^2*z^4 -x^2*y^3 -x*y^2*z^2 -y*z^4 -x^2*z^2 +x^3 -y^2*z -2*y*z -z,
  y^3*z^3 -x*z^3 +y^3 +y^2
)

/**/  Use R ::= QQ[t,s,x,y,z,w];
/**/  t..x;
[t, s, x]

/**/  elim(t..x, ideal(t-x^2*z*w, x^2-t, y^2*t-w)); -- Note the use of t..x.
ideal(-z*w^2 + w)

/**/  Use R ::= QQ[t[1..2], x[1..4]];
/**/  I := ideal(x[1]-t[1]^4, x[2]-t[1]^2*t[2], x[3]-t[1]*t[2]^3, x[4]-t[2]^4);
/**/  elim(indets(R,"t"), I);
ideal(x[2]^4 -x[1]^2*x[4], -x[3]^4 +x[1]*x[4]^3)
</example>
</description>
<seealso>
  <see>Orderings</see>
</seealso>
<types>
  <type>groebner</type>
  <type>groebner-basic</type>
</types>

<keys>
  <key>eliminate</key>
  <key>elimination</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ElimMat</title>
  <short_description>matrix for elimination ordering</short_description>

<syntax>
ElimMat(N: <type>INT</type>, ElimInd: <type>LIST</type>): <rtn>MAT</rtn>
ElimMat(W: <type>MAT</type>, ElimInd: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns an <tt>NxN</tt> matrix for a term ordering
eliminating the indeterminates with indices in <tt>ElimInd</tt>.
If a weight matrix is given, then these weights are included after
the first elimination row.
<example>
/**/  ElimMat(3, [2,3]);
matrix(QQ,
 [[0, 1, 1],
  [1, 1, 1],
  [0, 0, -1]])

/**/  ElimMat(mat([[1,5,0]]), [2,3]);
matrix(QQ,
 [[0, 1, 1],
  [1, 5, 0],
  [0, 0, -1]])
</example>
</description>

<seealso>
  <see>elim</see>
  <see>HomogElimMat</see>
</seealso>

<keys>
  <key>elimination ordering</key>
  <key>blockordering</key>
  <key>block ordering</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>EmbeddingHom</title>
  <short_description>returns the embedding homomorphism of a fraction field</short_description>
<syntax>
EmbeddingHom(K: <type>RING</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
This function returns the embedding homomorphism of the
fraction field <tt>K</tt>.

<example>
/**/ Use P ::= QQ[x,y];
/**/ K := NewFractionField(P);
/**/ phi := EmbeddingHom(K);  -- phi: P -> K 
/**/ f := 2*x+3*y;
/**/ phi(f);
2*x +3*y
/**/ RingOf(phi(f));
RingWithID(5,"FractionField(RingWithID(4))")
</example>
</description>

<keys>
   <key>homomorphism</key>
</keys>

<seealso>
  <see>CanonicalHom</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>EqSet</title>
  <short_description>checks if the set of elements in two lists are equal</short_description>
<syntax>
EqSet(L: <type>LIST</type>, M: <type>LIST</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function returns true if <tt>L</tt> equals <tt>M</tt> as sets,
otherwise it returns false.
<example>
/**/  L := [1,2,2];
/**/  M := [2,1];
/**/  EqSet(L, M);
true
</example>
</description>
<seealso>
  <see>intersection</see>
  <see>IntersectList</see>
  <see>IsSubset</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Equality Test</title>
  <short_description>test whether two values are equal or not</short_description>

<syntax>
A = B
A &lt;&gt; B
  return <rtn>BOOL</rtn>
</syntax>
<description>
The first form returns <tt>true</tt> if <tt>A</tt> is equal to <tt>B</tt>, otherwise
it returns <tt>false</tt> (or signals an error if they are not comparable).
The second form is the same as <tt>not(A=B)</tt>.
<example>
/**/ 1=2;
false
/**/ 1&lt;&gt;2;
true
</example>
</description>

<seealso>
  <see>Comparison Operators</see>
  <see>operators, shortcuts</see>
</seealso>

<keys>
  <key>=</key>
  <key>==</key>
  <key>&lt;&gt;</key>
  <key>equals</key>
  <key>not equals</key>
  <key>notequals</key>
  <key>unequal</key>
  <key>equality</key>
  <key>inequality</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>EquiIsoDec</title>
  <short_description>equidimensional isoradical decomposition</short_description>

<syntax>
EquiIsoDec(I: <type>IDEAL</type>): <rtn>LIST</rtn> of <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes an equidimensional isoradical decomposition of
I, i.e. a list of unmixed ideals <formula>I_1,...,I_k</formula> such that the radical of I
is the intersection of the radicals of <formula>I_1,...,I_k</formula>. Redundancies are
possible.
<par/>
NOTE: at the moment, this implementation works only if the coefficient
ring is the rationals or has large enough characteristic.

<example>
  Use R ::= QQ[x,y,z];
  I := intersect(ideal(x-1,y-1,z-1), ideal(x-2,y-2)^2, ideal(x)^3);
  H := EquiIsoDec(I);
  H;
[ideal(x), ideal(z - 1, y - 1, x - 1), ideal(xy - y^2 - 2x + 2y, x^2 -
y^2 - 4x + 4y, y^2z - y^2 - 4yz + 4y + 4z - 4, y^3 - 5y^2 + 8y - 4, x
- 2)]
-------------------------------
  T := [radical(J)|J In H];
  S := IntersectionList(T);
  radical(I) = S;
True
-------------------------------
</example>
</description>


<seealso>
  <see>PrimaryDecomposition</see>
  <see>radical</see>
  <see>RadicalOfUnmixed</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>equidimensional</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>error</title>
  <short_description>throw an error message</short_description>

<syntax>
error(S: <type>STRING</type>): <rtn>ERROR</rtn>
</syntax>
<description>
This function throws an error containing the given message.
For backward compatibility the function may also be called using
the name <tt>Error</tt>

<example>
/**/ Define T(N)
/**/   If type(N) &lt;&gt; INT Then error("Argument must be an integer."); EndIf;
/**/   Return mod(N,5);
/**/ EndDefine;

-- /**/ T(1/3); --> !!! ERROR !!!
ERROR: Argument must be an integer.
    If type(N) &lt;&gt; INT Then error("Argument must be an integer."); EndIf;
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CONTEXT: function T (previously defined at the prompt)
 called at top-level

/**/  T(7);
2
</example>
</description>


<seealso>
  <see>try</see>
  <see>GetErrMesg</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>eval</title>
  <short_description>substitute numbers or polynomials for indeterminates</short_description>

<syntax>
eval(E: <type>RINGELEM</type>|<type>MODULEELEM</type>|<type>LIST</type>|<type>MAT</type>, L: <type>LIST</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
This function substitutes <tt>L[I]</tt> for <tt>indet(I)</tt> in the
expression E which must be of type POLY, MODULEELEM, LIST, or MAT,
and defined in the current ring.
For more general substitutions use <ttref>subst</ttref>.
<par/>
If <tt>len(L)</tt> is different from <tt>NumIndets()</tt> then only
the first N substitutions are performed, where N is the minumum of the
two values.

<example>
/**/  Use QQ[x,y];
/**/  eval(x^2+y, [2, 3]);
7

/**/  eval(x^2+y, [2]);
y +4

/**/  F := x*(x-1)*(x-2)*y*(y-1)*(y-2)/36;
/**/  P := [1/2, -2/3];
/**/  eval(F, P);
-5/162

/**/  eval([x+y,x-y], [2,1]);
[3, 1]

/**/  eval([x+y,x-y], [x^2,y^2]);
[x^2 + y^2, x^2 - y^2]

/**/  eval([x+y,x-y], [y]);
[2*y, 0]
</example>
</description>


<seealso>
  <see>Evaluation of Polynomials</see>
  <see>subst</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>EvalHilbertFn</title>
  <short_description>evaluate the Hilbert function</short_description>
<syntax>
EvalHilbertFn(H:TAGGED("$hp.Hilbert"), N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function evaluates the Hilbert function H at N.  If H is the
Hilbert function of a quotient R/I, then the value returned is the
same as that returned by <tt>hilbert(R/I, N)</tt> but time is saved since the
Hilbert function does not need to be recalculated at each call.
<example>
/**/  Use R ::= QQ[w,x,y,z];
/**/  I := ideal(z^2-x*y, x*z^2+w^3);
/**/  H := Hilbert(R/I);
/**/  H;
H(0) = 1
H(1) = 4
H(t) = 6t - 3   for t &gt;= 2

/**/  EvalHilbertFn(H,1);
4
/**/  EvalHilbertFn(H,2);
9
</example>
</description>
<seealso>
  <see>HilbertFn</see>
  <see>HilbertPoly</see>
</seealso>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
 <title>Ext</title>
  <short_description>presentation Ext modules as quotients of free modules</short_description>
<syntax>
Ext(I: <type>INT</type>, M:TAGGED("Quotient"), Q:TAGGED("Quotient")): TAGGED("Quotient")
Ext(I: <type>LIST</type>, M:TAGGED("Quotient"), Q:TAGGED("Quotient")): TAGGED("$ext.ExtList")
</syntax>
 <description>
***** NOT YET IMPLEMENTED *****
<par/>
  In the first form the function computes the I-th Ext module of M and N.
It returns a presentation of <formula>Ext^I_R(M, N)</formula> as a quotient of a free module.
  <par />
IMPORTANT: the only exception to the type of M or N (or even of the
output) is when they are either a zero module or a free module.
In these cases their type is indeed MOD. 
  <par />
It computes Ext via a presentation of the quotient of the two modules
  <formula>Ker(Phi*_I)</formula>
  and
  <formula>Im(Phi*_{I-1})</formula>, where
  <par />
  -   <formula>Phi_I</formula>   is the I-th map in the free resolution of M
  <par />
  -   <formula>Phi*_I</formula>   is the map <formula>Hom(Phi_I, N)</formula>
  in the dual of the free resolution.
  <par />
Main differences with the previous version include:
  <par />
- SHIFTS have been removed, consequently  only standard homogeneous
  modules and quotients are supported
  <par />
- as a consequence of 1), the type <tt>Tagged(<quotes>Shifted</quotes>)</tt> has been
  removed. Ext will just be a <tt>Tagged(<quotes>Quotient</quotes>)</tt>
  <par />
- The former functions Presentation(), HomPresentation() and
  KerPresentation() have been removed
  <par />
- The algorithm uses Res() to compute the maps needed, and not
  SyzOfGens anylonger, believed to cause troubles
  <par />
- The function <tt>Ext</tt> always has THREE variables, see syntax...
  <par />

In the second form the variable I is a LIST of nonnegative
integers. In this case the function Ext prints all the Ext modules
corresponding to the integers in I.
The output is of special type <tt>Tagged(<quotes>$ext.ExtList</quotes>)</tt> which is basically
just the list of pairs  <formula>{(J, Ext^J(M, N)) | J in I}</formula> in
which the first element is an integer of I and the second element is
the correpsonding Ext module.
  <par />
VERY IMPORTANT: CoCoA cannot accept  the ring R as one of the inputs,
 so if you want to calculate the module <formula>Ext^I_R(M, R)</formula>
 you need to type something like
  <par />
<tt>Ext(I, M, ideal(1));</tt>
  <par />
or
  <par />
<tt>Ext(I, M, R^1);</tt>
  <par />
or
  <par />
<tt>Ext(I, M, R/ideal(0));</tt>
  <par />
NOTE: The input is pretty flexible in terms of what you can use for M
 and N. For example they can be zero modules or free modules. See some
 examples below.

<example>
  Use R ::= QQ[x,y,z];
  I := ideal(x^5, y^3, z^2);
  ideal(0) : (I);
ideal(0)
-------------------------------
  $hom.Hom(R^1/Module(I), R^1);   -- from Hom package
Module([[0]])
-------------------------------
  Ext(0, R/I, R^1);   --- all those things should be isomorphic
Module([[0]])
-------------------------------
  Ext(0..4, R/I, R/ideal(0)); -- another way to define the ring R as a quotient
Ext^0 = Module([[0]])

Ext^1 = Module([[0]])

Ext^2 = Module([[0]])

Ext^3 = R^1/Module([[x^5], [y^3], [z^2]])

Ext^4 = Module([[0]])

-------------------------------
  N := Module([x^2,y], [x+z,0]);
  Ext(0..4, R/I, R^2/N);
Ext^0 = Module([[0]])

Ext^1 = Module([[0]])

Ext^2 = R^2/Module([[0, x + z], [y, 0], [0, z^2], [z^2, 0], [0, y^3], [x^5, 0]])

Ext^3 = R^2/Module([[x + z, 0], [0, z^2], [z^2, 0], [y^3, 0], [0, x^5], [0, y]])

Ext^4 = Module([[0]])

-------------------------------
</example>

Since version 4.7.3 the output modules are presented minimally.
</description>
<seealso>
  <see>res</see>
  <see>Depth</see>
  <see>MinimalPresentation</see>
</seealso>
<keys>
  <key>author: damiano</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>F</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>factor</title>
  <short_description>factor a polynomial</short_description>
  
<syntax>
factor(F: <type>RINGELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function factorizes a polynomial into irreducibles in its ring of
definition.  Multivariate factorization is not yet supported over finite
fields.   To factorize an integer use <ttref>SmoothFactor</ttref>.
(For information about the algorithm, consult John Abbott's papers)
<par/>
Note: in older versions of CoCoA-5 the field names were <tt>Factors</tt>
and <tt>Exponents</tt>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  F := 4*x^8 + 4*x^6 + x^4 + 4*x^2 + 4;
/**/  FacInfo := factor(F);
/**/  indent(FacInfo);
record[
  RemainingFactor := 1,
  factors := [2*x^4-4*x^3+5*x^2-4*x+2, 2*x^4+4*x^3+5*x^2+4*x+2],
  multiplicities := [1, 1]
]
/**/  G := product([FacInfo.factors[i]^FacInfo.multiplicities[i]
/**/                        | i In 1..len(FacInfo.factors)]);
/**/  F = G * FacInfo.RemainingFactor;
true

/**/  factor((8*x^2 +16*x +8)/27);
record[factors := [x +1], multiplicities := [2], RemainingFactor := 8/27]

/**/  factor(2*x^2-4); -- over a finite field the factors are monic
record[factors := [x^2 -2], multiplicities := [1], RemainingFactor := 2]
---------------------------------
</example>
</description>

<seealso>
  <see>SmoothFactor</see>
  <see>SqFreeFactor</see>
  <see>ContentFreeFactor</see>
</seealso>


<keys>
  <key>factors</key>
  <key>factorise</key>
  <key>factorisation</key>
  <key>factorize</key>
  <key>factorization</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>factorial</title>
  <short_description>factorial function</short_description>

<syntax>
factorial(N: <type>INT</type>): <rtn>INT</rtn>
    </syntax>
<description>
This function returns the factorial of <tt>N</tt>.
<example>
/**/  factorial(5);
120

/**/  factorial(100);
9332621544394415268169923885626670049071596826438162146859
2963895217599993229915608941463976156518286253697920827223
758251185210916864000000000000000000000000
</example>
</description>

<seealso>
  <see>binomial</see>
</seealso>
<keys>
  <key>factorial</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FactorMultiplicity</title>
  <short_description>multiplicity of a factor of an integer</short_description>

<syntax>
FactorMultiplicity(N: <type>INT</type>, Fac: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function counts how many times a given factor divides a given
integer. Obviously Fac must not be -1, 0, or 1, and N must not be zero.

<example>
/**/  FactorMultiplicity(20, 2);
2

/**/  FactorMultiplicity(20, 10);
1

/**/  FactorMultiplicity(20, 7);
0
</example>
</description>
<keys>
  <key>integer factor order</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FGLM5</title>
  <short_description>perform a FGLM Groebner Basis conversion</short_description>

<syntax>
FGLM5(GBOld: <type>LIST</type>, M: <type>MAT</type>): <rtn>LIST</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function is implemented in ApCoCoALib by Stefan Kaspar.
<par/>
The function <tt>FGLM5</tt> calls the CoCoAServer to perform a
FGLM Groebner Basis conversion. Please note that the ideal generated
by the given Groebner Basis must be zero-dimensional. The Groebner
Basis contained in list GBOld will be converted into a Groebner Basis
with respect to term ordering <tt>Ord(M)</tt>, i.e. M must be a matrix
specifying a term ordering.

<example>
  Use QQ[x, y, z], DegRevLex;
  GBOld := *** [z^4 -3z^3 - 4yz + 2z^2 - y + 2z - 2, yz^2 + 2yz - 2z^2
  + 1, y^2 - 2yz + z^2 - z, x + y - z] ***;
  M := LexMat(3);
  GBNew := FGLM5(GBOld, M);
  Use QQ[x, y, z], Ord(M);
  -- New basis (Lex)
  BringIn(GBNew);
</example>
</description>


<seealso>     
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>apcocoalib</key>
  <key>author: kaspar</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>fields</title>
  <short_description>list the fields of a record</short_description>

<syntax>
fields(R: <type>RECORD</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list of all of the fields of the record <tt>R</tt>.
It is particularly useful when you want to know if a record field
has been defined
<example>
/**/  rec := record[name := "David", number := 3728852, data := ["X","Y"] ];
/**/  fields(rec);
["data", "name", "number"]

/**/  rec.data;
["X", "Y"]

/**/  "surname" IsIn fields(rec);
false
</example>
</description>

<seealso>
  <see>record</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>first</title>
  <short_description>the first N elements of a list</short_description>

<syntax>
first(L: <type>LIST</type>): <rtn>OBJECT</rtn>
first(L: <type>LIST</type>, N: <type>INT</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
In the first form the function returns the first element of the list
L, same as <tt>L[1]</tt>.
In the second form, it returns the list of the first N elements of L,
same as <tt>[ L[i] | i in 1..N ]</tt>
<example>
/**/  L := [1,2,3,4,5];
/**/  first(L);
1

/**/  first(L,3);
[1, 2, 3]
</example>
</description>


<seealso>
  <see>last</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FirstNonZero</title>
  <short_description>the first non-zero entry in a MODULEELEM</short_description>
<syntax>
FirstNonZero(V: <type>MODULEELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the first non-zero entry of V.  If it
is handed a zero MODULEELEM then an error is signalled.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  R5 := NewFreeModule(R,5);
/**/  V := ModuleElem(R5, [0, 0, x^2+y*z, 0, z^2]);

/**/  FirstNonZero(V);
x^2 +y*z

/**/  FirstNonZeroPosn(V);
2
</example>
</description>
<seealso>
  <see>FirstNonZeroPosn</see>
  <see>IsZero</see>
  <see>NonZero</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FirstNonZeroPosn</title>
  <short_description>the first non-zero entry in a MODULEELEM</short_description>
<syntax>
FirstNonZeroPosn(V: <type>MODULEELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the index of the first non-zero entry of V.  If it
is handed a zero MODULEELEM then an error is signalled.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  R5 := NewFreeModule(R,5);
/**/  V := ModuleElem(R5, [0, 0, x^2+y*z, 0, z^2]);

/**/  FirstNonZero(V);
x^2 +y*z

/**/  FirstNonZeroPosn(V);
2
</example>
</description>
<seealso>
  <see>FirstNonZero</see>
  <see>IsZero</see>
  <see>NonZero</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>flatten</title>
  <short_description>flatten a list</short_description>

<syntax>
flatten(L: <type>LIST</type>): <rtn>LIST</rtn>
flatten(L: <type>LIST</type>, N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
Components of lists may be lists themselves, i.e., lists may be
nested.  With one argument this function returns the list obtained
from the list <tt>L</tt> by removing all nesting, bringing all elements <em>to
the top level</em>.  With the optional second argument, <tt>N</tt>, nesting is
removed down <tt>N</tt> levels.
Thus, the elements of <tt>M := flatten(L,1)</tt> are formed as
follows: go through the elements of <tt>L</tt> one at a time; if an 
elements is not a list, add it to <tt>M</tt>; if an element is a list,
add all of its elements to <tt>M</tt>.
Recursively, <tt>Flatten(L, N) = Flatten(Flatten(L, N-1),1)</tt>.
For <tt>N</tt> large, depending on <tt>L</tt>, <tt>Flatten(L, N)</tt>
gives the same result as <tt>Flatten(L)</tt>.
<example>
/**/  flatten([1,["a","b",[2,3,4],"c","d"],5,6]);
[1, "a", "b", 2, 3, 4, "c", "d", 5, 6]

/**/  L := [1,2, [3,4], [5, [6,7,[8,9]]]];
/**/  flatten(L,1);
[1, 2, 3, 4, 5, [6, 7, [8, 9]]]

/**/  flatten(It,1);
[1, 2, 3, 4, 5, 6, 7, [8, 9]]

/**/  flatten(L,2);  -- same as flatten(flatten(L,1),1)
[1, 2, 3, 4, 5, 6, 7, [8, 9]]

/**/  flatten(L,3);  -- same as flatten(L)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FloatApprox</title>
  <short_description>approx. of rational number of the form <formula>M*2^E</formula></short_description>


<syntax>
FloatApprox(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, PrecBits: <type>INT</type>): <rtn>RAT</rtn>
  </syntax>
  <description>
This function computes an approximation of the form <formula>M*2^E</formula> to
a rational number <tt>X</tt> where the mantissa satisfies <formula>2^(B-1) <less_eq/> |M| &lt; 2^B-1</formula>
where <formula>B</formula> is the specified bit precision.  It gives 0 when applied to 0.
<par/>
The updated version of this function is not backward compatible with the
old one; you must replace the 2nd arg by the number of bits you want in
the mantissa (see <ttref>ILogBase</ttref>).  The old fn is obsolescent and is
now called <tt>FloatApprox10</tt>.
<example>
/**/  FloatApprox(1/3, 10);
683/2048

/**/  FloatApprox(1/3, 20);
699051/2097152

/**/  FloatApprox(123456789,8);
123207680
</example>
</description>

<seealso>
  <see>CFApprox</see>
  <see>FloatStr</see>
  <see>MantissaAndExponent2</see>
</seealso>

<keys>
  <key>rational approximation</key>
  <key>floating point</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FloatStr</title>
  <short_description>convert rational number to a decimal string</short_description>


<syntax>
FloatStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>): <rtn>STRING</rtn>
FloatStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, Prec: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function produces a decimal string representation of the rational
number <tt>X</tt>.  The optional second argument <tt>Prec</tt> says how many
significant decimal digits to produce; the default value is 5.

The aim is to produce an easily readable result.
<example>
/**/  FloatStr(2/3);      -- last printed digit is rounded
0.66667

/**/  FloatStr(7^510);    -- no arbitrary limit on exponent range
1.0000*10^431

/**/  FloatStr(1/81, 50);    -- precision of mantissa specified by user
0.012345679012345679012345679012345679012345679012346

/**/  FloatStr(987654/321);
3076.8
</example>
</description>

<seealso>
  <see>DecimalStr</see>
  <see>ScientificStr</see>
  <see>FloatApprox</see>
  <see>MantissaAndExponent10</see>
</seealso>
<keys>
  <key>printing rational numbers</key>
  <key>decimal</key>
  <key>floating point</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>floor</title>
  <short_description>round rational down to integer</short_description>

<syntax>
floor(X: <type>RAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the greatest integer less than or equal to <tt>X</tt>.

<example>
/**/  floor(0.99);
0

/**/  floor(1.01);
1

/**/  floor(-1);
-1

/**/  floor(-0.01);
-1
</example>
</description>

<seealso>
  <see>ceil</see>
  <see>round</see>
  <see>num</see>
  <see>den</see>
</seealso>
<keys>
  <key>round down</key>
  <key>rounding</key>
  <key>integer part</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>for</title>
  <short_description>loop command</short_description>

<syntax>
For I := N_1 To N_2 Do C EndFor
For I := N_1 To N_2 Step D Do C EndFor

where I is a dummy variable, N_1, N_2, and D are integer expressions,
and C is a sequence of commands.
</syntax>
<description>
In the first form, the variable I is assigned the values
<tt>N_1, N_1+1, ...,N_2</tt>
in succession.  After each assignment, the command sequence C
is executed.  The second form is the same, except that I is assigned
the values <tt>N_1, N_1+D, N_1+2D</tt>, etc. until the greatest value less than
or equal to <tt>N_2</tt> is reached.  If <tt>N_2 &lt; N_1</tt>, then C is not executed.
<par/>
NOTE: Large values for <tt>N_1, N_2</tt>, or D are not permitted; typically
      they should lie in the range about <formula>-10^9</formula> to <formula>+10^9</formula>.
<par/>
NOTE: Don&apos;t forget the capitalization in the word <tt>To</tt>.

<example>
/**/  For N := 1 To 5 Do Print 2^N, " "; EndFor;
2 4 8 16 32

/**/  for n := 1 to 20 step 3 do print n, " "; endfor;
1 4 7 10 13 16 19

/**/  for N := 10 To 1 Step -2 Do Print N, " "; EndFor;
10 8 6 4 2

/**/  For N := 5 To 3 Do Print N, " "; endfor;  -- no output
</example>

Loops can be nested.

<example>
/**/   Define MySort(ref L)
/**/     For I := 1 To len(L)-1 Do
/**/       M := I;
/**/       For J := I+1 To len(L) Do
/**/         If L[J] &lt; L[M] Then M := J; EndIf;
/**/       EndFor;
/**/       If M &lt;&gt; I Then
/**/         C := L[M];
/**/         L[M] := L[I];
/**/         L[I] := C;
/**/       EndIf;
/**/     EndFor;
/**/   EndDefine;

/**/  M := [5,3,1,4,2];
/**/  MySort(ref M);
/**/  M;
[1, 2, 3, 4, 5]
</example>

(Note that <tt>ref L</tt> is used so that the function can change the value
of the variable referenced by L.  See <tt>ref</tt>.)
</description>


<seealso>
  <see>foreach</see>
  <see>repeat</see>
  <see>while</see>
</seealso>

<types>
  <type>command</type>
  <type>programming</type>
  <type>loops</type>
</types>

<keys>
  <key>step</key>
  <key>downto</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>foreach</title>
  <short_description>loop command</short_description>
<syntax>
foreach  X  in  L  do  CMDS  endforeach
where <tt>X</tt> is a dummy variable, <tt>L</tt> is a <type>LIST</type>
</syntax>
<description>
The dummy variable <tt>X</tt> is assigned the value of each component
of <tt>L</tt> in turn.
After each assignment the command sequence <tt>CMDS</tt> is executed.
<example>
/**/  foreach N In 1..10 Do  -- Note: 1..10 gives the list [1,...,10].
/**/    print N^2, " ";
/**/  endforeach;
1 4 9 16 25 36 49 64 81 100

/**/  Use R ::= QQ[x,y,z];
/**/  F := x^2*y + 3*y^2*z - z^3;
/**/  J := [deriv(F, X) | X In indets(R)];
/**/  J;
[2*x*y, x^2 +6*y*z, 3*y^2 -3*z^2]

/**/  Foreach X In J Do
/**/    PrintLn X^2;
/**/  EndForeach;
4*x^2*y^2
x^4 +12*x^2*y*z +36*y^2*z^2
9*y^4 -18*y^2*z^2 +9*z^4
</example>
</description>
<seealso>
  <see>for</see>
  <see>repeat</see>
  <see>while</see>
</seealso>
<types>
  <type>command</type>
  <type>programming</type>
  <type>loops</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>format</title>
  <short_description>convert object to formatted string</short_description>
<syntax>
format(E: <type>OBJECT</type>, N: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
Like Sprint, this function converts the value of E into a string.  If
the string has fewer than N characters, then spaces are added to the
front to make the length N.

<example>
/**/  L := [5^n | n In 0..7];
/**/  Foreach F In L Do print Format(F,8); EndForeach;
       1       5      25     125     625    3125   15625   78125

/**/  M := Format(L,20);
/**/  M;  -- "Format" does not truncate
[1, 5, 25, 125, 625, 3125, 15625, 78125]
/**/  type(L);
LIST
/**/  type(M);
STRING
</example>
</description>

<seealso>
  <see>IO.SprintTrunc</see>
  <see>LaTeX</see>
  <see>sprint</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

<keys>
  <key>formatted printing</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FrbAlexanderDual</title>
  <short_description>Alexander Dual of monomial ideals</short_description>

<syntax>
FrbAlexanderDual(I: <type>IDEAL</type>): <rtn>LIST</rtn>
FrbAlexanderDual(I: <type>IDEAL</type>, T: <type>RINGELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
Using the <ttref>Frobby</ttref> library linked with CoCoALib.
Thanks to Bjarke Roune.
<example>
/**/  I := ideal(x^2, x*y, y^2, z^2);
/**/  FrbAlexanderDual(I);
ideal(x^2*y*z, x*y^2*z)

/**/  FrbAlexanderDual(I, x^2*y^2*z^5);
ideal(x^2*y*z^4, x*y^2*z^4)
</example>
</description>
<keys>
  <key>frobby</key>
  <key>author: bjarke roune</key>
</keys>

<seealso>
  <see>Frobby</see>
  <see>FrbPrimaryDecomposition</see>
  <see>PrimaryDecomposition</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FrbAssociatedPrimes</title>
  <short_description>Associated primes of monomial ideals</short_description>

<syntax>
FrbAssociatedPrimes(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
Using the <ttref>Frobby</ttref> C++ library by Bjarke Roune.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x^2, x*y, y^2, z^2);
/**/  FrbAssociatedPrimes(I);
[ideal(x, y, z)]
</example>
</description>
<keys>
  <key>frobby</key>
  <key>author: bjarke roune</key>
</keys>

<seealso>
  <see>Frobby</see>
  <see>FrbIrreducibleDecomposition</see>
  <see>FrbPrimaryDecomposition</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FrbIrreducibleDecomposition</title>
  <short_description>Irreducible decomposition of monomial ideals</short_description>

<syntax>
FrbIrreducibleDecomposition(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
Using the <ttref>Frobby</ttref> C++ library by Bjarke Roune.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x^2, x*y, y^2, z^2);
/**/  FrbIrreducibleDecomposition(I);
[ideal(x, y^2, z^2), ideal(x^2, y, z^2)];

-- *** missing manual for these function: volunteers? ;-) ***
FrbDimension
FrbMultigradedHilbertPoincareNumerator
FrbTotalDegreeHilbertPoincareNumerator
</example>
</description>
<keys>
  <key>frobby</key>
  <key>author: bjarke roune</key>
</keys>

<seealso>
  <see>Frobby</see>
  <see>FrbAssociatedPrimes</see>
  <see>FrbIrreducibleDecomposition</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FrbMaximalStandardMonomials</title>
  <short_description>Maximal standard monomials of monomial ideals</short_description>

<syntax>
FrbMaximalStandardMonomials(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
Using the <ttref>Frobby</ttref> library linked with CoCoALib.
<example>
/**/  I := ideal(x^2, x*y, y^2, z^2);
/**/  FrbMaximalStandardMonomials(I);
ideal(y*z, x*z)
</example>
</description>
<keys>
  <key>frobby</key>
  <key>author: bjarke roune</key>
</keys>

<seealso>
  <see>Frobby</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>FrbPrimaryDecomposition</title>
  <short_description>Primary decomposition of monomial ideals</short_description>
<syntax>
FrbPrimaryDecomposition(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
Using the <ttref>Frobby</ttref> C++ library by Bjarke Roune.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x^2, x*y^2, z^2);
/**/  FrbPrimaryDecomposition(I);
[ideal(x^2, y^2, z^2), ideal(x, z^2)]
</example>
</description>
<keys>
  <key>frobby</key>
  <key>author: bjarke roune</key>
</keys>
<seealso>
  <see>Frobby</see>
  <see>FrbAssociatedPrimes</see>
  <see>FrbIrreducibleDecomposition</see>
  <see>PrimaryDecomposition</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>func</title>
  <short_description>Anonymous function</short_description>
<syntax>
Func ... EndFunc
  returns <rtn>FUNCTION</rtn>
</syntax>
<description>
This syntatic structure defines a function without giving it a name;
anonymous functions can be passed as parameters and assigned to variables.
Note that <tt>Func...EndFunc</tt> can be used inside function definitions.
<example>
/**/  square := Func(x) Return x^2; EndFunc;
/**/  square(3);
9

/**/  SortedBy(["zzz", "x", "yy"], Func(x,y) Return len(x)>len(y); EndFunc);
["zzz", "yy", "x"]
</example>
</description>
<seealso>
  <see>define</see>
  <see>TopLevel</see>
  <see>ImportByRef, ImportByValue</see>
</seealso>
<keys>
  <key>anonymous functions</key>
  <key>lambda function</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Function [OBSOLETE]</title>
  <short_description>[OBSOLETE]</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] 
In CoCoA-5 functions are "first class objects", and so may be passed
like any other value -- the operator <tt>Function</tt> serves no purpose.
<par/>
In CoCoA-4 it was possible to have a variable and a function with the
same name; the operator <tt>Function</tt> was used to instruct CoCoA-4
to search for the function of the given name, <i>e.g.</i> to pass it as
an argument to another function.
</description>
<seealso>
  <see>FUNCTIONs are first class objects</see>
  <see>SortBy</see>
  <see>SortedBy</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>functions [OBSOLETE]</title>
  <short_description>[OBSOLETE] replaced by describe</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] please use the command <ttref>describe</ttref>.
</description>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>G</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GBasis</title>
  <short_description>calculate a Groebner basis</short_description>

<syntax>
GBasis(I: <type>IDEAL</type>|<type>MODULE</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list whose components form a Groebner basis for the
ideal (or module) <tt>I</tt> with respect to the term-ordering of the
polynomial ring of <tt>I</tt>.
<par/>
If <tt>I</tt> is a variable then the result is stored in <tt>I</tt> for later use.
<par/>
For the reduced Groebner basis, use the command <ref>ReducedGBasis</ref>.
<par/>
The coefficient ring must be a field.
<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x^4-x^2, x^3-y);
/**/  GBasis(I);
[-x^2 +x*y, -x*y +y^2, y^3 -y]
</example>
</description>

<seealso>
  <see>GBasisTimeout</see>
</seealso>

<types>
  <type>groebner</type>
  <type>groebner-basic</type>
</types>

<keys>
  <key>grobner basis</key>
  <key>groebner basis</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GBasisTimeout</title>
  <short_description>compute a Groebner basis with a timeout</short_description>

<syntax>
GBasisTimeout(I: <type>IDEAL</type>, SECONDS: <type>INT</type>): <rtn>LIST</rtn>
GBasisTimeout(M: <type>MODULE</type>, SECONDS: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
Same as <ttref>GBasis</ttref>, but it will stop and return an error if
the computation is not completed.
<par/>
For dealing with errors see <ttref>try</ttref>.

<example>
  Use R ::= QQ[t,x,y,z];
  I := ideal(t^3-x, t^4-y, t^5-z);
  J := I^5; Time G := GBasisTimeout(J, 1);
ERROR: Time expired: use $gb.Complete to complete the computation
CONTEXT: Error(GBasisTimeout_Err)
-------------------------------
  J := I^5; Time G := GBasisTimeout(J, 10);
Cpu time = 1.96, User time = 2
-------------------------------
</example>

</description>


<seealso>
  <see>GBasis</see>
  <see>try</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GBM</title>
  <short_description>intersection of ideals for zero-dimensional schemes</short_description>

<syntax>
GBM(L: <type>LIST</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes the intersection of ideals corresponding to
zero-dimensional schemes: GBM is for affine schemes, and <ttref>HGBM</ttref> for
projective schemes.  The list L must be a list of ideals.  The function
<ttref>IntersectList</ttref> should be used for computing the intersection of a
collection of general ideals.
<par/>
The name GBM comes from the name of the algorithm used: Generalized
Buchberger-Moeller.

<example>
/**/  Use P ::= QQ[x,y,z];
/**/  I1 := IdealOfPoints(P, mat([[1,2,1], [0,1,0]])); -- a simple affine scheme
/**/  I2 := IdealOfPoints(P, mat([[1,1,1], [2,0,1]]))^2;-- another affine scheme

***** NOT YET IMPLEMENTED *****
  GBM([I1, I2]);                                  -- intersect the ideals
ideal(xz + yz - z^2 - x - y + 1,
 z^3 - 2z^2 + z,
 yz^2 - 2yz - z^2 + y + 2z - 1,
 y^2z - y^2 - yz + y,
 xy^2 + y^3 - 2x^2 - 5xy - 5y^2 + 2z^2 + 8x + 10y - 4z - 6,
 x^2y - y^3 + 2x^2 + 2xy + 4y^2 - 3z^2 - 8x - 8y + 6z + 5,
 x^3 + y^3 - 7x^2 - 5xy - 4y^2 + 5z^2 + 16x + 10y - 10z - 7,
 y^4 - 2y^3 - 4x^2 - 8xy - 3y^2 + 4z^2 + 16x + 16y - 8z - 12)
-------------------------------
</example>
</description>


<seealso>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>HGBM</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>fat</key>
  <key>point</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>gcd</title>
  <short_description>greatest common divisor</short_description>

<syntax>
gcd(F: <type>INT</type>,G: <type>INT</type>): <rtn>INT</rtn>
gcd(L: <type>LIST</type> of <type>INT</type>): <rtn>INT</rtn>

gcd(F: <type>RINGELEM</type>, G: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
gcd(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the greatest common divisor of <tt>F_1,...,F_n</tt>
or of the elements in the list L.
For the calculation of the GCDs and LCMs of polynomials, the
coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[x,y];
/**/  F := x^2-y^2;
/**/  G := (x+y)^3;
/**/  gcd(F, G);
-x -y

/**/  gcd([3*4,3*8,6*16]);
12
</example>
</description>

<seealso>
  <see>div</see>
  <see>mod</see>
  <see>lcm</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>greatest common divisor</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GCDFreeBasis</title>
  <short_description>determine (minimal) GCD free basis of a set of integers</short_description>

<syntax>
GCDFreeBasis(L: <type>LIST</type> of <type>INT</type>): <rtn>LIST</rtn> of <type>INT</type>
</syntax>
<description>
This function returns a GCD free basis of a set of integers; you can
think of this as the set of all numbers (except 1) obtainable by performing GCD
and exact division operations.
<par/>
Given a set <formula>N = [ N_1,...N_k ]</formula> we seek a basis <formula>G = [ G_1,...,G_s ]</formula> such that
each <formula>N_i</formula> is a product of powers of the <formula>G_j</formula>, and the <formula>G_j</formula> are pairwise
coprime; the set <formula>G</formula> is called a GCD free basis for <formula>N</formula>.  In general the set
<formula>G</formula> is not uniquely defined.

<example>
/**/  GCDFreeBasis([factorial(20), factorial(10)]);
[46189, 4, 14175]
</example>
</description>


<seealso>
  <see>gcd</see>
</seealso>
<keys>
  <key>gcd free basis</key>
  <key>greatest common divisor</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GenericPoints</title>
  <short_description>random projective points</short_description>

<syntax>
GenericPoints(R: <type>RING</type>, NumPoints: <type>INT</type>): <rtn>LIST</rtn>
GenericPoints(R: <type>RING</type>, NumPoints: <type>INT</type>, RandomRange: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
<tt>GenericPoints</tt> returns a list of NumPoints generic projective points
with integer coordinates; it is not guaranteed that these points are
distinct.  RandomRange specifies the largest value any coordinate may
take.  If the second argument is omitted, the largest value possible
is 100 (or P-1 where P is the characteristic of the coefficient ring).

<example>
/**/  Use R ::= QQ[x,y];  GenericPoints(R,7);
[[1, 0], [0, 1], [1, 1], [12, 59], [6, 63], [12, 80], [17, 63]]

/**/  GenericPoints(R,7,500);
[[1, 0], [0, 1], [1, 1], [220, 162], [206, 452], [98, 106], [403, 449]]

/**/  Use R ::= ZZ/(5)[x,y,z];
/**/  GenericPoints(R,7);
[[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [2, 1, 1], [2, 2, 4], [3, 1, 3]]

/**/  GenericPoints(R,7,500);
[[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 4, 2], [1, 3, 2], [2, 3, 3]]
</example>
</description>


<types>
  <type>points</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GenRepr</title>
  <short_description>representation in terms of generators</short_description>
<syntax>
GenRepr(X: <type>RINGELEM</type>, I: <type>IDEAL</type>): <rtn>LIST</rtn> of RINGELEM
GenRepr(X: <type>MODULEELEM</type>, I: <type>MODULE</type>): <rtn>LIST</rtn> of RINGELEM
</syntax>
<description>
This function returns a list giving a representation of X in terms of
generators for I. Let the generators for I be <tt>[G_1,...,G_t]</tt>.  If X is
in I, then <tt>GenRepr</tt> will return a list <tt>[F_1,...,F_t]</tt> such that
<verbatim>
             X = F_1*G_1 + ... + F_t*G_t.
</verbatim>
If X is not in I, then <tt>GenRepr</tt> returns the empty list, [].

<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x+y^2, x^2-x*y);
/**/  GenRepr(x^3-x^2*y-y^3-x*y, I);
[-y, x]
/**/  -y*gens(I)[1] + x*gens(I)[2];
x^3 -x^2*y -y^3 -x*y
/**/  GenRepr(x+y, I);  -- x+y is not in I
[ ]

/**/  K := NewFractionField(NewPolyRing(QQ, ["a"]));
/**/  Use R ::= K[x,y];
/**/  L := [x+y^2, x^2-x*y];
/**/  GenRepr((a-2)*L[1] - (x-a)*L[2], ideal(L));
[a -2, -x +a]

/**/  R3 := NewFreeModule(R,3);
/**/  V1 := ModuleElem(R3, [x, y, y^2]);
/**/  V2 := ModuleElem(R3, [x-y, 0, x^2]);
/**/  V  := x^2*V1 - y^2*V2;
/**/  M := submodule(R3, [V1, V2]);
--/**/  GenRepr(V, M); -- NOT YET IMPLEMENTED *****
--[x^2, -y^2]
</example>
</description>
<seealso>
  <see>DivAlg</see>
  <see>IsIn</see>
  <see>NF</see>
  <see>syz</see>
  <see>SyzOfGens</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>gens</title>
  <short_description>list of generators of an ideal</short_description>

<syntax>
gens(I: <type>IDEAL</type>): <rtn>LIST</rtn>
gens(M: <type>MODULE</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list of polynomials which generate the ideal
I or the module M.  The list is not necessarily minimal.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(y^2-x^3, x*y);
/**/  gens(I);
[-x^3 +y^2, x*y]

/**/  gens(I^2);
[x^6 -2x^3*y^2 +y^4, -x^4*y +x*y^3, x^2*y^2]

/**/  R3 := NewFreeModule(R, 3);
/**/  e := gens(R3);  // canonical basis
/**/  e[2];
[0, 1, 0]

/**/  M := SubmoduleRows(R3, mat([[x,y,z], [x-1,0,z]]));
/**/  gens(M);
[[x, y, z], [x -1, 0, z]]
/**/  shape(It);
[MODULEELEM, MODULEELEM]
/**/  GensAsRows(M);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[x, y, z],
  [x -1, 0, z]])
</example>
</description>
<seealso>
  <see>GensAsCols, GensAsRows</see>
  <see>minimalize</see>
  <see>minimalized</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GensAsCols, GensAsRows</title>
  <short_description>matrix of generators of a module</short_description>

<syntax>
GensAsRows(M: <type>MODULE</type>): <rtn>MAT</rtn>
GensAsCols(M: <type>MODULE</type>): <rtn>MAT</rtn>
</syntax>
<description>
These functions returns a matrix which generate the module M
with the components as row (or colums) of a matrix.
<par/>
The generators are not necessarily minimal.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  R3 := NewFreeModule(R, 3);
/**/  L := [[x,y,z], [x-1,0,z]];
/**/  M := SubmoduleRows(R3, mat(L));
/**/  gens(M);
[[x, y, z], [x -1, 0, z]]
/**/ shape(It);
[MODULEELEM, MODULEELEM]

/**/ GensAsRows(M);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[x, y, z],
  [x -1, 0, z]])

/**/ GensAsCols(M);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[x, x -1],
  [y, 0],
  [z, z]])
</example>
</description>
<seealso>
  <see>gens</see>
  <see>SubmoduleCols, SubmoduleRows</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Get</title>
  <short_description>read characters from a device</short_description>

<syntax>
Get(D: <type>DEVICE</type>, N: <type>INT</type>): <rtn>LIST</rtn> of <type>INT</type>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function reads N characters from D and returns the list of
their ASCII codes.

<example>
  D := OpenIFile("io.cpkg");  -- open the file "io.cpkg"
  Get(D,10);  -- get the first 10 characters
[45, 45, 32, 105, 111, 100, 101, 118, 46, 112]
-------------------------------
  ascii(It); convert the ASCII code to characters
-- iodev.p
-------------------------------
  ascii(Get(D,10));  -- get the next 10 characters and convert
kg : 0.1 :
-------------------------------
  Close(D);
</example>

The instruction <tt>Get(DEV.STDIN,3)</tt>, for instance, will read
3 characters typed in by the user.
Clever use of this function can be used to prompt a
user for input to a function, although it is usually easier for
functions to take input directly as arguments.
NOTE: this function does not work properly under the GUI Interface.
</description>


<seealso>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetCol</title>
  <short_description>convert a column of a matrix into a list</short_description>

<syntax>
GetCol(M: <type>MAT</type>, K: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function makes a list containing the entries of the <tt>K</tt>-th column of <tt>M</tt>.
<example>
/**/  M := mat([[1,2], [3,4]]);
/**/  GetCol(M,2);
[2, 4]
</example>
</description>

<seealso>
  <see>GetRow</see>
  <see>GetCols</see>
</seealso>
<keys>
  <key>matrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetCols</title>
  <short_description>convert a matrix into a list of lists</short_description>

<syntax>
GetCols(M: <type>MAT</type>): <rtn>LIST</rtn> of LIST
</syntax>
<description>
This function produces a list of lists containing the columns of <tt>M</tt>.
<example>
/**/  M := mat([[1,2], [3,4]]);
/**/  GetCols(M);
[[1, 3], [2, 4]]
</example>
</description>

<seealso>
  <see>GetCol</see>
  <see>GetRows</see>
</seealso>
<keys>
  <key>matrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetEnv</title>
  <short_description>access shell variables</short_description>

<syntax>
GetEnv(S: <type>STRING</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns the value of system shell variables

<example>
/**/  GetEnv("HOME");
/Users/bigatti

/**/  GetEnv("COCOARC");
/Users/bigatti/.cocoarc

/**/  GetEnv("COCOA_PACKAGES");
/Applications/CoCoA-4.7/packages
</example>
</description>

<keys>
  <key>home</key>
  <key>path</key>
  <key>shell</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetErrMesg</title>
  <short_description>returns the message associated with an error</short_description>

<syntax>
GetErrMesg(E: <type>ERROR</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns the string containing the error message
associated with an error.

<example>
/**/  ErrMsg := ""; 

  Try
    F := 1/0;
  UponError E Do
    ErrMsg := GetErrMesg(E);
  EndTry;  -- no error is thrown with Try .. UponError .. EndTry

/**/ ErrMsg;
Division by zero or by a zero-divisor
</example>
</description>


<seealso>
  <see>try</see>
  <see>error</see>
</seealso>
<keys>
  <key>message</key>
  <key>msg</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetRow</title>
  <short_description>convert a row of a matrix into a list</short_description>

<syntax>
GetRow(M: <type>MAT</type>, K: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function makes a list containing the entries of the <tt>K</tt>-th row of <tt>M</tt>.
<example>
/**/  M := mat([[1,2], [3,4]]);
/**/  GetRow(M,2);
[3, 4]
</example>
</description>

<seealso>
  <see>GetRows</see>
  <see>SetRow</see>
</seealso>
<keys>
  <key>matrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GetRows</title>
  <short_description>convert a matrix into a list of lists</short_description>

<syntax>
GetRows(M: <type>MAT</type>): <rtn>LIST</rtn> of LIST
</syntax>
<description>
This function produces a list of lists containing the rows of <tt>M</tt>.
<example>
/**/  M := mat([[1,2], [3,4]]);
/**/  GetRows(M);
[[1, 2], [3, 4]]
</example>
</description>

<seealso>
  <see>GetRow</see>
</seealso>
<keys>
  <key>matrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>gin</title>
  <short_description>generic initial ideal</short_description>
<syntax>
gin(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
gin(I: <type>IDEAL</type>, VerboseFlag: <type>STRING</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
These functions return the [probabilistic] gin (generic initial ideal)
of the ideal <tt>I</tt>.
It is obtained by computing twice the leading term ideal of <formula>g(I)</formula>,
where <formula>g</formula> is a random change of coordinates with 
integer coefficients in the range <formula>[-10^6, 10^6]</formula>
using TwinFloats (see <ttref>NewRingTwinFloat</ttref>) to allow a much
wider range of coefficients than a direct computation over the
rationals (use second argument to see the TwinFloat precision needed).
<example>
/**/  Use R ::= QQ[x,y,z], DegRevLex;
/**/  gin(ideal(y^2-x*z, x^2*z-y*z^2));  -- computed twice using TwinFloats
ideal(x^2, x*y^2, y^4)

/**/  gin(ideal(y^7-x^4*z^3, x^5*z-y*z^5), "verbose");
-- trying with FloatPrecision 64
-- trying with FloatPrecision 64
ideal(x^6, x^5*y^2, x^4*y^4, x^3*y^6, x^2*y^8, x*y^10, y^12)
</example>
</description>
<keys>
  <key>generic initial ideal</key>
</keys>
<seealso>
  <see>NewRingTwinFloat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GradingDim</title>
  <short_description>Number of components in weighted degree</short_description>
<syntax>
GradingDim(P): <rtn>INT</rtn>
</syntax>
<description>
This function returns the grading dimension of a polynomial ring, i.e.
how many of the rows of OrderMatrix are to be taken as specifying the grading.
<example>
/**/  OrdM := CompleteToOrd(RowMat([2,3]));
/**/  P := NewPolyRing(QQ, ["x","y"], OrdM, 1);
/**/  GradingDim(P);
1
</example>
</description>
<seealso>
  <see>NewPolyRing</see>
  <see>GradingMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>GradingMat</title>
  <short_description>matrix of generalized weights for indeterminates</short_description>
<syntax>
WeightsMatrix(R: <type>RING</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the grading matrix (or weights matrix) for the
polynomials ring <tt>R</tt>.
<example>
/**/  OrdM := CompleteToOrd(RowMat([2,3]));  OrdM;
matrix(QQ,
 [[2, 3],
  [0, -1]])
/**/  P := NewPolyRing(QQ, ["x","y"], OrdM, 1);  -- GradingDim = 1
/**/  WeightsMatrix(P);
matrix([
  [2, 3]
])

/**/  Use P;
/**/  deg(x*y);
2
/**/  wdeg(x*y);
[5]
</example>
</description>
<seealso>
  <see>deg</see>
  <see>wdeg</see>
  <see>GradingDim</see>
  <see>NewPolyRing</see>
</seealso>
<keys> 
  <key>WeightsList</key>
  <key>WeightsMatrix</key>
  <key>weights matrix</key>
  <key>grading matrix</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>H</title>

<!-- ===  COMMAND-rm Head =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HColon</title>
  <short_description>ideal or module quotient</short_description>

<syntax>
HColon(M: <type>IDEAL</type>, N: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
The function <ttref>colon</ttref> returns the quotient of M by N:
the ideal of all polynomials F such that F*G is in M for all G in N.
<par/>
This function computes the same ideal using a Hilbert-driven
algorithm. It differs from <ttref>colon</ttref> only when the input
is non-homogeneous, in which case, <tt>HColon</tt> may be faster.

<example>
  Use R ::= QQ[x,y];
  ideal(xy, x^2) : ideal(x);
ideal(y, x)
-------------------------------
  colon(ideal(x^2, xy), ideal(x, x-y^2));
ideal(x)
-------------------------------
  HColon(ideal(x^2, xy), ideal(x, x-y^2));
ideal(x)
-------------------------------
</example>
</description>


<seealso>
  <see>HSaturation</see>
  <see>saturate</see>
  <see>HColon</see>
  <see>colon</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND-rm Help =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HGBM</title>
  <short_description>intersection of ideals for zero-dimensional schemes</short_description>

<syntax>
HGBM(L: <type>LIST</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes the intersection of ideals corresponding to
zero-dimensional schemes: <ttref>GBM</ttref> is for affine schemes, and HGBM for
projective schemes.  The list L must be a list of ideals.  The function
<ttref>IntersectList</ttref> should be used for computing the intersection of a
collection of general ideals.
<par/>
The name GBM comes from the name of the algorithm used: Generalized
Buchberger-Moeller.  The prefix H comes from Homogeneous since ideals
of projective schemes are necessarily homogeneous.

<example>
  Use QQ[x[0..2]];
  I1 := IdealOfProjectivePoints([[1,2,1], [0,1,0]]);   -- simple projective scheme
  I2 := IdealOfProjectivePoints([[1,1,1], [2,0,1]])^2; -- another projective scheme
  HGBM([I1, I2]);                                      -- intersect the ideals
ideal(x[0]^3 - x[0]x[1]^2 - 5x[0]^2x[2] + x[1]^2x[2] + 8x[0]x[2]^2 - 4x[2]^3,
 x[0]^2x[1] + x[0]x[1]^2 - 3x[0]x[1]x[2] - x[1]^2x[2] + 2x[1]x[2]^2,
 x[0]x[1]^3 - 2x[0]^2x[2]^2 - 5x[0]x[1]x[2]^2 - 4x[1]^2x[2]^2 +
8x[0]x[2]^3 + 10x[1]x[2]^3 - 8x[2]^4,
 x[0]x[1]^2x[2] + x[1]^3x[2] - 2x[0]^2x[2]^2 - 5x[0]x[1]x[2]^2
- 5x[1]^2x[2]^2 + 8x[0]x[2]^3 + 10x[1]x[2]^3 - 8x[2]^4,
 x[1]^4x[2] - 2x[1]^3x[2]^2 - 4x[0]^2x[2]^3 - 8x[0]x[1]x[2]^3
- 3x[1]^2x[2]^3 + 16x[0]x[2]^4 + 16x[1]x[2]^4 - 16x[2]^5)
-------------------------------
</example>
</description>


<seealso>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>GBM</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>fat</key>
  <key>point</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>hilbert [OBSOLESCENT]</title>
  <short_description>the Hilbert-Poincare' function</short_description>
<syntax>
[OBSOLESCENT]
</syntax>
<description>
Renamed as <ttref>HilbertFn</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertBasisKer</title>
  <short_description>Hilbert basis for a monoid</short_description>

<syntax>
HilbertBasisKer(M: <type>MAT</type>): <rtn>LIST</rtn>

where M is a matrix over ZZ.
</syntax>
<description>
This function returns a list whose components are lists (of
non-negative integers) representing the Hilbert basis for the monoid
of elements with non-negative coordinates in the kernel of M.

<example>
/**/  M := mat([[1,-2,3,4], [1, 0, 0, -1]]);
/**/  HilbertBasisKer(M);
[[0, 3, 2, 0], [1, 4, 1, 1], [2, 5, 0, 2]]

/**/  M * transposed(mat(It));
matrix([
  [0, 0, 0],
  [0, 0, 0]
])
</example>
</description>


<seealso>
  <see>LinKerBasis</see>
</seealso>

<keys>
  <key>hilbert basis positive kernel</key>
  <key>positive kernel hilbert basis</key>
  <key>positivekerhilbertbasis</key>
  <key>hilbertbasispositiveker</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertFn</title>
  <short_description>the Hilbert function</short_description>
<syntax>
HilbertFn(R: <type>RING</type>|<type>IDEAL</type>): TAGGED("$hp.Hilbert")
HilbertFn(R: <type>RING</type>|<type>IDEAL</type>, N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
The first form of this function computes the Hilbert function for R.
The second form computes the N-th value of the Hilbert function.  The
weights of the indeterminates of R must all be 1.  If the input is not
homogeneous, the Hilbert function of the corresponding leading term
(initial) ideal or module is calculated.  For repeated evaluations of
the Hilbert function, use <ttref>EvalHilbertFn</ttref> instead
of <tt>Hilbert(R, N)</tt> in order to speed up execution.
<par/>
The coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  HilbertFn(R/ideal(z^2-x*y, x*z^2+t^3));
H(0) = 1
H(1) = 4
H(t) = 6*t -3   for t &gt;= 2

/**/  R2 := NewFreeModule(R, 2);
/**/  MGens := matrix(R, [[x^3,y^3], [x*y^2,0], [0,z^3]]);
/**/  M := SubmoduleRows(R2, MGens);
/**/  HilbertFn(M);
H(0) = 0
H(1) = 0
H(2) = 0
H(3) = 3
H(4) = 12
H(t) = (1/3)*t^3 +(3/2)*t^2 +(-101/6)*t +35   for t >= 5

/**/  HilbertFn(M,3);
3
/**/  HilbertFn(M,5);
30
</example>
</description>

<seealso>
  <see>EvalHilbertFn</see>
  <see>HilbertPoly</see>
  <see>HVector</see>
  <see>HilbertSeries</see>
</seealso>

<types>
  <type>groebner</type>
  <type>groebner-basic</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertPoly</title>
  <short_description>the Hilbert polynomial</short_description>
<syntax>
HilbertPoly(R: <type>RING</type> or TAGGED("Quotient")): <rtn>RINGELEM</rtn> in the ring QQt.
</syntax>
<description>
This function returns the Hilbert polynomial for R as a polynomial in
the standard CoCoA ring QQt (= QQ[t]).
<par/>
The weights of the indeterminates of R must all be 1, and the
coefficient ring must be a field.
<par/>
If the input is not homogeneous, the Hilbert polynomial of the
corresponding leading term (initial) ideal or module is calculated.
For the Hilbert *function*, see <ttref>HilbertFn</ttref>.
<example>
/**/  Use R ::= QQ[w,x,y,z];
/**/  I := ideal(z^2-x*y, x*z^2+w^3);
/**/  Hilbert(R/I);
H(0) = 1
H(1) = 4
H(t) = 6*t-3   for t &gt;= 2

/**/  F := HilbertPoly(R/I);
/**/  F;  -- a polynomial in the ring Qt
6*t-3

/**/ T := indet(RingOf(F), 1);
/**/ subst(F, T, 3);
15
</example>
</description>
<seealso>
  <see>EvalHilbertFn</see>
  <see>HilbertFn</see>
  <see>HVector</see>
  <see>HilbertSeries</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertSeries</title>
  <short_description>the Hilbert-Poincare series</short_description>
<syntax>
HilbertSeries(M: <type>MODULE</type>|<type>IDEAL</type>|<type>RING</type>):TAGGED("$hp.PSeries")
</syntax>
<description>
This function computes the Hilbert-Poincare series of M.
The input, M, must be homogeneous (with respect to the first row of
the weights matrix).  In the standard case, i.e. the weights of all
indeterminates are 1, the result is simplified so that the power
appearing in the denominator is the dimension of M.
<par/>
NOTES:
<par/>
(i) the coefficient ring must be a field.
<par/>
(ii) these functions produce tagged objects: they cannot safely be
     (non-)equality to other values.
<par/>
Starting from release 4.7.5 the input may also be an ideal.
<par/>
For more information, see the article: A.M. Bigatti, <quotes>Computations of
Hilbert-Poincare Series</quotes> J. Pure Appl. Algebra, 119/3 (1997),
237--253.

<example>
/**/  Use R ::= QQ[t,x,y,z]; -- standard weights
/**/  HilbertSeries(R/ideal(R,[]));
(1) / (1-t)^4

/**/  HilbertSeries(R/ideal(t^2, x, y^3));
(1 + 2*t + 2*t^2 + t^3) / (1-t)

/**/  R2 := NewFreeModule(R, 2); -- MODULE
/**/  M := SubmoduleRows(R2, matrix(R, [[x^2,0], [0,z^3]]));
/**/  HilbertSeries(M);
(t^2 + t^3) / (1-t)^4

-- /**/  HilbertSeries(R2/M);  --***WORK IN PROGRESS***

/**/  Ws := RowMat([1,2,3,4]); -- weights and multigradings
/**/  P := NewPolyRing(QQ,["t","x","y","z"],CompleteToOrd(Ws),1);
/**/  Use P;
/**/  HilbertSeries(P/ideal(t^2, x, y^3));
---  Non-simplified HilbertPoincare' Series  ---
(1 - 2*t^2 + t^4 - t^9 + 2*t^11 - t^13) / ( (1-t)*(1-t^2)*(1-t^3)*(1-t^4) )

/**/  HilbertSeries(ideal(t^2, x, y^3));
---  Non-simplified HilbertPoincare' Series  ---
(2*t^2 - t^4 + t^9 - 2*t^11 + t^13) / ( (1-t)*(1-t^2)*(1-t^3)*(1-t^4) )

/**/  Ws := mat([[1,2,3,4],[0,0,5,8]]);
/**/  P := NewPolyRing(QQ,["t","x","y","z"],CompleteToOrd(Ws),2);
/**/  Use P;
/**/  HilbertSeries(P/ideal(t^2, x, y^3));
---  Non Simplified Pseries  ---
(1 - 2*t[1]^2 + t[1]^4 - t[1]^9*t[2]^15 + 2*t[1]^11*t[2]^15 - t[1]^13*t[2]^15) / ( (1-t[1])^1*(1-t[1]^2)*(1-t[1]^3*t[2]^5)*(1-t[1]^4*t[2]^8) )

/**/  Ws := mat([[1,2,3,4],[0,0,5,8]]);
/**/  P := NewPolyRing(QQ, ["t","x","y","z"], CompleteToOrd(Ws), 2);
/**/  Use P;
/**/  Poincare(P/ideal(t^2, y^3));
---  Non-simplified HilbertPoincare' Series  ---
(1 - t[1]^2 - t[1]^9*t[2]^15 + t[1]^11*t[2]^15) / 
    ((1-t[1])^1*(1-t[1]^2)*(1-t[1]^3*t[2]^5)*(1-t[1]^4*t[2]^8) )
</example>
</description>
<seealso>
  <see>dim</see>
  <see>multiplicity</see>
  <see>HilbertFn</see>
  <see>HVector</see>
  <see>HilbertSeriesShifts</see>
  <see>HilbertSeriesMultiDeg</see>
  <see>GradingMat</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertSeriesMultiDeg</title>
  <short_description>the Hilbert-Poincare series wrt a multigrading</short_description>
<syntax>
HilbertSeriesMultiDeg(RmodI: <type>RING</type>, WM: <type>MAT</type>): TAGGED("$hp.PSeries")
</syntax>
<description>
This function computes the multigraded Hilbert-Poincare series
of <tt>RmodI</tt> wrt the multigrading <tt>WM</tt>.
The <tt>I</tt> must be homogeneous wrt the multigrading <tt>WM</tt>.
<par/>
This function is only a handy shortcut to avoid creating the proper
polynomial ring multi-graded with <tt>WM</tt>.
<example>
/**/ Use R ::= QQ[x,y];
/**/ HilbertSeriesMultiDeg(R/ideal(Indets(R))^2, mat([[1,1]]));
(1 + 2*t) / (1-t)^0

/**/ HilbertSeriesMultiDeg(R/ideal(Indets(R))^2, mat([[1,0],[0,1]]));
---  Non-simplified HilbertPoincare' Series  ---
(1 - t[2]^2 - t[1]*t[2] - t[1]^2 + t[1]*t[2]^2 + t[1]^2*t[2])
/ ( (1-t[1])*(1-t[2]) )
</example>
</description>
<seealso>
  <see>HilbertSeries</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HilbertSeriesShifts</title>
  <short_description>the Hilbert-Poincare series</short_description>
<syntax>
HilbertSeriesShifts(M: <type>MODULE</type>, ShiftsList: <type>LIST</type>):TAGGED("$hp.PSeries")
HilbertSeriesShifts(M: TAGGED("Quotient"), ShiftsList: <type>LIST</type>)
                                           :TAGGED("$hp.PSeries")
</syntax>
<description>
This function computes the Hilbert-Poincare series
(single-graded) module <tt>M</tt> with shifts <tt>sh</tt>.
<par/>
This function is only a handy shortcut to avoid creating the proper
free module with shifts <tt>sh</tt>.
<par/>
NB functions producing tagged objects cannot safely be compared
for equality with other values.
<par/>
For more information, see the article: A.M. Bigatti, <quotes>Computations of
Hilbert-Poincare Series</quotes> J. Pure Appl. Algebra, 119/3 (1997),
237--253.
<example>
/**/  Use P ::= QQ[x,y,z];
/**/  F := NewFreeModule(P, ColMat([2,0]));  -- P(-2) (+) P(0)
/**/  M := SubmoduleRows(F, mat([[x,y^3], [x-z,0]]));
/**/  HilbertSeries(M);
(2*t^3) / (1-t)^3
/**/  HilbertSeriesShifts(M, [3,1]);
(2*t^4) / (1-t)^3
</example>
</description>
<seealso>
  <see>dim</see>
  <see>HilbertFn</see>
  <see>HVector</see>
  <see>multiplicity</see>
  <see>GradingMat</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>homog</title>
  <short_description>homogenize with respect to an indeterminate</short_description>

<syntax>
homog(V: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
homog(V: <type>MODULEELEM</type>, X: <type>RINGELEM</type>): <rtn>MODULEELEM</rtn>
homog(L: <type>LIST</type>, X: <type>RINGELEM</type>): <rtn>LIST</rtn>
homog(I: <type>IDEAL</type>, X: <type>RINGELEM</type>): <rtn>IDEAL</rtn>
homog(M: <type>MODULE</type>, X: <type>RINGELEM</type>): <rtn>MODULE</rtn>
</syntax>
<description>
This function returns the homogenization of the first arg with respect to the
indeterminate <tt>X</tt>, which must have weight 1.  The elements of the list <tt>L</tt>
are homogenized separately.  For an ideal/module the result is the ideal/module
containing the homogenizations of all elements (and not simply the
homogenizations of the specific generators).
<example>
/**/  Use R ::= QQ[x,y,z,w];
/**/  homog(x^3-y, w);
x^3 -y*w^2

/**/  homog([x^3-y, x^4-z], w);
[x^3 -y*w^2, x^4 -z*w^3]

/**/  I := ideal(x^3-y, x^4-z);
/**/  homog(I, w);    -- don&apos;t just get the homogenizations of 
                      -- the generators of I
ideal(x*y -z*w, x^2*z -y^2*w, x^3 -y*w^2, y^3 -x*z^2)
</example>
</description>

<seealso>
  <see>IsHomog</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HomogElimMat</title>
  <short_description>matrix for elimination ordering</short_description>

<syntax>
HomogElimMat(W: <type>MAT</type>, ElimInd: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns a matrix for a term ordering eliminating the
indeterminates with indices in <tt>ElimInd</tt> for homogeneous input
wrt the weights in the matrix <tt>W</tt>.
If you don't understand what this means use <ttref>ElimMat</ttref>
instead ;-)

<example>
/**/  HomogElimMat(mat([[1,5,0]]), [2,3]);
matrix(QQ,
 [[1, 5, 0],
  [0, 1, 1],
  [0, 0, -1]])
</example>
</description>


<seealso>
  <see>elim</see>
  <see>ElimMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HSaturation</title>
  <short_description>saturation of ideals</short_description>

<syntax>
HSaturation(I: <type>IDEAL</type>, J: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This functions returns the saturation of I with respect to J: the
ideal of polynomials F such that F*G is in I for all G in <formula>J^d</formula>
for some positive integer <formula>d</formula>.
<par/>
It calculates the saturation using a Hilbert-driven algorithm.
It differs from <ttref>saturate</ttref> only when the
input is inhomogeneous, in which case, <tt>HSaturation</tt> may be faster.
<par/>
The coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x^4-x, y*x-2*x);
/**/  saturate(I, ideal(x));
ideal(y -2, x^3 -1)

  HSaturation(I, ideal(x)); -- ***** NOT YET IMPLEMENTED *****
</example>
</description>


<seealso>
  <see>colon</see>
  <see>HColon</see>
  <see>saturate</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>HVector</title>
  <short_description>the h-vector of a module or quotient object</short_description>
<syntax>
HVector(R: <type>RING</type> or TAGGED("Quotient")): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the h-vector of M, i.e., the
coefficients of the numerator of the simplified Poincare series for M.
M can be a module or a quotient.
<par/>
The weights of the indeterminates of the polynomial ring of M must all be 1,
and the coefficient ring must be a field.
<par/>
If the input is not homogeneous, the Hilbert function of the
corresponding leading term (initial) ideal or module is calculated.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  HVector(R/ideal(x,y,z)^5);
[1, 3, 6, 10, 15]

/**/  HilbertSeries(R/ideal(x,y,z)^5);
(1 + 3t + 6t^2 + 10t^3 + 15t^4) / (1-t)
</example>
</description>
<seealso>
  <see>HilbertFn</see>
  <see>HilbertSeries</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>hnumerator</key>
  <key>hilbert numerator</key>
  <key>hilbert poincare numerator</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>I</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ID</title>
  <short_description>identification for ring</short_description>
<syntax>
ID(R: <type>RING</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the identification number of the ring <tt>R</tt>.
Two rings are considered equal if and only if they have the same ID:
this means they have the same internal implementation.
<example>
/**/ R ::= QQ[x,y,z];
/**/ R;
RingID(7,"QQ[x,y,z]")
/**/ S ::= QQ[x,y,z];
/**/ R = S;
false
/**/ ID(R);
7
/**/ ID(S);
8
-- /**/ RingElem(R,"x") = RingElem(S, "x"); --> !!! ERROR !!! mixed rings

/**/ S := R; -- or S := RingOf( some element in R )
/**/ R = S;
true
</example>
</description>
<seealso>
  <see>print</see>
  <see>println</see>
  <see>Evaluation and Assignment</see>
</seealso>
<keys>
  <key>system variable</key>
  <key>The variable It</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ideal</title>
  <short_description>ideal generated by list</short_description>

<syntax>
ideal(P_1: <type>RINGELEM</type>,...,P_n: <type>RINGELEM</type>): <rtn>IDEAL</rtn>
ideal(L: <type>LIST</type>): <rtn>IDEAL</rtn>
ideal(R: <type>RING</type>, L: <type>LIST</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
The first form returns the ideal generated by <tt>P_1,...P_n</tt>.
The second form returns the ideal generated by the polynomials in <tt>L</tt>.
The third is the same as the second but works also if <tt>L = []</tt>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x-y^2, x*y-z);
/**/  I;
ideal(-y^2 +x, x*y -z)

/**/  L := [x*y-z, x-y^2];
/**/  J := ideal(L);  -- same as ideal(R, L)
/**/  I = J;
true

/**/  ideal(R, []);
ideal()
</example>
</description>

<types>
  <type>cast</type>
</types>
<keys>
  <key>cast</key>
  <key>convertto</key>
  <key>generated</key>
  <key>generators</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IdealAndSeparatorsOfPoints</title>
  <short_description>ideal and separators for affine points</short_description>

<syntax>
IdealAndSeparatorsOfPoints(Points: <type>LIST</type>): <rtn>RECORD</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in affine space.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes the results of <ttref>IdealOfPoints</ttref> and
<ttref>SeparatorsOfPoints</ttref> together at a cost lower than making the two
separate calls.  The result is a record with three fields:
<verbatim>
    points     -- the points given as argument
    ideal      -- the result of IdealOfPoints
    separators -- the result of SeparatorsOfPoints
</verbatim>
Thus, if the result is stored in a variable with identifier X, then:
X.points will be the input list of points;
X.ideal will be the ideal of the set of points, with generators
forming the reduced Groebner basis for the ideal;
X.separators will be a list of polynomials whose i-th element will
take the value 1 on the i-th point and 0 on the others.
<par/>
NOTE:
<par/>
 * the current ring must have at least as many indeterminates as the
   dimension of the space in which the points lie;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned, the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:
<verbatim>
     X := IdealAndSeparatorsOfPoints(Pts);
     Foreach Element In gens(X.ideal) Do
       PrintLn Element;
     EndForeach;
</verbatim>

For ideals and separators of points in projective space, see
<ttref>IdealAndSeparatorsOfProjectivePoints</ttref>.

<example>
  Use R ::= QQ[x,y];
  Points := [[1, 2], [3, 4], [5, 6]];
  X := IdealAndSeparatorsOfPoints(Points);
  X.points;
[[1, 2], [3, 4], [5, 6]]
-------------------------------
  X.ideal;
ideal(x - y + 1, y^3 - 12y^2 + 44y - 48)
-------------------------------
  X.separators;
[1/8y^2 - 5/4y + 3, -1/4y^2 + 2y - 3, 1/8y^2 - 3/4y + 1]
-------------------------------
</example>
</description>


<seealso>
  <see>GBM</see>
  <see>HGBM</see>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>Interpolate</see>
  <see>QuotientBasis</see>
  <see>SeparatorsOfPoints</see>
  <see>SeparatorsOfProjectivePoints</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>zero</key>
  <key>buchbergermoeller</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IdealAndSeparatorsOfProjectivePoints</title>
  <short_description>ideal and separators for points</short_description>

<syntax>
IdealAndSeparatorsOfProjectivePoints(Points: <type>LIST</type>): <rtn>RECORD</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in projective space.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes the results of <ttref>IdealOfProjectivePoints</ttref> and
<ttref>SeparatorsOfProjectivePoints</ttref> together at a cost lower than making
the two separate calls.  The result is a record with three fields:
<verbatim>
    points     -- the points given as argument
    ideal      -- the result of IdealOfProjectivePoints
    separators -- the result of SeparatorsOfProjectivePoints
</verbatim>
Thus, if the result is stored in a variable with identifier X, then:
X.ideal will be the ideal of the set of points, with generators
forming a reduced Groebner basis for the ideal;
X.separators will be a list of homogeneous polynomials whose i-th
element will be non-zero (actually 1, using the given representatives
for the coordinates of the points) on the i-th point and 0 on the others.
<par/>
NOTE:
<par/>
 * the current ring must have at least one more indeterminate than the
   dimension of the projective space in which the points lie, i.e, at
   least as many indeterminates as the length of an element of
   the input, Points;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned, the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:
<verbatim>
     X := IdealAndSeparatorsOfProjectivePoints(Pts);
     Foreach Element In gens(X.ideal) Do
       PrintLn Element;
     EndForeach;
</verbatim>

For ideals and separators of points in affine space, see
<ttref>IdealAndSeparatorsOfPoints</ttref>.

<example>
  Use R ::= QQ[x,y,z];
  Points := [[0,0,1],[1/2,1,1],[0,1,0]];
  X := IdealAndSeparatorsOfProjectivePoints(Points);
  X.points;
[[0, 0, 1], [1, 1, 1], [0, 1, 0]]
-------------------------------
  X.ideal;
ideal(xz - 1/2yz, xy - 1/2yz, x^2 - 1/4yz, y^2z - yz^2)
-------------------------------
  X.separators;
[-2x + z, x, -2x + y]
-------------------------------

  Use R ::= QQ[t,x,y,z];
  Pts := GenericPoints(20);  -- 20 random points in projective 3-space
  X := IdealAndSeparatorsOfProjectivePoints(Pts);
  Len(Gens(X.Ideal));  -- number of generators in the ideal
17
-------------------------------
  HilbertFn(R/X.Ideal);
H(0) = 1
H(1) = 4
H(2) = 10
H(t) = 20   for t >= 3
-------------------------------
  F := X.Separators[3];
  [Eval(F, P)| P In Pts];
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-------------------------------
  Res(R/X.Ideal);  -- the resolution of the ideal
0 --> R^10(-6) --> R^24(-5) --> R^15(-4) --> R
-------------------------------
</example>
</description>


<seealso>
  <see>HGBM</see>
  <see>GBM</see>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>Interpolate</see>
  <see>QuotientBasis</see>
  <see>SeparatorsOfPoints</see>
  <see>SeparatorsOfProjectivePoints</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>buchbergermoeller</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IdealOfPoints</title>
  <short_description>ideal of a set of affine points</short_description>

<syntax>
IdealOfPoints(P: <type>RING</type>, Points: <type>MAT</type>): <rtn>IDEAL</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in affine space.
</syntax>
<description>
<par/>
This function computes the reduced Groebner basis for the ideal of all
polynomials which vanish at the given set of points.  It returns the
ideal generated by that Groebner basis.
<par/>
NOTE:
<par/>
 * the current ring must have at least as many indeterminates as the
   dimension of the space in which the points lie;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned, the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<!-- <par/> -->
<!--  * if the number of points is large, say 100 or more, the returned -->
<!--    value can be very large.  To avoid possible problems when printing -->
<!--    such values as a single item we recommend printing out the elements -->
<!--    one at a time as in this example: -->
<!-- <verbatim> -->
<!--      I := IdealOfPoints(P, Pts); -->
<!--      Foreach Element In gens(I) Do -->
<!--        PrintLn Element; -->
<!--      EndForeach; -->
<!-- </verbatim> -->
For ideals of points in projective space, see
<ttref>IdealOfProjectivePoints</ttref>.

<example>
/**/  Use P ::= QQ[x,y];
/**/  Points := mat([[1, 2], [3, 4], [5, 6]]);
/**/  I := IdealOfPoints(P, Points);
/**/  I;
ideal(x -y +1, y^3 -12*y^2 +44*y -48)

/**/  K := NewFractionField(NewPolyRing(QQ, ["a"]));
/**/  Use K;
/**/  Points := mat([[1,2,0], [3,4,a], [5,1,6]]);
/**/  Use P ::= K[x,y,z], Lex;
/**/  I := IdealOfPoints(P, Points);
/**/  indent(I);
ideal(
  z^3 +(-a -6)*z^2 +(6*a)*z,
  y +((-a -12)/(6*a^2 -36*a))*z^2 +((a^2 +72)/(6*a^2 -36*a))*z -2,
  x +((2*a -6)/(3*a^2 -18*a))*z^2 +((-2*a^2 +36)/(3*a^2 -18*a))*z -1
)
</example>
</description>

<seealso>
  <see>GBM</see>
  <see>HGBM</see>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>Interpolate</see>
  <see>QuotientBasis</see>
  <see>SeparatorsOfPoints</see>
  <see>SeparatorsOfProjectivePoints</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>buchbergermoeller</key>
  <key>buchberger-moeller</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IdealOfProjectivePoints</title>
  <short_description>ideal of a set of projective points</short_description>

<syntax>
IdealOfProjectivePoints(Points: <type>LIST</type>): <rtn>IDEAL</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in projective space.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes the reduced Groebner basis for the ideal of
all homogeneous polynomials which vanish at the given set of points.
It returns the ideal generated by that Groebner basis.
<par/>
NOTE:
<par/>
 * the current ring must have at least one more indeterminate than the
   dimension of the projective space in which the points lie, i.e, at
   least as many indeterminates as the length of an element of
   the input, Points;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned, the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:
<verbatim>
     I := IdealOfProjectivePoints(Pts);
     Foreach Element In gens(I) Do
       PrintLn Element;
     EndForeach;
</verbatim>
For ideals of points in affine space, see <ttref>IdealOfPoints</ttref>.

<example>
  Use R ::= QQ[x,y,z];
  I := IdealOfProjectivePoints([[0,0,1],[1/2,1,1],[0,1,0]]);
  I;
ideal(xz - 1/2yz, xy - 1/2yz, x^2 - 1/4yz, y^2z - yz^2)
-------------------------------
  I.Gens;  -- the reduced Groebner basis
[xz - 1/2yz, xy - 1/2yz, x^2 - 1/4yz, y^2z - yz^2]
-------------------------------
</example>
</description>


<seealso>
  <see>GBM</see>
  <see>HGBM</see>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>Interpolate</see>
  <see>QuotientBasis</see>
  <see>SeparatorsOfPoints</see>
  <see>SeparatorsOfProjectivePoints</see>
</seealso>

<types>
  <type>groebner</type>
  <type>points</type>
</types>

<keys>
  <key>buchbergermoeller</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IdentityMat</title>
  <short_description>the identity matrix</short_description>

<syntax>
IdentityMat(R: <type>RING</type>, N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the NxN identity matrix.

<example>
 /**/ IdentityMat(QQ,3);
matrix([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
</example>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>if</title>
  <short_description>conditional statement</short_description>
  

<syntax>
If B_1 Then C_1 EndIf
If B_1 Then C_1 Else D EndIf
If B_1 Then C_1 Elif B_2 Then C_2 Elif ... EndIf
If B_1 Then C_1 Elif B_2 Then C_2 Elif ... Else D EndIf

where the B_j are boolean expressions,
and the C_j and D are command sequences.
</syntax>
<description>
If <tt>B_n</tt> is the first in the sequence of the <tt>B_j</tt> to evaluate to True,
then <tt>C_n</tt> is executed.
If none of the <tt>B_j</tt> evaluates to True, then <tt>D</tt> is executed if present otherwise
nothing is done.
The construct, <tt>Elif B_j Then C_j</tt> can be repeated any number of times.
<par/>
NB: <tt>Elsif</tt> is no longer allowed.

<example>
/**/  Define MySign(A)
/**/    If A &gt; 0 Then Return 1;
/**/    Elif A = 0 Then Return 0;
/**/    Else Return -1;
/**/    EndIf;
/**/  EndDefine;

/**/  MySign(3);
1
</example>
</description>

<keys>
  <key>else</key>
</keys>

<seealso>
</seealso>

<types>
  <type>command</type>
  <type>programming</type>
  <type>branching</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ILogBase</title>
  <short_description>integer part of the logarithm</short_description>

<syntax>
ILogBase(X: <type>RAT</type>, Base: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the integer part (floor) of the logarithm of a
rational number in a given base.  The signs of X and Base are ignored.

<example>
/**/  ILogBase(128,2);
7

/**/  ILogBase(81.5,3);
4
</example>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>image [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] apply ring homomorphism</short_description>
<syntax>
Image(V: <type>OBJECT</type>, F:TAGGED("RMap")): <rtn>OBJECT</rtn>
</syntax>
<description>
In CoCoA-5 homomorphisms are properly implemented as <ttref>RINGHOM</ttref>.
<tt>Image</tt> was the CoCoA-4 function mimicking homomorphisms, in
particular <ttref>PolyAlgebraHom</ttref>.
<example>
/**/  Use D ::= QQ[x,y];   -- domain
/**/  f := x-y;   -- a RINGELEM in D

/**/  Use C ::= QQ[a,b,c]; -- codomain

/**/  -- the old trick
/**/  Phi := RMap(a, c^2-a*b);  -- OBSOLESCENT
/**/  Image(f, Phi);            -- OBSOLESCENT
a*b -c^2 +a

/**/  -- the proper call
/**/  phi := PolyAlgebraHom(D, C, [a, c^2-a*b]);  -- a RINGHOM
/**/  phi(f);
a*b -c^2 +a
</example>
</description>
<seealso>
  <see>PolyAlgebraHom</see>
  <see>apply</see>
  <see>BringIn</see>
  <see>subst</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>implicit</title>
  <short_description>implicitization</short_description>
<syntax>
implicit(SubalgebraGens: <type>LIST</type>): <rtn>IDEAL</rtn>
implicit(R: <type>RING</type>, SubalgebraGens: <type>LIST</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the implicitization of the subalgebra generated
by the list <tt>SubalgebraGens</tt>.
<par/>
If provided with a ring <tt>R</tt>, the result is in <tt>R</tt>,
otherwise it is in a newly created ring.
<example>
/**/ Use S ::= QQ[s,t];
/**/ implicit([s^3, s^2*t, s*t^2, t^3]);
ideal(x[3]^2 -x[2]*x[4], x[2]*x[3] -x[1]*x[4], x[2]^2 -x[1]*x[3])

/**/ R ::= QQ[x,y,z,w];
/**/ implicit(R, [s^3, s^2*t, s*t^2, t^3]);
ideal(z^2 -y*w, y*z -x*w, y^2 -x*z)
</example>
</description>
<seealso>
  <see>ker</see>
</seealso>
<keys>
  <key>subalgebra</key>
  <key>homomorphism</key>
  <key>kernel</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ImplicitPlot</title>
  <short_description>outputs the zero locus of a bivariate polynomial to a file</short_description>

<syntax>
ImplicitPlot(F: <type>POLY</type>, Xrange: <type>LIST</type>, Yrange: <type>LIST</type>)
</syntax>
<description>
This function evaluates the first argument, a bivariate polynomial, at
a grid of points in the range given by the second and third arguments.
The coordinates of the approximate zeroes are output to a file
called <quotes>CoCoAPlot</quotes>.
See <ttref>ImplicitPlotOn</ttref> for outputting to another file.
<par/>
This result can be plotted using your preferred plotting program.
For example, start <quotes>gnuplot</quotes> and then give it the command
<verbatim>  plot <quotes>CoCoAPlot</quotes></verbatim>
to see the plot.

<example>
/**/  Use R ::= QQ[x,y];
/**/  ImplicitPlot(x^2 + y^2 - 200^2, [-256,256], [-256,256]);
Plotting points...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
800 plotted points have been placed in the file CoCoAPlot
</example>

</description>



<seealso>
  <see>ImplicitPlotOn</see>
  <see>PlotPoints</see>
</seealso>

<keys>
  <key>gnuplot</key>
  <key>plot curve</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ImplicitPlotOn</title>
  <short_description>outputs the zero locus of a bivariate polynomial to a file</short_description>

<syntax>
ImplicitPlotOn(F: <type>POLY</type>, Xrange: <type>LIST</type>, Yrange: <type>LIST</type>, PlotFileName: <type>STRING</type>)
</syntax>
<description>
This function is the same as <ttref>ImplicitPlot</ttref> with a fourth
argument giving the name of the file to print on.
<par/>
Note that the last argument is a STRING, the name of the file, and not
a DEVICE, as for <ttref>print on</ttref>.

<example>
/**/  Use R::= QQ[x,y];
/**/  F := x^2 + y^2 - 100;
/**/  G := ((x+y)^2-1)*(x^2-36);
/**/  H := ((64*y^2-36*x^2)*(36*y^2-64*x^2)*(100*x^2-y^2)-1) * F - 1000^2 * G;

/**/  ImplicitPlotOn(F, [-16,16], [-16,16], "PLOT-circle");
Plotting points...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
640 plotted points have been placed in the file circle

/**/  ImplicitPlotOn(G, [-16,16], [-16,16], "PLOT-lines");
Plotting points...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
1502 plotted points have been placed in the file lines

/**/  ImplicitPlotOn(H, [-16,16], [-16,16], "PLOT-curve");
Plotting points...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
2790 plotted points have been placed in the file curve
</example>
After having produced the plot files using CoCoA-4,
start <quotes>gnuplot</quotes> and then give it the following commands:
<verbatim>  plot <quotes>circle</quotes>
  replot <quotes>lines</quotes>
  replot <quotes>curve</quotes>
</verbatim>
</description>



<seealso>
  <see>ImplicitPlot</see>
  <see>PlotPointsOn</see>
</seealso>

<keys>
  <key>gnuplot</key>
  <key>plot curve</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ImportByRef, ImportByValue</title>
  <short_description>import an external variable by reference or value</short_description>
<syntax>
ImportByRef X;
ImportByValue X;
  where <tt>X</tt> is the name of a variable in the containing scope.
</syntax>
<description>
<em>***YOU PROBABLY SHOULDN'T USE THESE COMMANDS YET!***</em>
It seems that they can be used only inside anonymous functions (see <ttref>func</ttref>).
<par/>
These commands "import" an external variable by reference or value.
<tt>ImportByValue</tt> creates a local variable with the given name, and its
initial value is taken from the variable of the same name in the context the
anonymous function is defined.  <tt>ImportByRef</tt> creates a reference to
the named variable in the context where the anonymous function is defined.
<example>
/**/  Define add(X)
/**/    AnonFn := Func(Y) ImportByValue X; Return X+Y; EndFunc;
/**/    Return AnonFn;
/**/  EndDefine;
/**/  add3 := add(3);
/**/  add3(2);
5
</example>
</description>
<seealso>
  <see>TopLevel</see>
  <see>func</see>
</seealso>
<keys>
  <key>closure</key>
  <key>variable capture</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>in</title>
  <short_description>list element selector in list constructor</short_description>
<syntax>
[X in L | B: <type>BOOL</type>]
[E | X in L]
[E | X in L and B]
  where L: <type>LIST</type>, B: <type>BOOL</type>, E: expression
  returns <rtn>LIST</rtn>
</syntax>
<description>
See <ref>List Constructors</ref> for a full description.
<example>
/**/  [N in 1..10 | IsPrime(N)];
[2, 3, 5, 7]

/**/  [N^2 | N in 1..10 and IsPrime(N)];
[4, 9, 25, 49]
</example>
</description>
<seealso>
  <see>List Constructors</see>
  <see>IsIn</see>
</seealso>
</command>
<!--===  COMMAND  =============================================== -->
<command>
  <title>incr, decr</title>
  <short_description>increment/decrement a counter</short_description>

<syntax>
incr(ref X: <type>INT</type>)
decr(ref X: <type>INT</type>)
</syntax>
<description>
<tt>incr(ref X)</tt> adds 1 to the value of <tt>X</tt>.
<tt>decr(ref X)</tt> subtracts 1 from the value of <tt>X</tt>.
<par/>
These functions are useful when counting objects or adjusting pointers.
<example>
/**/ L := [(10^k-1)/9 | k in 1..99];
/**/ NPrimes := 0;
/**/ Foreach N in L Do
/**/   If IsPrime(N) Then incr(ref NPrimes); EndIf;
/**/ EndForeach;
/**/ PrintLn "The list L contains ", NPrimes, " primes.";
The list L contains 3 primes.
</example>
</description>
<types>
   <type>INT</type>
</types>

<keys>
  <key>increment</key>
  <key>decrement</key>
  <key>counter</key>
  <key>++</key>
</keys>

</command>
<!--===  COMMAND  =============================================== -->
<command>
  <title>indent</title>
  <short_description>prints in a more readable way</short_description>

<syntax>
indent(X: <type>OBJECT</type>)
indent(X: <type>OBJECT</type>, N: <type>INT</type>)
</syntax>
<description>
This function prints the argument <tt>X</tt> splitting it into several
lines: a <tt>LIST</tt> or <tt>IDEAL</tt> is printed one element per line,
a <tt>RECORD</tt> one field per line.
<par/>
The second optional argument is for setting the level of recursive
indentation; it is useful for example when printing a list of records.

<example>
/**/ L := [1,2] &gt;&lt; [3,4];
/**/ L;
[[1, 3], [1, 4], [2, 3], [2, 4]]

/**/ indent(L);
[
  [1, 3],
  [1, 4],
  [2, 3],
  [2, 4]
]

/**/ indent(L,2);
[
  [
    1,
    3
  ],
    --( Further output )--
  [
    2,
    4
  ]
]

/**/ indent(record[B:=1,A:=2]);
record[
  A := 2,
  B := 1
]
</example>
</description>

<seealso>
  <see>format</see>
</seealso>
<keys>
  <key>indentation</key>
  <key>print</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>indet</title>
  <short_description>individual indeterminates</short_description>

<syntax>
indet(R: <type>RING</type>, N: <type>INT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the N-th indeterminate of the current ring.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  indet(R, 2);
y
</example>
</description>


<seealso>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>indets</see>
  <see>NumIndets</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IndetIndex</title>
  <short_description>index of an indeterminate</short_description>

<syntax>
IndetIndex(X: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the position in which the indeterminate is
listed when the corresponding ring was created.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  IndetIndex(y);
2

/**/  Use R ::= QQ[x[1..2,1..2],y[1..2]];
/**/  Indets(R);
[x[1,1], x[1,2], x[2,1], x[2,2], y[1], y[2]]

/**/  IndetIndex(x[2,1]);
3

/**/  S ::= QQ[a,b,c];
/**/  IndetIndex(RingElem(S, "b"));
2
</example>
</description>


<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetName</see>
  <see>indets</see>
  <see>NumIndets</see>
  <see>UnivariateIndetIndex</see>
</seealso>
<keys>
  <key>position</key>
  <key>variable</key>
  <key>indexed</key>
  <key>indices</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IndetName</title>
  <short_description>the name of an indeterminate</short_description>

<syntax>
IndetName(X: <type>RINGELEM</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns the name of the indeterminate X as a string
(i.e. the letter without the indices).

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  IndetName(indet(R, 2));
y

/**/  type(It);
STRING

/**/  Use R ::= QQ[a, x[1..3]];
/**/  IndetName(Indet(R, 2));
x

/**/  indent(IndetSymbols(R));
[
  record[head := "a", indices := []],
  record[head := "x", indices := [1]],
  record[head := "x", indices := [2]],
  record[head := "x", indices := [3]]
]
</example>
</description>


<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetSymbols</see>
  <see>NumIndets</see>
</seealso>
<keys>
  <key>variable</key>
  <key>indexed</key>
  <key>indices</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>indets</title>
  <short_description>list of indetermiantes in a PolyRing</short_description>

<syntax>
indets(R: <type>RING</type>): <rtn>LIST</rtn>
indets(R: <type>RING</type>, X: <type>STRING</type>): <rtn>LIST</rtn>
</syntax>
<description>
With one argument (a polynomial ring), this function returns the
list of indeterminates of that polynomial ring.
With two arguments (the second a STRING), it returns the
list of all indeterminates whose name is the given string.
The indeterminates in the list appear in order of increasing
index (see the function <tt>IndetIndex</tt>).
<par/>
This function used to be called <tt>IndetsCalled</tt> up to version 5.0.3,
and <tt>AllIndetsCalled</tt> in CoCoA-4.
<par/>
Additionally, up to version 4.7.3 you could get this list just by giving
the name, <i>e.g.</i> <tt>Use QQ[x[0..4]];  x;</tt> but this syntax is no longer
allowed because it is ambiguous: 
<tt>x[2];</tt> is different from <tt>X := x;  X[2];</tt>

<example>
/**/  S ::= QQ[x,y,z];
/**/  Use R ::= QQ[a,b];
/**/  indets(CurrentRing);
[a, b]
/**/  indets(S);
[x, y, z]
/**/  indets(S,"x");
[x]
/**/  RingElem(S,"x"); -- work also if R is not a polynomial ring
x

/**/  Use R ::= QQ[x[1..4],a[1..2,1..3]];
/**/  indets(R,"x");
[x[1], x[2], x[3], x[4]]
/**/  indets(R,"a");
[a[1,1], a[1,2], a[1,3], a[2,1], a[2,2], a[2,3]]
/**/  indets(R,"b");
[]
</example>
</description>


<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>NumIndets</see>
</seealso>
<keys>
  <key>allindetscalled</key>
  <key>variables</key>
  <key>indexed</key>
  <key>indices</key>
  <key>indeterminates</key>
  <key>indeterminate named</key>
  <key>indeterminate names</key>
  <key>indet range</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IndetSubscripts</title>
  <short_description>the index of an indeterminate</short_description>

<syntax>
IndetSubscripts(X: <type>RINGELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the subscripts of the name of the argument,
an indeterminate (used to be called <tt>IndetInd</tt>).
<par/>
Please note the difference with <ttref>IndetIndex</ttref>.

<example>
/**/  Use R ::= QQ[x[1..3,1..2],y,z];
/**/  IndetSubscripts(x[3,2]);
[3, 2]
/**/  IndetSubscripts(y);
[]
/**/  IndetIndex(RingElem(R, ["x",3,2]));
6
/**/  IndetSubscripts(RingElem(R, ["x",3,2]));
[3, 2]
</example>
</description>


<seealso>
  <see>indet</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>IndetSymbols</see>
  <see>indets</see>
  <see>NumIndets</see>
</seealso>
<keys>
  <key>variable</key>
  <key>indexed</key>
  <key>indices</key>
  <key>indetind</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IndetSymbols</title>
  <short_description>the names of the indeterminates in a PolyRing</short_description>
<syntax>
IndetSymbols(P: <type>RING</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns the list of the symbols in a polynomial ring.
A symbol is a record <tt>with</tt> head (as <ttref>IndetName</ttref>)
and <tt>indices</tt> (as <ttref>IndetSubscripts</ttref>)
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  indent(IndetSymbols(R));
[
  record[head := "x", indices := []],
  record[head := "y", indices := []],
  record[head := "z", indices := []]
]

/**/  Use R ::= QQ[a, x[1..3]];
/**/  indent(IndetSymbols(R));
[
  record[head := "a", indices := []],
  record[head := "x", indices := [1]],
  record[head := "x", indices := [2]],
  record[head := "x", indices := [3]]
]
</example>
</description>
<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>NumIndets</see>
  <see>SymbolRange</see>
</seealso>
<keys>
  <key>variable</key>
  <key>indexed</key>
  <key>indices</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>InducedHom</title>
  <short_description>homomorphism induced by a homomorphism</short_description>

<syntax>
InducedHom(RmodI: <type>RING</type>, phi: <type>RINGHOM</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
InducedHom(R, phi) -- where R is a QuotientRing, gives the
homomorphism R/I into S induced by phi: R into S (which must have
the base ring of RmodI as its domain, and whose kernel must
contain the defining ideal of RmodI)

InducedHom(FrF, phi) -- may be partial where FrF is a
FractionField, gives the homomorphism induced by phi (which must
have the base ring of FrF as its domain). Note that the resulting
homomorphism may be only partial (e.g. if ker(phi) is non-trivial,
or if the codomain is not a field). 

<example>
/**/ Use R ::= QQ[x,y];
/**/ RmodI := NewQuotientRing(R, ideal(x^2-1));

/**/ Use S ::= QQ[a,b,c];
/**/ SmodJ := NewQuotientRing(S, ideal(a^2-1));

/**/ phi := PolyAlgebraHom(R,S,[a,b]);
/**/ Use R;
/**/ phi(x);
a
/**/ psi := InducedHom(RmodI, CanonicalHom(S,SmodJ)(phi));
/**/ Use RmodI;
/**/ psi(x);
(a)
</example>
</description>


<seealso>
  <see>NewQuotientRing</see>
  <see>CanonicalHom</see>
  <see>PolyAlgebraHom</see>
  <see>PolyRingHom</see>
</seealso>
<keys>
  <key>quotienting homomorphism</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>InitialIdeal</title>
  <short_description>Initial ideal</short_description>

<syntax>
InitialIdeal(I: <type>IDEAL</type>, Inds: <type>LIST</type>): <rtn>IDEAL</rtn>
</syntax>
<description>

The <em>initial form</em> of a polynomial F is the homogeneous
component of F of the lowest degree (in contrast with the <em>leading
form</em>, see <ttref>LF</ttref>, <ttref>DF</ttref>).
The <em>initial ideal</em> of the ideal <tt>I</tt> is the ideal
generated by the initial forms of all polynomials in <tt>I</tt>.
It is also called <em>tangent cone</em> (which strictly is the variety
defined by the initial ideal).
<par/>
The implementation is based on Lazard's method (see Kreuzer-Robbiano,
Commutative Computer Algebra II, pg.463).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  InitialIdeal(ideal(x^3-y), [x,y,z]);
ideal(-y)
/**/  TgCone(ideal(x^3+x^2-y^2));
ideal(x^2 -y^2)

/**/  I := ideal(x^3-y*z, y^2-x*z, z^2-x^2*y);
/**/  TgCone(I); -- same as InitialIdeal(I, [x,y,z]);
ideal(y^2 -x*z, z^2, -y*z)
</example>
</description>
<keys>
  <key>tangentcone</key>
  <key>tangent cone</key>
</keys>
<seealso>
  <see>InitialIdeal</see>
  <see>PrimaryPoincare</see>
</seealso>

</command>
<!--===  COMMAND  =============================================== -->
<!-- <command> -->
<!--   <title>InputForm</title> -->
<!--   <short_description>prints a version suitable for input</short_description> -->

<!--     <description> -->
<!-- This function returns the argument in a form which is suitable as -->
<!-- input.  ** not yet implemented ** -->

<!-- <example> -->
<!--   A := "hello world"; -->
<!--   Print A; -->
<!-- hello world -->
<!--   Print InputForm(A); -->
<!-- "hello world"; -->
<!-- </example> -->
<!-- </description> -->

<!-- <syntax> -->
<!-- InputForm(???):??? -->
<!-- </syntax> -->

<!-- <seealso> -->
<!--  <see>indent</see> -->
<!-- </seealso> -->

<!-- <types> -->
<!-- </types> -->

<!-- <keys> -->
<!--   <key>print</key> -->
<!--   <key>InputForm</key> -->
<!--   <key>string</key> -->
<!-- </keys> -->

<!--   </command> -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>insert [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] insert an object in a list</short_description>
<syntax>
[OBSOLESCENT] insert(ref L: <type>LIST</type>, N: <type>INT</type>, E: <type>OBJECT</type>)
</syntax>
<description>
This function inserts <tt>E </tt>into <tt>L</tt> as the <tt>N</tt>-th component.
Kept just for backward compatibility, it is strongly discouraged for its
intrinsic inefficiency.  See <ttref>append</ttref>.
<example>
/**/  L := ["a","b","d","e"];
/**/  insert(ref L,3,"c");
/**/  L;
["a", "b", "c", "d", "e"]
</example>
</description>
<seealso>
  <see>append</see>
  <see>remove</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Interpolate</title>
  <short_description>interpolating polynomial</short_description>

<syntax>
Interpolate(Points: <type>LIST</type>, Values: <type>LIST</type>): <rtn>RINGELEM</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points and Values is a list of the same size containing
numbers from the coefficient ring.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function returns a multivariate polynomial which takes given
values at a given set of points.
<par/>
NOTE:
<par/>
 * the current ring must have at least as many indeterminates as the
   dimension of the space in which the points lie;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned, the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:

<example>
  X := Interpolate(Pts, Vals);
  Foreach Element In X Do
    PrintLn Element;
  EndForeach;

  Use QQ[x,y];
  Points := [[1/2, 2], [3/4, 4], [5, 6/11], [-1/2, -2]];
  Values := [1/2,1/3,1/5,-1/2];
  F := Interpolate(Points, Values);
  F;
-46849/834000y^2 - 1547/52125x + 13418/52125y + 46849/208500
-------------------------------
  [Eval(F, P) | P In Points] = Values;  -- check
True
-------------------------------
</example>
</description>


<types>
  <type>points</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>interreduce, interreduced</title>
  <short_description>interreduce a list of polynomials</short_description>

<syntax>
interreduce(ref L: <type>LIST</type> of <type>RINGELEM</type>)
interreduced(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
These functions reduce each polynomial using the other polynomials as
reduction rules.
The process terminates when each is in normal form with respect to the
others.  The function <tt>interreduce</tt> takes a variable containing a list
and overwrites that variable with the interreduced list.  The second
returns an interreduced list without affecting its arguments.

<example>
/**/  interreduced([x^3-x*y^2+y*z, x*y, z]);
[x*y, z, x^3]

/**/  L := [x^3-x*y^2+y*z, x*y, z];
/**/  interreduce(ref L);
/**/  L;
[x*y, z, x^3]
</example>
<!-- /**/  Unset FullRed;  // FullRed = False -->
<!-- /**/  Use R ::= QQ[x,y,z]; -->
<!-- /**/  interreduced([x^3-x*y^2+y*z, x*y, z]); -->
<!-- [x^3 - x*y^2 + y*z, x*y, z] -->

<!-- /**/  Set FullRed;  // FullRed = True (the default value) -->
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>intersection</title>
  <short_description>intersect lists, ideals, or modules</short_description>
<syntax>
intersection(A: <type>LIST</type>, B: <type>LIST</type>): <rtn>LIST</rtn>
intersection(A: <type>IDEAL</type>, B: <type>LIST</type>): <rtn>LIST</rtn>
intersection(A: <type>LIST</type>, B: <type>IDEAL</type>): <rtn>LIST</rtn>
intersection(A: <type>IDEAL</type>, B: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the intersection of <tt>A</tt> and <tt>B</tt>.
<par/>
The coefficient ring must be a field.
<par/>
NOTE: To compute the intersection of ideals corresponding to
zero-dimensional schemes, see the commands <ttref>GBM</ttref>
and <ttref>HGBM</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  intersection(ideal(x,y,z), ideal(x*y));
ideal(x*y)

/**/  intersection(["a","b","c"], ["b","c","d"]);
["b", "c"]
-------------------------------
</example>
</description>
<seealso>
  <see>GBM</see>
  <see>HGBM</see>
  <see>IntersectList</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IntersectList</title>
  <short_description>intersect lists, ideals, or modules</short_description>
<syntax>
IntersectionList(L: <type>LIST</type> of <type>LIST</type>): <rtn>LIST</rtn>
IntersectionList(L: <type>LIST</type> of <type>IDEAL</type>): <rtn>IDEAL</rtn>
IntersectionList(L: <type>LIST</type> of <type>MODULE</type>): <rtn>MODULE</rtn>
</syntax>
<description>
This function returns the intersection of all elements in <tt>L</tt>.
Generalizes <ttref>intersection</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  Points := [[0,0],[1,0],[0,1],[1,1]]; -- a list of points in the plane
/**/  IntersectionList([ ideal(x-P[1]*z, y-P[2]*z)  |  P In Points]);
ideal(y^2 - y*z, x^2 - x*z)

/**/ IntersectionList([ 1..7, 3..10, 0..5 ]);
[3, 4, 5]
</example>
</description>
<seealso>
  <see>intersection</see>
  <see>IdealOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>HGBM</see>
  <see>intersection</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>inverse</title>
  <short_description>multiplicative inverse</short_description>
<syntax>
inverse(X: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function computes the multiplicative inverse of its argument.
It is included for use when writing inverse(X) comes more naturally
than writing <tt>X^(-1)</tt>, though both notations are functionally equivalent.
<example>
/**/  inverse(mat(QQ, [[1,2], [3,4]]));
matrix([
  [-2, 1],
  [3/2, -1/2]
])
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>InverseSystem</title>
  <short_description>Inverse system of an ideal of derivations</short_description>
<syntax>
InverseSystem(I: <type>IDEAL</type>, D: <type>INT</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
Thanks to Enrico Carlini.
<par/>
Given an ideal of derivations <tt>I</tt>, and an integer <tt>D</tt>, this function
computes the degree <tt>D</tt> part of the inverse system of <tt>I</tt>.
<par/>
For the sake of simplicity Forms/Polynomials and Derivations live in
the same ring, the distinction between them is purely formal.
<example>
/**/  Use QQ[x,y,z];
/**/  InverseSystem(ideal(x^3+x*y*z), 3);
[z^3, y*z^2, x*z^2, y^2*z, x^2*z, y^3, x*y^2, x^2*y, x^3 - 6*x*y*z]
</example>
</description>
<seealso>
  <see>DerivationAction</see>
  <see>PerpIdealOfForm</see>
</seealso>
<keys>
  <key>author: enrico carlini</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IO.SprintTrunc</title>
  <short_description>convert to a string and truncate</short_description>

<syntax>
$io.SprintTrunc(E: <type>OBJECT</type>, N: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function works like <ttref>sprint</ttref>, turning the value of the
expression E into a string, but if the string has length greater than
N-1, it is truncated and the string <tt>...</tt> is concatenated.  This
function is useful in formatting reports of results.

<example>
  Use R ::= QQ[x,y];
  I := ideal(x,y);
  $io.SprintTrunc(I,4);
Idea...
-------------------------------
</example>
</description>


<seealso>
  <see>format</see>
  <see>sprint</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>iroot</title>
  <short_description>integer part of r-th root of an integer</short_description>

<syntax>
iroot(N: <type>INT</type>, R: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the R-th root of an integer.  If the argument is
not a perfect R-th power it returns the integer part of the root.

<example>
/**/  iroot(25, 2);
5
/**/  iroot(99, 3);
4
/**/  iroot(-1, 3);
-1
</example>
</description>


<seealso>
  <see>ILogBase</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsAntiSymmetric</title>
  <short_description>checks if a matrix is anti-symmetric</short_description>
  
<syntax>
IsAntiSymmetric(M: <type>MAT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the square matrix <tt>M</tt> is anti-symmetric.
<example>
/**/  M := mat([[0, 1, 2], [-1, 0, 3], [-2, -3, 0]]);
/**/  IsAntiSymmetric(M);
true
</example>
</description>
<seealso>
  <see>IsSymmetric</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsConstant</title>
  <short_description>checks if a ringelem is in the coefficient ring</short_description>

<syntax>
IsConstant(X: <type>RINGELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the value of a RINGELEM of a polynomial ring
actually lies in the image of the coefficient ring.  It is equivalent to
checking that the degree in each indeterminate is 0.

<example>
/**/  QQx ::= QQ[x];
/**/  Use QQx[y,z];
/**/  IsConstant(y+1);
false
/**/  IsConstant(x+1);
true
</example>
</description>

<seealso>
  <see>indets</see>
</seealso>

</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsContained</title>
  <short_description>checks if A is Contained in B</short_description>
  
<syntax>
IsContained(A: <type>IDEAL</type>, B: <type>IDEAL</type>): <rtn>BOOL</rtn>
IsContained(A: <type>MODULE</type>, B: <type>MODULE</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether A is contained in B.
Was <tt>&lt;=</tt> in CoCoA-4: this syntax is no longer supported.

<example>
/**/  Use QQ[x,y,z];
/**/  IsContained(ideal(x), ideal(x+y, x-y));
true
</example>
</description>
<seealso>
  <see>IsIn</see>
  <see>IsSubset</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsDefined</title>
  <short_description>check if an expression has been defined</short_description>

<syntax>
IsDefined(E)
</syntax>
<description>
This function returns true if <tt>E</tt> is defined, otherwise it returns false.
Typically, it is used to check if a name has already been assigned.
<par/>
To know if a field in a record has been assigned use <ttref>fields</ttref>.

<example>
/**/  IsDefined(MyVariable);
false

/**/  MyVariable := 3;
/**/  IsDefined(MyVariable);
true
</example>
</description>

<seealso>
  <see>fields</see>
</seealso>

</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsDiagonal</title>
  <short_description>checks if a matrix is diagonal</short_description>

<syntax>
IsDiagonal(M: <type>MAT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the square matrix M is diagonal.

<example>
/**/  M := mat([[0, 1, 2],[-1, 0, 3],[-2, -3, 0]]);
/**/  IsDiagonal(M);
false
</example>
</description>

<seealso>
  <see>IsSymmetric</see>
  <see>DiagMat</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsDivisible</title>
  <short_description>checks if A is divisible by B</short_description>
<syntax>
IsDivisible(A: <type>RINGELEM</type>, B: <type>RINGELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function says whether <tt>A</tt> is divisible by <tt>B</tt>; it
returns <tt>true</tt> if so, otherwise <tt>false</tt>.

<example>
/**/  Use QQ[x,y,z];
/**/   IsDivisible(x, x^2*(y-1));
false
/**/   IsDivisible(x^2*(y-1), x);
true
</example>
</description>

<keys>
  <key>divides</key>
  <key>divisibility</key>
  <key>factor</key>
  <key>isfactor</key>
</keys>

<seealso>
  <see>valuation</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsElem</title>
  <short_description>checks if A is an element of B</short_description>
  
<syntax>
IsElem(A: <type>RINGELEM</type>, B: <type>IDEAL</type>): <rtn>BOOL</rtn>
IsElem(A: <type>MODULEELEM</type>, B: <type>MODULE</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether A is an element of B.
Same as the command <ttref>IsIn</ttref>, but works on fewer types: it
is in CoCoA-5 for compatibility with the C++ function in CoCoALib.

<example>
/**/  Use QQ[x,y,z];
/**/  IsElem(x, ideal(x+y, x-y));
true

/**/  x IsIn ideal(x+y, x-y);
true
</example>
</description>
<seealso>
  <see>IsIn</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsEven, IsOdd</title>
  <short_description>test whether an integer is even or odd</short_description>

<syntax>
IsEven(N: <type>INT</type>): <rtn>BOOL</rtn>
IsOdd(N: <type>INT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
These functions test whether an integer is even or odd.

<example>
/**/  IsEven(3);
false
/**/  IsOdd(3);
true
</example>
</description>


<seealso>
  <see>IsZero</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsFactorClosed</title>
  <short_description>test whether a list of PPs is factor closed</short_description>

<syntax>
IsFactorClosed(L: <type>LIST</type> of power products): <rtn>BOOL</rtn>
</syntax>
<description>
A set of power products is factor closed iff it contains every factor of
every one of its elements.  This function checks whether the given set
is factor closed (also known as "order-ideal").  It is an error if L is empty.

<example>
/**/  use P ::= QQ[x,y,z];
/**/  IsFactorClosed([1, x, x^2]);
true
/**/  IsFactorClosed([one(P), y^2]);
false
</example>
</description>

<seealso>
  <see>QuotientBasis</see>
  <see>LT</see>
  <see>TmpNBM</see>
  <see>IsStronglyStable</see>
</seealso>
<keys>
  <key>factor-closed</key>
  <key>factor closed</key>
  <key>order-ideal</key>
  <key>order ideal</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsField</title>
  <short_description>test whether a ring is a field</short_description>

<syntax>
IsField(R: <type>RING</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether a ring is a field.

<example>
/**/  IsField(ZZ);
false
/**/  IsField(QQ);
true
</example>
</description>


<seealso>
  <see>IsFiniteField</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsFiniteField</title>
  <short_description>test whether a ring is a finite field</short_description>

<syntax>
IsFiniteField(R: <type>RING</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether a ring is a finite field.

<example>
/**/  IsFiniteField(ZZ);
false
/**/  IsFiniteField(QQ);
false
/**/  Fp::=ZZ/(7); IsFiniteField(Fp);
true
</example>
</description>


<seealso>
  <see>IsField</see>
  <see>IsPthPower</see>
  <see>LogCardinality</see>
  <see>PthRoot</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsHomog</title>
  <short_description>test whether given polynomials are homogeneous</short_description>

<syntax>
IsHomog(F: <type>RINGELEM</type>|<type>MODULEELEM</type>): <rtn>BOOL</rtn>
IsHomog(L: <type>LIST</type>): <rtn>BOOL</rtn>
IsHomog(I: <type>IDEAL</type>|<type>MODULE</type>): <rtn>BOOL</rtn>
</syntax>
<description>
The first form of this function returns True if F is homogeneous.
The second form returns True if every element of L is homogeneous.
Otherwise, they return False.  The third form returns True if the
ideal/module can be generated by homogeneous elements, and False
if not.  Homogeneity is with respect to the first row of the weights
matrix.
<par/>
NOTE: when the grading dimension is 0 everything is trivially true.
For safety reasons (from version 5.0.3) <tt>IsHomog</tt> throws an error
in this case, e.g. <tt>IsHomog(x-1)</tt> gives error instead of a
possibly misleading <tt>true</tt>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  IsHomog(x^2-x*y);
true

/**/  IsHomog(x-y^2);
false

/**/  IsHomog([x^2-x*y, x-y^2]);
false

/**/  R := NewPolyRing(QQ, ["x","y"], mat([[2,3],[1,2]]), 1);
/**/  Use R;
/**/  IsHomog(x^3*y^2+y^4);
true

/**/  R := NewPolyRing(QQ, ["x","y"], mat([[2,3],[1,2]]), 2);
/**/  Use R;
/**/  IsHomog(x^3*y^2+y^4);
false

/**/  Use R ::= QQ[x,y];
/**/  IsHomog(ideal(x^2+y,y));
true

/**/  Use R ::= QQ[x,y], Lex;  -- note: GradingDim = 0
-- /**/  IsHomog(x-1); -- !!! ERROR !!! instead of "true"
</example>
</description>


<seealso>
  <see>deg</see>
  <see>wdeg</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsIn</title>
  <short_description>check if one object is contained in another</short_description>

<syntax>
X  IsIn  Y        (return <rtn>BOOL</rtn>)
</syntax>
<description>
The semantics of <tt>IsIn</tt> is explained in the following table:
<verbatim>
   --------------------------------------------------------------------
  | OBJECT     IsIn  LIST    checks if the list contains the object.   |
  | POLY       IsIn  IDEAL   checks for ideal membership.              |
  | MODULEELEM IsIn  MODULE  checks for module membership.             |
  | STRING     IsIn  STRING  checks if the first string is a substring |
  |                      of the second one.                            |
   --------------------------------------------------------------------
                       IsIn operator
</verbatim>
</description>

<types>
  <type>IDEAL</type>
  <type>LIST</type>
  <type>MODULE</type>
  <type>RINGELEM</type>
  <type>STRING</type>
  <type>MODULEELEM</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsIndet</title>
  <short_description>checks argument is an indetermiante</short_description>

<syntax>
IsIndet(X: <type>RINGELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether <tt>X</tt> is an indeterminate.  If so, it
returns <tt>true</tt>; otherwise it returns <tt>false</tt>.  An error
is signalled if <tt>X</tt> is not a <tt>RINGELEM</tt> or
if <tt>RingOf(X)</tt> is not a polynomial ring.

<example>
/**/  Use QQ[x,y,z];
/**/  IsIndet(x);
true
/**/  IsIndet(x-1);
false
</example>
</description>


</command>
<!-- ===  COMMAND  =============================================== -->
<!-- <command> -->
<!--   <title>IsInImage</title> -->
<!--   <short_description>check if a RINGELEM is in image of RINGHOM</short_description> -->
<!-- <syntax> -->
<!-- IsInImage(phi: <type>RINGHOM</type>, f: <type>RINGELEM</type>): <rtn>BOOL</rtn> -->
<!-- </syntax> -->
<!-- <description> -->
<!-- This function checks if <tt>f</tt> is in the image of <tt>phi</tt>. -->
<!-- <example> -->
<!-- /**/  QQxyz ::= QQ[x,y,z]; -->
<!-- /**/  QQab  ::= QQ[a,b]; -->

<!-- /**/  Use QQab; -->
<!-- /**/  phi := PolyAlgebraHom(QQxyz, QQab, [a+1, a*b+3, b^2]); -->
<!-- ideal(-x^2*z +y^2 +2*x*z -6*y -z +9) -->
<!-- /**/  IsSurjective(phi); -->
<!-- false -->

<!-- /**/  Use QQab; -->
<!-- /**/  IsInImage(phi, b); -->
<!-- false -->
<!-- /**/  IsInImage(phi, a^2); -->
<!-- true -->
<!-- /**/  PreImage(phi, a^2); -->
<!-- x^2 -2*x +1 -->
<!-- /**/  phi(ReadExpr(QQxyz, "x^2 - 2*x + 1")); -->
<!-- a^2 -->
<!-- </example> -->
<!-- </description> -->
<!-- <seealso> -->
<!--   <see>IsSurjective</see> -->
<!--   <see>IsInImage</see> -->
<!--   <see>PreImage</see> -->
<!-- </seealso> -->
<!-- </command> -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsInjective</title>
  <short_description>check if a RINGHOM is injective</short_description>
<syntax>
IsInjective(phi: <type>RINGHOM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function checks if a RINGHOM is injective.
<example>
/**/  QQxyz ::= QQ[x,y,z];
/**/  QQab  ::= QQ[a,b];

/**/  Use QQab;
/**/  phi := PolyAlgebraHom(QQxyz, QQab, [a+1, a*b+3, b^2]);
/**/  IsInjective(phi);
false
/**/  ker(phi);
ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)
/**/  IsSurjective(phi);
false

/**/  Use QQab;
/**/  PreImage(phi, b);
record[IsInImage := false, ker := ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)]

/**/  indent(PreImage(phi, a^2));
Record[
  IsInImage := true,
  OnePreImage := x^2 -2*x +1,
  ker := ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)
]
/**/  phi(ReadExpr(QQxyz, "x^2 - 2*x + 1"));
a^2
/**/  phi(ReadExpr(QQxyz, "x^2 - 2*x + 1 + (-x^2*z +y^2 +2*x*z -6*y -z +9)"));
a^2
</example>
</description>
<seealso>
  <see>ker</see>
  <see>IsSurjective</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsInRadical</title>
  <short_description>check if a polynomial (or ideal) is in a radical</short_description>

<syntax>
IsInRadical(F: <type>RINGELEM</type>, I: <type>IDEAL</type>): <rtn>BOOL</rtn>
IsInRadical(J: <type>IDEAL</type>, I: <type>IDEAL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the first argument, a polynomial or an
ideal, is contained in the radical of the second argument, an ideal.

<par/>
This function is much faster than asking <tt>F IsIn Radical(I);</tt>.

<example>
/**/  Use QQ[x,y,z];
/**/  I := ideal(x^6*y^4, z);
/**/  IsInRadical(x*y, I);
true

/**/  IsInRadical(ideal(x,y), I);
false

/**/  MinPowerInIdeal(x*y, I);
6
</example>
</description>


<seealso>
  <see>MinPowerInIdeal</see>
  <see>radical</see>
</seealso>

<keys>
  <key>radical membership</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsInSubalgebra [OBSOLETE]</title>
  <short_description>[OBSOLETE] check if one polynomial is in a subalgebra</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
See  <ttref>SubalgebraRepr</ttref>.
</description>
<seealso>
  <see>SubalgebraRepr</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsLexSegment</title>
  <short_description>checks if an ideal is lex-segment</short_description>

<syntax>
IsLexSegment(I: <type>IDEAL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the monomial ideal I is a lex-segment ideal.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x*y^3, y^4, x^3, x^2*y, x^2*z);
/**/  IsLexSegment(I);
false
</example>
</description>


<seealso>
  <see>IsStable</see>
  <see>IsStronglyStable</see>
  <see>LexSegmentIdeal</see>
</seealso>
<keys>
  <key>lex segment</key>
  <key>lex-segment</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsNumber [OBSOLETE]</title>
  <short_description>[OBSOLETE] checks if the argument is a number</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
See <tt>IsInteger</tt>, <tt>IsRational</tt>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsPositiveGrading</title>
  <short_description>check if a matrix defines a positive grading</short_description>

<syntax>
IsPositiveGrading(M: <type>MAT</type>): <rtn>BOOL</rtn>
IsPositiveGrading(M: <type>MAT</type>,N: <type>INT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function determines whether a matrix defines a positive grading,
i.e. foreach column the first nonnegative entry is positive.

<example>
/**/  IsPositiveGrading(LexMat(5));
true

/**/  IsPositiveGrading(LexMat(5),3); --considering only the first three rows
false

/**/  IsPositiveGrading(mat([[0,2,3], [1, -1, 0]]));
true

/**/  IsPositiveGrading(mat([[1,1], [0,-1], [-1, 0]]));
true
</example>
</description>


<seealso>
  <see>HilbertSeriesMultiDeg</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsPrime</title>
  <short_description>prime integer test</short_description>

<syntax>
IsPrime(N: <type>INT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function determines whether a positive integer is prime; if <code>N</code>
is not positive, an error is signalled.  This function may be extremely slow
when <code>N</code> is a large prime; in practice it is usually better to call
<code>IsProbPrime</code>.

For the curious: currently, the function first performs a probabilistic check
(Miller-Rabin), if that passes, it then verifies primality (via Lucas test).

<example>
/**/  IsPrime(32003);
true

/**/  IsPrime(10^100);
false
</example>
</description>


<seealso>
  <see>IsProbPrime</see>
  <see>NextPrime</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsProbPrime</title>
  <short_description>checks if an integer is a probable prime</short_description>

<syntax>
IsProbPrime(N: <type>INT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function returns True if its integer argument passes a fairly
stringent primality test; otherwise it returns False.  There is a very
small chance of the function returning True even though the argument is
composite; if it returns False, we are certain that the argument is composite.
Some people call it a compositeness test.

<example>
/**/  IsProbPrime(2);
true

/**/  IsProbPrime(1111111111111111111);
true

/**/  [N in 1..1111 | IsProbPrime((10^N-1)/9)]; -- only five values are known
[2, 19, 23, 317, 1031]                          -- next might be 49081
</example>
</description>


<seealso>
  <see>IsPrime</see>
  <see>NextProbPrime</see>
</seealso>
<keys>
  <key>primality test</key>
  <key>compositeness test</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsPthPower</title>
  <short_description>p-th power test</short_description>

<syntax>
IsPthPower(X: <type>RINGELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function determines whether a polynomial over a finite
field (of char p) is a p-th power.
If the coefficient ring is not a finite field then an error is signalled.

<example>
/**/  Use ZZ/(7)[x];
/**/  IsPthPower(x^7+3);
true
/**/  IsPthPower(x^6+3);
false
</example>
</description>


<seealso>
  <see>IsFiniteField</see>
  <see>PthRoot</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>isqrt</title>
  <short_description>(truncated) square root of an integer</short_description>

<syntax>
isqrt(N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the square root of an integer.  If the argument is
not a perfect square it returns the integer part of the square root.

<example>
/**/  isqrt(16);
4

/**/  isqrt(99);
9

-- /**/  isqrt(-1);  --> !!! ERROR !!!
ERROR: Value must be non-negative
 isqrt(-1);
 ^^^^^^^^^
</example>
</description>

<keys>
  <key>square root</key>
  <key>squareroot</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsQuotientRing</title>
  <short_description>test whether a ring is a quotient ring</short_description>

<syntax>
IsQuotientRing(R: <type>RING</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether a ring is a quotient ring; it returns <tt>true</tt>
if the ring is a quotient ring.
<example>
/**/  Use R ::= QQ[x,y];
/**/  S := R/ideal(x);
/**/  IsQuotientRing(S);
true;
</example>
</description>

<seealso>
  <see>DefiningIdeal</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsStable</title>
  <short_description>checks if an ideal is stable</short_description>

<syntax>
IsStable(I: <type>IDEAL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the monomial ideal I is stable.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x*y^3, y^4, x^3, x^2*y, x^2*z);
/**/  IsStable(I);
true
</example>
</description>


<seealso>
  <see>IsLexSegment</see>
  <see>IsStronglyStable</see>
  <see>LexSegmentIdeal</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsStdGraded</title>
  <short_description>checks if the grading is standard</short_description>
  
<syntax>
IsStdGraded(P: <type>RING</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether <tt>P</tt> is standard graded,
<em>i.e.</em> <tt>GradingDim</tt> is 1 and all indeterminates
in <tt>P</tt> have degree 1.

<example>
/**/  P ::= QQ[x,y,z];
/**/  IsStdGraded(P);
true
/**/  P ::= QQ[x,y,z], lex;
/**/  IsStdGraded(P);
false
/**/  P := NewPolyRing(QQ, ["x","y"], mat([[2,3],[1,2]]), 1);
/**/  IsStdGraded(P);
false
</example>
</description>

<seealso>
  <see>NewPolyRing</see>
  <see>wdeg</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsStronglyStable</title>
  <short_description>checks if an ideal is strongly stable</short_description>

<syntax>
IsStronglyStable(I: <type>IDEAL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the monomial ideal I is strongly stable
(Borel-fixed in characteristic 0).

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x*y^3, y^4, x^3, x^2*y, x^2*z);
/**/  IsStronglyStable(I);
true
</example>
</description>


<seealso>
  <see>IsLexSegment</see>
  <see>IsStable</see>
</seealso>
<keys>
  <key>borel</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsSubset</title>
  <short_description>checks if the elements of one list are a subset of another</short_description>
<syntax>
IsSubset(L: <type>LIST</type>, M: <type>LIST</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function returns <tt>true</tt> if <tt>MakeSet(L)</tt> is contained in <tt>MakeSet(M)</tt>;
otherwise it returns <tt>false</tt>.
<example>
/**/  IsSubset([1,1,2],[1,2,3,"a"]);
true
/**/  IsSubset([1,2],["a","b"]);
false
/**/  IsSubset([],[1,2]);
true
</example>
</description>
<seealso>
  <see>IsContained</see>
  <see>IsIn</see>
  <see>EqSet</see>
  <see>MakeSet</see>
  <see>subsets</see>
</seealso>
<keys>
  <key>subset</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsSurjective</title>
  <short_description>check if a RINGHOM is surjective</short_description>
<syntax>
IsSurjective(phi: <type>RINGHOM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function checks if a RINGHOM is surjective.
<example>
/**/  QQxyz ::= QQ[x,y,z];
/**/  QQab  ::= QQ[a,b];

/**/  Use QQab;
/**/  phi := PolyAlgebraHom(QQxyz, QQab, [a+1, a*b+3, b^2]);
ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)
/**/  IsSurjective(phi);
false

/**/  PreImage(phi, b);
record[IsInImage := false, ker := ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)]
</example>
</description>
<seealso>
  <see>ker</see>
  <see>IsInjective</see>
  <see>PreImage</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsSymmetric</title>
  <short_description>checks if a matrix is symmetric</short_description>

<syntax>
IsSymmetric(M: <type>MAT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether the square matrix <tt>M</tt> is symmetric.
<example>
/**/ M := mat([[1, 2, 3],  [2, 4, 5],  [3, 5, 6]]);
/**/ IsSymmetric(M);
true
</example>
</description>
<seealso>
  <see>IsAntiSymmetric</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsTerm</title>
  <short_description>checks if the argument is a term</short_description>
  
<syntax>
IsTerm(X: <type>RINGELEM</type>|<type>MODULEELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
The function determines whether X is a term.  For a polynomial, a
<em>term</em> is a power-product, i.e., a product of indeterminates.
Thus, <formula>x*y^2*z</formula> is a term,
while <formula>4*x*y^2*z</formula> and <formula>x*y+z^3</formula> are not.
For a vector, a term is a power-product times a standard basis vector, e.g.,
<formula>(0, x*y^2*z, 0)</formula>.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  IsTerm(x+y^2);
false

/**/  IsTerm(x^3*y*z^2);
true

/**/  IsTerm(5*x^3*y*z^2);
false

/**/  R2 := NewFreeModule(R,2);
--/**/  IsTerm(ModuleElem(R2, [0,x*z])); --***WORK IN PROGRESS***
--true

--/**/  IsTerm(ModuleElem(R2, [x,y])); --***WORK IN PROGRESS***
--false
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsTermOrdering</title>
  <short_description>check if a matrix defines a term-ordering</short_description>

<syntax>
IsTermOrdering(M: <type>MAT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function determines whether a square matrix defines a term-ordering,
i.e. if its determinant is non-zero and if foreach column the first
nonnegative entry is positive.
<example>
/**/  IsTermOrdering(LexMat(5));
true

/**/  IsTermOrdering(StdDegRevLexMat(5));
true

/**/  IsTermOrdering(RevLexMat(5));
false
</example>
</description>
<seealso>
  <see>NewPolyRing</see>
  <see>OrdMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsTree5</title>
  <short_description>checks if a facet complex is a tree</short_description>

<syntax>
IsTree5(L: <type>LIST</type>): [BOOL, LIST ]
IsTree5(L: <type>LIST</type>, "NOOPT"): [BOOL, LIST]
IsTree5(L: <type>LIST</type>, "OPT"): [BOOL, LIST]
IsTree5(L: <type>LIST</type>, "CS_NOOPT"): [BOOL, LIST]
IsTree5(L: <type>LIST</type>, "CS_OPT"): [BOOL, LIST]
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function is implemented in CoCoALib.
<par/>
This function tests whether the facet complex described by the
list L of square free power products is a tree, plus a list which:
<par/>
- is empty if L is a tree
<par/>
- contains three elements of a cycle of L if L is not a tree.
<par/>
Four options <tt>NOOPT</tt>,<tt>OPT</tt>,<tt>CS_NOOPT</tt>,<tt>CS_OPT</tt> are available as second
argument, specifying different algorithms; the default is <tt>CS_OPT</tt>.
<par/>
For a full description of the algorithms we refer to the paper by
M. Caboara, S. Faridi, and P. Selinger, <quotes>Simplicial cycles and
the computation of simplicial trees</quotes>, Journal of Symbolic Computation,
vol.42/1-2, pp.77-88 (2006).

<example>
  Use R ::= QQ[x,y,z,t];
  D := [x*y, y*z, z*t, t*x];
  IsTree5(D);
[False, [xy, xt, yt]]
-------------------------------
  IsTree5([xy, yz, zt]);
[True, [ ]]
-------------------------------
</example>
</description>

<keys>
  <key>author: caboara</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsTrueGCDDomain</title>
  <short_description>test whether a ring is a true GCD domain</short_description>

<syntax>
IsTrueGCDDomain(R: <type>RING</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether a ring is a (true) GCD domain but not a field.
CoCoA can compute GCDs of elements of a true GCD domain.
<example>
/**/  IsTrueGCDDomain(ZZ);
true
/**/  IsTrueGCDDomain(QQ);
false
</example>
</description>
<seealso>
  <see>IsField</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsZero</title>
  <short_description>test whether an object is zero</short_description>

<syntax>
IsZero(X: <type>OBJECT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether its argument is zero; the argument can be
of almost any type for which <em>zero</em> makes sense.
<example>
/**/  IsZero(23);
false
/**/  IsZero(3-3);
true
/**/  Use R ::= QQ[x,y,z];
/**/  IsZero(x^2+3*y-1);
false
/**/  IsZero(ideal(x^2,x*y^3));
false
/**/  F := NewFreeModule(R, 3);
/**/  zero(F);
[0, 0, 0]
/**/  IsZero(zero(F));
true
/**/  IsZero(matrix([[0,0,0], [0,0,0]]));
true
</example>
</description>
<seealso>
  <see>IsEven, IsOdd</see>
  <see>zero</see>
  <see>ZeroMat</see>
</seealso>
<types>
  <type>IDEAL</type>
  <type>INT</type>
  <type>MAT</type>
  <type>MODULE</type>
  <type>RINGELEM</type>
  <type>RAT</type>
  <type>MODULEELEM</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsZeroCol, IsZeroRow</title>
  <short_description>test whether a column(row) is zero</short_description>

<syntax>
IsZeroCol(M: <type>MAT</type>, N: <type>INT</type>): <rtn>BOOL</rtn>
IsZeroRow(M: <type>MAT</type>, N: <type>INT</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether all entries in the <tt>N</tt>-th column(row)
of <tt>M</tt> are zero.
<example>
/**/  IsZeroRow(matrix([[1,0,0], [0,0,0]]), 1);
false
/**/  IsZeroCol(matrix([[1,0,0], [0,0,0]]), 2);
true
</example>
</description>
<seealso>
  <see>IsZero</see>
  <see>ZeroMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsZeroDim</title>
  <short_description>test whether an ideal is zero-dimensional</short_description>

<syntax>
IsZeroDim(I: <type>IDEAL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether its argument is zero-dimensional.
<example>
/**/  Use QQ[x,y,z];
/**/  IsZeroDim(ideal(x));
false
/**/  IsZeroDim(ideal(x^3, y^4-x ,z-3));
true
/**/  IsZeroDim(ideal(x^2, x*y^3));
false
</example>
</description>
<seealso>
  <see>dim</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>IsZeroDivisor</title>
  <short_description>test whether a RINGELEM is a zero-divisor</short_description>

<syntax>
IsZeroDivisor(X: <type>RINGELEM</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function tests whether its argument is a zero-divisor.
<example>
/**/  Use P ::= QQ[x,y,z];
/**/  R := NewQuotientRing(P, ideal(x*y));
/**/  IsZeroDivisor(RingElem(R,x));
true
/**/  colon(ideal(zero(R)), ideal(RingElem(R,x)));
ideal((y))
</example>
</description>
<seealso>
  <see>colon</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>It</title>
  <short_description>variable containing the last result</short_description>

<syntax>
It
</syntax>
<description>
<tt>It</tt> is a top-level SYSTEM VARIABLE containing the last result computed
but not assigned.  It is the CoCoA equivalent to GAP's <tt>last</tt>.
<par/>
When CoCoA evaluates a <em>standalone expression</em>, the result is assigned to
the system variable named <tt>It</tt> (and then printed as if in a <ref>println</ref>
command).  You may use <tt>It</tt> in expressions just like any other variable.
<example>
/**/  1+1; -- standalone expression ==> result is saved in "It".
2
/**/  It;
2

/**/  It+1;
3
/**/  It;
3

/**/  X := 17;  -- assignment is not a standalone expression, "It" is unchanged
/**/  It;
3
/**/  X+It;
20
</example>
</description>
<seealso>
  <see>print</see>
  <see>println</see>
  <see>Evaluation and Assignment</see>
</seealso>
<keys>
  <key>system variable</key>
  <key>The variable It</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>J</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>jacobian</title>
  <short_description>the Jacobian of a list of polynomials</short_description>

<syntax>
jacobian(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the Jacobian matrix of the polynomials in <tt>L</tt>
with respect to all the indeterminates of the current ring.
<example>
/**/  Use R ::= QQ[x,y];
/**/  L := [x-y, x^2-y, x^3-y^2];
/**/  jacobian(L);
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[1, -1],
  [2*x, -1],
  [3*x^2, -2*y]])
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>JanetBasis</title>
  <short_description>the Janet basis of an ideal</short_description>
<syntax>
JanetBasis(I: <type>IDEAL</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
Thanks to Mario Albert.
<par/>
This function returns the Janet basis of an ideal.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  L := [x-y, x^2-z+1, x^3-y^2];
/**/  JanetBasis(ideal(L));
[x -y, z^2 -3*z +2, y*z -y -z +1, y^2 -z +1]
</example>
</description>
<keys>
  <key>janet basis</key>
  <key>author: mario albert</key>
</keys>

<seealso>
  <see>GBasis</see>
</seealso>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>K</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ker</title>
  <short_description>Kernel of a homomorphism</short_description>
<syntax>
ker(phi: <type>RINGHOM</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the kernel of a homomorphism.
<example>
/**/ R ::= QQ[x,y,z,w];
/**/ Use S ::= QQ[s,t];
/**/ phi := PolyAlgebraHom(R, S, [s^3, s^2*t, s*t^2, t^3]);
/**/ ker(phi);
ideal(z^2 -y*t, y*z -x*t, y^2 -x*z)

/**/ SmodJ := NewQuotientRing(S, ideal(ReadExpr(S,"t+s")));
/**/ Use SmodJ;
/**/ psi := PolyAlgebraHom(R, SmodJ, [s^3, s^2*t, s*t^2, t^3]);
/**/ ker(psi);
ideal(x +w, y -w, z +w)

/**/ RmodI := NewQuotientRing(R, ideal(ReadExpr(R,"x+y")));
/**/ ker(InducedHom(RmodI, psi));
ideal((-y +w), (y -w), (z +w))
</example>
</description>
<seealso>
  <see>PreImage</see>
  <see>IsInjective</see>
  <see>IsSurjective</see>
</seealso>
<keys>
  <key>subalgebra</key>
  <key>homomorphism</key>
  <key>kernel</key>
</keys>
</command>
</chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>L</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>last</title>
  <short_description>the last N elements of a list</short_description>

<syntax>
last(L: <type>LIST</type>): <rtn>OBJECT</rtn>
last(L: <type>LIST</type>, N: <type>INT</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
In the first form, the function returns the last element of L.  In
the second form, it returns the list of the last N elements of L.
<par/>
The CoCoA equivalent to GAP <tt>last</tt> is the variable <ttref>It</ttref>.

<example>
/**/  L := [1,2,3,4,5];
/**/  last(L);
5

/**/  last(L,3);
[3, 4, 5]
</example>
</description>


<seealso>
  <see>first</see>
  <see>tail</see>
  <see>It</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LaTeX</title>
  <short_description>LaTeX formatting</short_description>

<syntax>
LaTeX(X: <type>OBJECT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns a string containing the argument formatted in LaTeX.
From version 4.7.5 it returns a string, so it can be printed on a file.
Can also be called as <tt>latex</tt>.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := x^3+2*y^2*z;
/**/  LaTeX(F);
x^{3} + 2y^{2}z

/**/  M := mat([[1,2],[3,4]]);
/**/  LaTeX(M);
\left( \begin{array}{cc} 
  1 &amp; 2 \\
  3 &amp; 4 \end{array}\right)

/**/  R ::= QQ[x,y,z];
/**/  LaTeX(ideal(x^2,y+z));
(x^{2},
 y +z)

/**/  P := NewFractionField(R);
/**/  Use P;
/**/  F := (x+y)/(1-z)^3;
/**/  LaTeX(F);
\frac{ - x - y} {z^{3}-3z^{2} + 3z-1}

</example>
</description>


<seealso>
  <see>format</see>
  <see>sprint</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

<keys>
  <key>LaTeX printing</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LC</title>
  <short_description>the leading coefficient of a polynomial or ModuleElem</short_description>

<syntax>
LC(F: <type>RINGELEM</type>|<type>MODULEELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the leading coefficient of F, as determined by
the term-ordering of the ring to which F belongs.
<example>
/**/  Use R ::= QQ[x,y];
/**/  LC(x +3*x^2 -5*y^2);
3

/**/  F := NewFreeModule(R,3);
/**/  LC(ModuleElem(F, [0, 5*y+6*x^2, y^2]));
6
</example>
</description>
<seealso>
  <see>coefficients</see>
  <see>CoeffOfTerm</see>
  <see>LT</see>
</seealso>
<keys>
  <key>leading coefficient</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>lcm</title>
  <short_description>least common multiple</short_description>

<syntax>
lcm(N: <type>INT</type>, M: <type>INT</type>): <rtn>INT</rtn>
lcm(L: <type>LIST</type> of <type>INT</type>): <rtn>INT</rtn>

lcm(F: <type>RINGELEM</type>, G: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
lcm(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the least common multiple of <tt>F_1,...,F_n</tt>
or of the elements in the list L.
For the calculation of the GCDs and LCMs of polynomials, the
coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[x,y];
/**/  F := x^2-y^2;
/**/  G := (x+y)^3;
/**/  lcm(F, G);
-x^4 -2*x^3*y +2*x*y^3 +y^4

/**/  IsDivisible(F*G, It);
true

/**/  lcm(F, G) * gcd(F,G) = F*G;
true

/**/  lcm([3*4,3*8,6*16]);
96
</example>
</description>


<seealso>
  <see>div</see>
  <see>mod</see>
  <see>gcd</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>least common multiple</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>len</title>
  <short_description>the length of an object</short_description>


<syntax>
len(E: <type>STRING</type>|<type>LIST</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the <em>length</em> of an object, as summarized in
the table below:
<verbatim>
      ----------------------------------------------
     | type   | length                              |
     -----------------------------------------------|
     | STRING | number of bytes in the string       |
     | LIST   | number of items in the list         |
      ----------------------------------------------
               The function <tt>len</tt>
</verbatim>

<example>
/**/  len( [2,3,4] );
3

/**/  len( "string" );
6
</example>

Previously <tt>len</tt> could be applied to other types too; this is no
longer supported.  See <ttref>NumCompts</ttref> for module elements, <ttref>NumRows</ttref>
for matrices, and <ttref>NumTerms</ttref> for polynomials.
</description>

<keys>
  <key>length</key>
</keys>
<seealso>
  <see>count</see>
  <see>NumCompts</see>
  <see>NumRows</see>
  <see>NumTerms</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LexMat</title>
  <short_description>matrices for std. term-orderings</short_description>

<syntax>
LexMat(N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix defining a standard term-ordering.
These functions return matrices defining standard term-orderings.

<example>
  LexMat(3);
matrix([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
</example>
</description>


<seealso>
  <see>Orderings</see>
  <see>StdDegLexMat</see>
  <see>StdDegRevLexMat</see>
  <see>RevLexMat</see>
  <see>XelMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LexSegmentIdeal</title>
  <short_description>lex-segment ideal containing L, or with the same Hilbert fn as I</short_description>

<syntax>
LexSegmentIdeal(L: <type>LIST</type> of power-products): <rtn>IDEAL</rtn>
LexSegmentIdeal(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
If the argument is a list of power-products L, this function returns the
smallest lex-segment ideal containing the power-products in L.
<par/>
If it is an ideal I, it returns the lex-segment ideal having the same
Hilbert function as I.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  LexSegmentIdeal([y^3]);
ideal(y^3, x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3)
/**/  LexSegmentIdeal(ideal(y^3));
ideal(x^3)
</example>
</description>


<seealso>
  <see>IsLexSegment</see>
  <see>StableIdeal</see>
  <see>StronglyStableIdeal</see>
</seealso>

<keys>
  <key>lex segment</key>
  <key>lex-segment</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LF</title>
  <short_description>the leading form of a polynomial or an ideal</short_description>

<syntax>
LF(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
LF(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
For a polynomial <tt>F</tt> this function returns the leading form, <i>i.e.</i> the
sum of all summands having highest degree.  It throws an error if the argument
is zero or if the <ttref>GradingDim</ttref> of the polynomial ring is 0
(use <ttref>DF</ttref> to allow these cases).
<par/>
For an ideal <tt>I</tt> this function returns the ideal of all the <tt>LF(f)</tt>
for <tt>f in I</tt>.  It throws an error if the <ttref>GradingDim</ttref> of the polynomial
ring is 0.

<example>
/**/  Use R ::= QQ[x,y];
/**/  LF(x^2 -x*y +2*x -1);
x^2 -x*y

/**/  Use R ::= QQ[x,y], Lex;  -- GradingDim is 0: everything is homogeneous
-- /**/  LF(x-1); --> !!! ERROR !!! instead of x-1

/**/ P := NewPolyRing(QQ, IndetSymbols(R), mat([[1,4],[1,0]]), 1);
/**/ Use P;
/**/ LF(x^2 - x*y);
-x*y
/**/  LF(x^4 + x^2 - y);
 x^4 -y
</example>
</description>

<keys>
  <key>leading-form</key>
  <key>leadingform</key>
  <key>leading form</key>
</keys>

<seealso>
  <see>DF</see>
  <see>IsHomog</see>
  <see>LC</see>
  <see>LM</see>
  <see>LPP</see>
  <see>LT</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinearSimplify</title>
  <short_description>simplifying linear substitution for a univariate polynomial over QQ</short_description>
<syntax>
LinearSimplify(F: <type>RINGELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns a <tt>RECORD[LinearChange, SimplePoly]</tt>
where <tt>LinearChange</tt> is a linear change of variable
and <tt>SimplePoly</tt> is simple (in a heuristic sense).
The composition <tt>SimplePoly(LinearChange)</tt> is equal the
univariate polynomial <tt>F</tt>.
<example>
/**/  Use QQ[x];
/**/  LinearSimplify((123*x-456)^9-1);
record[LinearChange := 123*x - 456, SimplePoly := x^9 - 1]

/**/  LinearSimplify(x^9-1); -- the heuristic finds no useful simplification
record[LinearChange := x, SimplePoly := x^9 - 1]
</example>
</description>
<keys>
  <key>linear simplify</key>
  <key>simplification</key>
  <key>simplifying substitution</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinKer</title>
  <short_description>find the kernel of a matrix</short_description>
<syntax>
LinKer(M: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns a matrix whose columns representing a basis for
the kernel of <tt>M</tt>.  Calling the function twice on the same input will
not necessarily produce the same output, though in each case, a basis
for the kernel is produced.
<par/>
This function works only on matrices whose entries are in a field
(from version CoCoA-5.0.3).
The CoCoA-4 function returning a ZZ-basis for the kernel of <tt>M</tt> is not
yet implemented.
<par/>
The output as it was given by CoCoA-4 (the basis of the ker) is
now given by <ttref>LinKerBasis</ttref>.
See also <ttref>HilbertBasisKer</ttref>.
<example>
/**/   M := mat([[1,2,3,4],[5,6,7,8],[9,10,11,12]]);
/**/   LinKer(M);
matrix(QQ,
 [[-1, -2],
  [2, 3],
  [-1, 0],
  [0, -1]])

/**/ M*It;
matrix(QQ,
 [[0, 0],
  [0, 0],
  [0, 0]])
</example>
</description>
<seealso>
  <see>LinKerModP</see>
  <see>LinSolve</see>
  <see>HilbertBasisKer</see>
</seealso>
<keys>
  <key>linear kernel</key>
  <key>nullspace</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinKerBasis</title>
  <short_description>find the kernel of a matrix</short_description>
<syntax>
LinKerBasis(M: <type>MAT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list whose components are lists
representing a basis for the kernel of M.  Calling the function
twice on the same input will not necessarily produce the same output,
though in each case, a basis for the kernel is produced.
<par/>
This function works only on matrices whose entries are in a field
(from version CoCoA-5.0.3).
The CoCoA-4 function returning a ZZ-basis for the kernel of <tt>M</tt> is not
yet implemented.
<example>
/**/   M := mat([[1,2,3,4],[5,6,7,8],[9,10,11,12]]);
/**/   LinKerBasis(M);
[[-1, 2, -1, 0], [-2, 3, 0, -1]]

/**/  K := NewFractionField(NewPolyRing(QQ, ["a","b"]));
/**/  Use K;
/**/  M := mat([[1,2,3,a],[5,6,7,a*b]]);
/**/  LinKerBasis(M);
[[-1, 2, -1, 0], [(a*b -3*a)/2, (-a*b +5*a)/4, 0, -1]]
</example>
</description>
<seealso>
  <see>LinKerModP</see>
  <see>LinSolve</see>
</seealso>
<keys>
  <key>linear kernel</key>
  <key>nullspace</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinKerModP</title>
  <short_description>find the kernel of a matrix</short_description>

<syntax>
LinKerModP(M: <type>MAT</type>): <rtn>LIST</rtn>

where M is a matrix over QQ or ZZ.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function returns a list whose components are lists representing a
basis for the kernel of M over the current field of coefficients.

<example>
  M := mat([[1,2,3,4],[5,6,7,8],[9,10,11,12]]);
  Use ZZ/(3)[x];
  LinKerModP(M);
[[1, 1, 1, 0], [0, 2, 2, 2]]
-------------------------------
  Use ZZ/(7)[x];
  LinKerModP(M);
[[2, 3, 2, 0], [1, 3, 5, 5]]
-------------------------------
  N := M*Transposed(mat(It));
  [ [ mod(X,Characteristic()) | X In Row ]  | Row In N ];
[[0, 0], [0, 0], [0, 0]]
-------------------------------
</example>
</description>


<seealso>
  <see>LinKer</see>
  <see>LinSolve</see>
</seealso>
<keys>
  <key>linear kernel</key>
  <key>nullspace</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinSol [OBSOLETE]</title>
  <short_description>[OBSOLETE] find a solution to a linear system</short_description>
<syntax>
[OBSOLETE] use LinSolve
</syntax>
<description>
[OBSOLETE] Replaced by <ttref>LinSolve</ttref>
</description>
<seealso>
  <see>LinSolve</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LinSolve</title>
  <short_description>find a solution to a linear system</short_description>
<syntax>
LinSolve(M: <type>MAT</type>, RHS: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function finds a solution <tt>X</tt> to the matrix equation <tt>M*X = RHS</tt>.
If more than one solution exists, it returns just one of them.
If no solution exists then it produces a 0-by-0 matrix.
To find all solutions, compute the kernel of <tt>M</tt> using the function <ttref>LinKer</ttref>.
<par/>
NOTE: an easy way of converting a list into a column matrix (for the second
argument) is to use the function <ttref>ColMat</ttref>.
<example>
/**/  M := mat([[3,1,4],[1,5,9],[2,6,5]]);
/**/  L := [123,456,789];
/**/  LinSolve(M, ColMat(L));
mat([
  [199/5],
  [742/5],
  [-181/5]
])

/**/  M*It;
mat([
  [123],
  [456],
  [789]
])
-------------------------------
</example>
</description>
<seealso>
  <see>LinKer</see>
</seealso>
<keys>
  <key>solve matrix equation</key>
  <key>solve linear system</key>
  <key>linear system solving</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LM</title>
  <short_description>the leading monomial of a polynomial or ModuleElem</short_description>

<syntax>
LM(X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
LM(X: <type>MODULEELEM</type>): <rtn>MODULEELEM</rtn>
</syntax>
<description>
This function returns the leading monomial of <tt>X</tt>.  The monomial
includes the coefficient.  To get the leading term of <tt>P</tt>, (which does
not included the coefficient), use <ttref>LT</ttref>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  LM(3*x^2*y + y);
3*x^2*y
</example>
</description>
<seealso>
  <see>LC</see>
  <see>LF</see>
  <see>LPP</see>
  <see>LT</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>log</title>
  <short_description>the list of exponents of the leading term of a polynomial</short_description>

<syntax>
log(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of exponents of the leading term of <tt>F</tt>.
The inverse function is <ttref>LogToTerm</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := x^3*y^2*z^5 + x^2*y + x*z^4;
/**/  log(F);
[3, 2, 5]
</example>
</description>

<seealso>
  <see>ILogBase</see>
  <see>LT</see>
  <see>LogToTerm</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LogCardinality</title>
  <short_description>extension degree of a finite field</short_description>


<syntax>
LogCardinality(Fp: <type>RING</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the extension degree of a finite field over its prime
field, or equivalently the log (base p) of its cardinality.
<example>
/**/  Fp ::= ZZ/(7);
/**/  Use Fpx ::= Fp[x];
/**/  Fq := Fpx/ideal(x^2+1);
/**/  LogCardinality(Fq);
2
</example>
</description>

<seealso>
  <see>IsFiniteField</see>
  <see>characteristic</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LogToTerm</title>
  <short_description>returns a monomial (power-product) with given exponents</short_description>


<syntax>
LogToTerm(R: <type>RING</type>, L: <type>LIST</type> of <type>INT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the power-product whose list of exponents is <tt>L</tt>.
It is the inverse of <ttref>log</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  LogToTerm(R, [2,3,5]);
x^2*y^3*z^5

/**/  log(It);
[2, 3, 5]
</example>
</description>

<seealso>
  <see>log</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LPosn</title>
  <short_description>the position of the leading power-product in a ModuleElem</short_description>
  
<syntax>
LPosn(V: <type>MODULEELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the position of the leading power-product of <tt>V</tt>.
<par/>
This function used to be called <tt>LPos</tt> up to version 5.0.3.
<example>
/**/  Use R ::= QQ[x,y,z];  -- the default term-ordering is DegRevLex
/**/  R4 := NewFreeModule(R,4); -- the default module ordering is TOPos
/**/  LPosn(ModuleElem(R4, [0, x, y^2, x^2]));
4
/**/  LPP(ModuleElem(R4, [0, x, y^2, x^2]));
x^2
/**/  LT(ModuleElem(R4, [0, x, y^2, x^2]));
[0, 0, 0, x^2]


  Use R ::= QQ[x,y], PosTo;
  LT(Vector(x,y^2));
Vector(x, 0)
-------------------------------
  LPP(Vector(x,y^2));
x
-------------------------------
  LPosn(Vector(x,y^2));
1
-------------------------------
</example>
</description>

<seealso>
  <see>LF</see>
  <see>LM</see>
  <see>LPP</see>
  <see>LT</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LPP</title>
  <short_description>the leading power-product of a polynomial or ModuleElem</short_description>

<syntax>
LPP(X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
LPP(X: <type>MODULEELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the leading power-product of <tt>X</tt>; it discards
information about which component the power-product appears in.
<example>
/**/  Use R ::= QQ[x,y];
/**/  LPP(3*x^2*y+y);  -- LPP is the same as LT for polynomials
x^2*y

-- Note the difference between LPP and LT for MODULEELEM.
/**/  R4 := NewFreeModule(R,4); -- the default module ordering is TOPos
/**/  LPP(ModuleElem(R4, [0, x, y^2, x^2]));
x^2
/**/  LT(ModuleElem(R4, [0, x, y^2, x^2]));
[0, 0, 0, x^2]
/**/  LPosn(ModuleElem(R4, [0, x, y^2, x^2]));
4
</example>
</description>
<seealso>
  <see>LC</see>
  <see>LF</see>
  <see>LM</see>
  <see>LPosn</see>
  <see>LT</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>LT</title>
  <short_description>the leading term of an object</short_description>

<syntax>
LT(I: <type>RINGELEM</type>):   <rtn>RINGELEM</rtn>
LT(I: <type>IDEAL</type>):      <rtn>IDEAL</rtn>
LT(I: <type>MODULEELEM</type>): <rtn>MODULEELEM</rtn>
LT(I: <type>MODULE</type>):     <rtn>MODULE</rtn>
</syntax>
<description>
If E is a polynomial this function returns the leading term of the
polynomial E with respect to the term-ordering of the polynomial ring
of E.
For the leading monomial, which includes the coefficient, use <ttref>LM</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];  -- the default term-ordering is DegRevLex
/**/  LT(y^2-x*z);
y^2

/**/  Use R ::= QQ[x,y,z], Lex;
/**/  LT(y^2-x*z);
x*z
</example>
If <tt>E</tt> is a MODULEELEM, <tt>LT(E)</tt> gives the leading term
of <tt>E</tt> with respect to the module term-ordering of <tt>E</tt>.
For the leading monomial, which includes the coefficient, use <ttref>LM</ttref>.
<example>
/**/  R3 := NewFreeModule(R,3);
/**/  LT(ModuleElem(R3, [0, x, y^2]));
[0, 0, y^2]

  Use R ::= QQ[x,y], PosTo;
  V := Vector(0, x, y^2);
  LT(V); -- the leading term of V w.r.t. PosTo
Vector(0, x, 0)
-------------------------------
</example>
If <tt>E</tt> is an ideal or module, <tt>LT(E)</tt> returns the ideal or module
generated by the leading terms of all elements of E, sometimes called
the <em>initial</em> ideal or module.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x-y, x-z^2);
/**/  LT(I);
ideal(x, z^2)
</example>
</description>

<seealso>
  <see>LC</see>
  <see>LF</see>
  <see>LM</see>
  <see>LPP</see>
  <see>Module Orderings</see>
  <see>Orderings</see>
</seealso>

<keys>
  <key>leading term</key>
  <key>initial term</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>M</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MakeCheck</title>
  <short_description>run a series of tests</short_description>

<syntax>
MakeCheck()
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function run a series of tests on the whole system.  To get a
reliable result you should run this on a <em>just opened</em> CoCoA
because some printouts may mysteriously add some empty spaces which
will result in an, apparent, failure of some tests.
<example>
  MakeCheck();
</example>

</description>


<keys>
  <key>tests</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MakeMatByRows, MakeMatByCols</title>
  <short_description>convert a list into a matrix</short_description>

<syntax>
MakeMatByRows(R: <type>INT</type>, C: <type>INT</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
MakeMatByCols(R: <type>INT</type>, C: <type>INT</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
These functions convert the list L into a matrix.
The first argument is the number of rows and the second the number of columns.

<example>
/**/  MakeMatByRows(2, 10, 1..20);
matrix([
  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
])

/**/  MakeMatByCols(2, 10, 1..20);
matrix([
  [1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
  [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
])
</example>
</description>


<seealso>
  <see>BlockMat</see>
  <see>matrix</see>
  <see>NewMat</see>
  <see>ColMat</see>
  <see>RowMat</see>
  <see>DiagMat</see>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
</seealso>
<keys>
  <key>rows</key>
  <key>cols</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MakeSet</title>
  <short_description>remove duplicates from a list</short_description>

<syntax>
MakeSet(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns a list obtained by removing duplicates from <tt>L</tt>.
<example>
/**/  MakeSet([2,2,2,1,2,1,1,3,3]);
[2, 1, 3]
</example>
NOTE: to test two sets for equality use the function <ttref>EqSet</ttref>
instead of a normal equality test (because the latter yields false if the
elements are in a different order).
</description>

<seealso>
  <see>EqSet</see>
  <see>intersection</see>
  <see>IntersectList</see>
  <see>remove</see>
</seealso>
<keys>
  <key>duplicates</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MantissaAndExponent10</title>
  <short_description>convert rational number to a float</short_description>


<syntax>
MantissaAndExponent10(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, Prec: <type>INT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function converts a rational number into a <tt>RECORD</tt> with components
named <tt>exponent</tt>, <tt>mantissa</tt> and <tt>NumDigits</tt>.
<par/>
If <tt>X=0</tt>, all fields of the record are set to zero.
<par/>
For non-zero <tt>X</tt> the fields give the best representation of the form <formula>M*10^E</formula>
where <tt>M</tt> has <tt>Prec</tt> decimal digits.
The value of <tt>NumDigits</tt> is simply <tt>Prec</tt>.
The value of <tt>exponent</tt> is <tt>ILogBase(X,10)</tt>, plus 1 if the mantissa "overflows".
The value of <tt>mantissa</tt> is an integer <tt>M</tt> satisfying <formula>10^(Prec-1) <less_eq/> |M| &lt; 10^Prec-1</formula>
<example>
/**/  MantissaAndExponent10(1/2,3);       --  1/2 = 5.00*10^(-1)
record[NumDigits := 3, exponent := -1, mantissa := 500]

/**/  MantissaAndExponent10(0.99999, 4);   --  0.99999 rounds up to give 1.000
record[NumDigits := 4, exponent := 0, mantissa := 1000]
</example>
</description>

<seealso>
  <see>DecimalStr</see>
  <see>FloatApprox</see>
  <see>FloatStr</see>
  <see>ILogBase</see>
  <see>MantissaAndExponent2</see>
  <see>ScientificStr</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MantissaAndExponent2</title>
  <short_description>convert rational number to a binary float</short_description>


<syntax>
MantissaAndExponent2(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, Prec: <type>INT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function converts a rational number into a <tt>RECORD</tt> with components
named <tt>exponent</tt>, <tt>mantissa</tt> and <tt>NumDigits</tt>.
<par/>
If <tt>X=0</tt>, all fields of the record are set to zero.
<par/>
For non-zero <tt>X</tt> the fields give the best representation of the form <formula>M*2^E</formula>
where <tt>M</tt> has <tt>Prec</tt> bits.
The value of <tt>NumDigits</tt> is simply <tt>Prec</tt>.
The value of <tt>exponent</tt> is <tt>ILogBase(X,2)</tt>, plus 1 if the mantissa "overflows".
The value of <tt>mantissa</tt> is an integer <tt>M</tt> satisfying <formula>2^(Prec-1) <less_eq/> |M| &lt; 2^Prec-1</formula>
<example>
/**/  MantissaAndExponent2(1/2,8);       --  1/2 = 128*2^(-8)
record[NumDigits := 8, exponent := -1, mantissa := 128]

/**/  MantissaAndExponent2(65535, 10);   --  rounds up
record[NumDigits := 10, exponent := 16, mantissa := 512]
</example>
</description>

<seealso>
  <see>FloatApprox</see>
  <see>ILogBase</see>
  <see>MantissaAndExponent10</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Manual</title>
  <short_description>search online help system</short_description>

<syntax>
? key
?? key
</syntax>
<description>
These operators are used to search the online help system for
information matching a keyword (introduced in CoCoA 4.2).
<par/>
The commands have the form <tt>?key</tt> and <tt>??key</tt>
where <em>key</em> is a literal string without quotes.
They are case insensitive and ignore blank space before or after <em>key</em>.
Also, the semicolon usually required at the end of a line of CoCoA input
is optional.
<par/>
The search system is fairly simple.  The searching algorithm looks through
the title and keywords of each manual page.  A page matches if <em>key</em>
appears as a (case-insensitive) substring of the title/keywords.
<par/>
The <tt>??</tt> form prints the list of all matches.
The <tt>?</tt> form prints the page matching exactly if there is one,
otherwise the list of all matches.
<par/>
<example>
/**/ ?approxs
--============[ ApproxSolve ]=============--
--> ApproxSolve(L: LIST of RINGELEM): LIST of LIST of RAT

This function returns the list of real solutions (points) of a
   --( Further output )--

--====&lt;  No entry for "approx" >====--
All 8 matches for "approx":
 ? ApproxSolve
 ? CFApprox
   --( Further output )--
</example>

</description>

<keys>
  <key>?</key>
  <key>??</key>
  <key>help</key>
  <key>online help</key>
</keys>
 
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MapDown [OBSOLETE]</title>
  <short_description>[OBSOLETE] convert a constant polynomial to a number</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
See <ttref>AsINT</ttref>, <ttref>AsRAT</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>matrix</title>
  <short_description>convert a list into a matrix</short_description>
<syntax>
matrix(L: <type>LIST</type>): <rtn>MAT</rtn>
matrix(R: <type>RING</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
matrix(R: <type>RING</type>, M: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns a matrix in the ring <tt>R</tt>.
<par/>
When the input is <tt>L</tt>, a <em>rectangular</em> LIST of LIST of
RINGELEM all in <tt>R</tt> (or INT, or RAT).
When the ring is not specified it <quotes>guesses</quotes> the right
ring; if all elements are INT or RAT the resulting matrix is in QQ.
<par/>
The third form is equivalent to <tt>apply(CanonicalHom(RingOf(M),R), M)</tt>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  L := [[1,2],[3,4]];
/**/  mat(L);
matrix(QQ,
 [[1, 2],
  [3, 4]])
/**/  mat(R,L);
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[1, 2],
  [3, 4]])
/**/  mat(ZZ,L);
matrix(ZZ,
 [[1, 2],
  [3, 4]])

/**/  RingOf(mat(R, [[1,2],[3,4]]));
RingDistrMPolyClean(QQ, 2)

/**/ M := IdentityMat(ZZ,2);   matrix(QQ, M);
matrix(QQ,
 [[1, 0],
  [0, 1]])
</example>
</description>
<seealso>
  <see>NewMat</see>
  <see>ColMat</see>
  <see>RowMat</see>
  <see>DiagMat</see>
  <see>MakeMatByRows, MakeMatByCols</see>
  <see>ConcatHor</see>
  <see>ConcatVer</see>
  <see>BlockMat</see>
  <see>apply</see>
  <see>CanonicalHom</see>
</seealso>
<keys>
  <key>Mat</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>max</title>
  <short_description>a maximum element of a sequence or list</short_description>
<syntax>
max(E_1: <type>OBJECT</type>,...,E_n: <type>OBJECT</type>): <rtn>OBJECT</rtn>
max(L: <type>LIST</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
In the first form, this function returns a maximum of <formula>E_1,...,E_n</formula>.
In the second form, it returns a maximum of the objects in the list <tt>L</tt>.
<example>
/**/  max([1,2,3]);
3
/**/  max(1,2,3);
3

/**/  use R ::= QQ[x,y,z];
/**/  max(x^3*z, x^2*y^2); -- x^2y^2 > x^3z in the default ordering, DegRevLex
x^2*y^2
/**/  min(x^3*z, x^2*y^2);
x^3*z

/**/  use R ::= QQ[x,y,z], DegLex;
/**/  max(x^3*z, x^2*y^2); -- x^3z &lt; x^2y^2 in DegLex
x^3*z
</example>
</description>
<seealso>
  <see>min</see>
  <see>Relational Operators</see>
</seealso>
<types>
  <type>INT</type>
  <type>RAT</type>
  <type>RINGELEM</type>
  <type>STRING</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MayerVietorisTreeN1</title>
  <short_description>N-1st Betti multidegrees of monomial ideals using Mayer-Vietoris trees</short_description>
<syntax>
MayerVietorisTreeN1(I: <type>IDEAL</type>): <rtn>INT</rtn>
</syntax>
<description>
Thanks to Eduardo Saenz-de-Cabezon.
<par/>
This function returns the list of multidegrees <tt>M</tt> such that the N-1st
Betti number of a monomial ideal <tt>I</tt> at multidegree <tt>M</tt> is not zero.
It is computed via a version of its Mayer-Vietoris tree.
<par/>
The length of this list is the number of irreducible components of I,
the number of maximal standard monomials, and the number of generators
of its Alexander Dual.
<example>
/**/  Use QQ[x,y,z];
/**/  I := ideal(x, y, z)^2;
/**/  MayerVietorisTreeN1(I);
[x^2*y*z, x*y^2*z, x*y*z^2]
</example>
</description>
<seealso>
  <see>Frobby</see>
</seealso>
<keys>
  <key>mvt</key>
  <key>author: eduardo saenz-de-cabezon</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>min</title>
  <short_description>a minimum element of a sequence or list</short_description>
<syntax>
min(E_1: <type>OBJECT</type>,...,E_n: <type>OBJECT</type>): <rtn>OBJECT</rtn>
min(L: <type>LIST</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
In the first form, this function returns a minimum of <formula>E_1,...,E_n</formula>.
In the second form, it returns a minimum of the objects in the list <tt>L</tt>.
<par/>
See more examples in <ttref>max</ttref>.
<example>
/**/  min([1,2,3]);
1
/**/  min(1,2,3);
1
</example>
</description>

<seealso>
  <see>max</see>
  <see>Relational Operators</see>
</seealso>

<types>
  <type>INT</type>
  <type>RAT</type>
  <type>STRING</type>
  <type>RINGELEM</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MinGens</title>
  <short_description>list of minimal generators</short_description>
  
<syntax>
MinGens(M: <type>IDEAL</type>|<type>MODULE</type>): <rtn>LIST</rtn>
</syntax>
<description>
If M is a homogeneous ideal or module, this function returns a list of
minimal generators for M.
<par/>
The coefficient ring must be a field.
<par/>
For non-homogeneous input use <ttref>MinGensGeneral</ttref>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x-y, (x-y)^4, z+y, (z+y)^2);
/**/  MinGens(I);
[y + z, x + z]

/**/  R3 := NewFreeModule(R, 3);
/**/  MGens := matrix(R, [[x,y,z], [x^2,0,z^2], [2*x^2,x*y,z^2+x*z]]);
/**/  M := SubmoduleRows(R3, MGens);
/**/  gens(M);
[[x, y, z], [x^2, 0, z^2], [2*x^2, x*y, x*z +z^2]]
/**/  MinGens(M);
[[x, y, z], [0, x*y, x*z -z^2]]
</example>
</description>

<seealso>
  <see>minimalize</see>
  <see>minimalized</see>
</seealso>

<types>
  <type>groebner</type>
  <type>groebner-basic</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MinGensGeneral</title>
  <short_description>list of minimal generators</short_description>
  
<syntax>
MinGensGeneral(M: <type>IDEAL</type>|<type>MODULE</type>): <rtn>LIST</rtn>
</syntax>
<description>
If <tt>M</tt> is a homogeneous ideal or module, use <ttref>MinGens</ttref>.
<par/>
Otherwise this function returns a list of generators for <tt>M</tt>
minimal in the sense that none can be generated by the others.
There is no optimal algorithm of theoretical guarantee when input is
not homogeneous.
<par/>
The coefficient ring must be a field.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x-1, (x-y)^4, z+y, (z+y)^2);
/**/  MinGensGeneral(I);
[x -1, x^4 -4*x^3*y +6*x^2*y^2 -4*x*y^3 +y^4, y +z]
</example>
</description>

<seealso>
  <see>minimalize</see>
  <see>minimalized</see>
</seealso>

<types>
  <type>groebner</type>
  <type>groebner-basic</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>minimalize</title>
  <short_description>remove redundant generators</short_description>
<syntax>
minimalize(ref X: <type>IDEAL</type>)
minimalize(ref X: <type>MODULE</type>)
</syntax>
<description>
Similar to <ttref>minimalized</ttref>, but modifies the
argument <tt>X</tt> and returns NULL.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x^2-y^2, z^4-y^4, x^2-z^2);
/**/  I;
ideal(x^2 -y^2, -y^4 +z^4, x^2 -z^2)
/**/  minimalize(ref I); -- returns NULL and modifies I
/**/  I;
ideal(x^2 -z^2, y^2 -z^2)
</example>
</description>
<seealso>
  <see>MinGens</see>
  <see>minimalized</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>minimalized</title>
  <short_description>ideal, submodule with minimal generators</short_description>
<syntax>
minimalized(E: <type>IDEAL</type>): <rtn>IDEAL</rtn>
minimalized(E: <type>MODULE</type>): <rtn>MODULE</rtn>
</syntax>
<description>
It works only in the homogeneous case: it returns the ideal or module
generated by a set of minimal generators of E (with minimal cardinality).
The minimal set of generators is not necessarily a subset of the given
generators.
<par/>
In the inhomogeneous case use <ttref>MinGensGeneral</ttref>.
<par/>
The coefficient ring is assumed to be a field.
<par/>
The similar function <ttref>minimalize</ttref> performs the same
operation, but modifies the argument (<ttref>ref</ttref>) and returns NULL.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x^2-y^2, z^4-y^4, x^2-z^2);
/**/  I;
ideal(x^2 -y^2, -y^4 +z^4, x^2 -z^2)
/**/  minimalized(I);
ideal(x^2 -z^2, y^2 -z^2)
/**/  I; -- not modified
ideal(x^2 -y^2, -y^4 +z^4, x^2 -z^2)
</example>
</description>
<seealso>
  <see>MinGens</see>
  <see>minimalize</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MinimalPresentation</title>
  <short_description>minimal presentation for a quotient</short_description>

<syntax>
MinimalPresentation(Q:TAGGED):TAGGED

where Q is a quotient module of the type R^s/M
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
Given a quotient module of the type <formula>R<sup>s</sup>/M</formula>,
or a zero module, this function computes an isomorphic quotient,
<formula>R<sup>t</sup>/N</formula>, minimally presented
[using the algortihm in Kreuzer-Robbiano II].

<example>
  Use R ::= QQ[x,y,z];
  MinimalPresentation(R^3/Module([[x,1,1], [x,2,2]]));
R^2/Module([[x, 0]])
-------------------------------
</example>
</description>

<keys>
  <key>minimal presentation</key>
  <key>author: damiano</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>minors</title>
  <short_description>list of minor determinants of a matrix</short_description>

<syntax>
minors(M: <type>MAT</type>, N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of all determinants of N x N
submatrices of M.

<example>
/**/  M := mat([[1,2,3],[-1,2,4]]);
/**/  minors(M, 2);
[4, 7, 2]
</example>
</description>


<seealso>
  <see>det</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MinPoly</title>
  <short_description>minimal polynomial of a matrix</short_description>
<syntax>
MinPoly(M: <type>MAT</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
Thanks to Maria-Laura Torrente.
<par/>
This function returns the minimal polynomial of the matrix <tt>M</tt> in the
indeterminate <tt>X</tt> (with <tt>M</tt> a square matrix whose entries lie
in the coefficient ring of <tt>X</tt>, or in the same ring of <tt>X</tt> but not
dependent on <tt>X</tt>).
See also <ttref>CharPoly</ttref>.
<example>
/**/  Use R ::= QQ[x];
/**/  MinPoly(matrix([[0,0,1],[0,0,0],[0,0,0]]), x);
x^2
/**/  CharPoly(matrix([[0,0,1],[0,0,0],[0,0,0]]), x);
x^3
</example>
</description>

<seealso>
  <see>CharPoly</see>
</seealso>
<keys>
  <key>minimal polynomial</key>
  <key>author: maria-laura torrente</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MinPowerInIdeal</title>
  <short_description>the mininum power of a polynomial is an ideal</short_description>

<syntax>
MinPowerInIdeal(F: <type>RINGELEM</type>, I: <type>IDEAL</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the minimum power of F, the first argument, in
the ideal I, the second argument.
If F is not in the radical I then -1 is returned.

<example>
/**/  Use QQ[x,y,z];
/**/  I := ideal(x^6*y^4, z);
/**/  IsInRadical(x*y, I);
true

/**/  MinPowerInIdeal(x*y, I);
6
</example>
</description>


<seealso>
  <see>IsInRadical</see>
  <see>radical</see>
</seealso>

<keys>
  <key>radical membership</key>
</keys>
</command>
<!-- ===  COMMAND-rm MinSyzMinGens ========================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>mod</title>
  <short_description>remainder for integers</short_description>

<syntax>
mod(N: <type>INT</type>, D: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
We define the quotient <tt>Q</tt> and remainder <tt>R</tt> to be integers which
satisfy <formula>N = Q*D + R</formula> with <formula>0 <less_eq/> R &lt; |D|</formula>.
Then <tt>div(N, D)</tt> returns <tt>Q</tt> while <tt>mod(N, D)</tt> returns <tt>R</tt>.
<par/>
NOTE: To perform the division algorithm on a polynomial, use
<ttref>NR</ttref> (normal remainder) to find the remainder, or
<ttref>DivAlg</ttref> to get both the quotients and the remainder.

<example>
/**/  div(10,3);
3

/**/  mod(10,3);
1
</example>
</description>


<seealso>
  <see>div</see>
  <see>DivAlg</see>
  <see>GenRepr</see>
  <see>NF</see>
  <see>NR</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Mod2Rat [OBSOLETE]</title>
  <short_description>[OBSOLETE] reconstruct rationals from modular integers</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
See <ttref>RatReconstructWithBounds</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ModuleElem</title>
  <short_description>create a module element</short_description>

<syntax>
ModuleElem(M: <type>MODULE</type>, L: <type>LIST</type>): <rtn>MODULEELEM</rtn>
</syntax>
<description>
This function returns the MODULEELEM (called <tt>Vector</tt> in CoCoA-4)
in the module <tt>M</tt> whose components are the components of the list L.
<example>
/**/  Use R ::= QQ[x];
/**/  R3 := NewFreeModule(R,3);
/**/  V := ModuleElem(R3, [1, x, x^2]);  V;
[1, x, x^2]
/**/  type(V);
MODULEELEM
/**/  zero(R3);
[0, 0, 0]
</example>
</description>   
<seealso>
  <see>SubmoduleCols, SubmoduleRows</see>
</seealso>
<keys>
  <key>vector</key>
  <key>module element</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ModuleOf</title>
  <short_description>the module environment of the object</short_description>

<syntax>
ModuleOf(M: <type>MODULE</type>): <rtn>MODULE</rtn>
</syntax>
<description>
This function returns the module on which the object E is defined.
<par/>
NB A module contains many information and two separate rings, even when
defined with the same commands, are not <quotes>equal</quotes>.
When a module is printed only a few informations are shown, so different
modules might look the same.

<example>
/**/  Use R ::= QQ[x];
/**/  R3 := NewFreeModule(R,3);
/**/  V := ModuleElem(R3, [1, x, x^2]);  V;
[1, x, x^2]
/**/  type(V);
MODULEELEM
/**/  ModuleOf(V) = R3;
true
/**/  ModuleOf(V);
FreeModule(RingDistrMPolyClean(QQ, 1), 3)
</example>
</description>

<keys>
  <key>vector</key>
  <key>module element</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>monic</title>
  <short_description>divide polynomials by their leading coefficients</short_description>

<syntax>
monic(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns <tt>F</tt> divided by its leading coefficient (see <ttref>LC</ttref>) or,
if <tt>F</tt> is zero, it returns just zero.

<example>
/**/  Use R ::= QQ[x,y];
/**/  F := 4*x^5-y^2;
/**/  monic(F);
x^5 +(-1/4)*y^2

/**/  Use R ::= ZZ[x,y];
/**/  F := 4*x^5-y^2;
-- /**/  monic(F);  --> !!! ERROR !!! can&apos;t invert coefficients over ZZ
ERROR: Inexact division
monic(L);  -- can't invert coefficient ...
^^^^^^^^

/**/  Use P ::= ZZ/(5)[x,y];
/**/  F := 2*x^2+4*y^3;
/**/  monic(F);
y^3 -2*x^2
</example>
</description>

<seealso>
  <see>LC</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>monomials</title>
  <short_description>the list of monomials of a polynomial</short_description>

<syntax>
monomials(F: <type>RINGELEM</type>|<type>MODULEELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of monomials of F.
The function <ttref>support</ttref> returns the list of terms
(monomials without coefficients).
<example>
/**/  Use R ::= QQ[x,y];
/**/  F := 3*x^2*y +5*y^3 -x*y^5;
/**/  monomials(F);
[-x*y^5, 3*x^2*y, 5*y^3]

/**/  support(F);
[x*y^5, x^2*y, y^3]

  Monomials(Vector(3*x^2*y+y,5*x*y+4)); --***WORK IN PROGRESS***
[Vector(3x^2y, 0), Vector(0, 5xy), Vector(y, 0), Vector(0, 4)]
</example>
</description>
<seealso>
  <see>coefficients</see>
  <see>support</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>MonsInIdeal</title>
  <short_description>ideal generated by the monomials in an ideal</short_description>

<syntax>
MonsInIdeal(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function returns the ideal generated by all monomials in the
original ideal I.

<example>
  Use R ::= QQ[x,y,z];
  I := ideal(xy^3+z^2, y^5-z^3, xz-y^2-x^3, x^4-xz^2+y^3);
  MonsInIdeal(I);
ideal(z^3, yz^2, x^2z^2, x^5z, x^4yz, x^5y, x^2y^2z, x^7, x^4y^2,
      xy^3z, y^4z, xy^4, x^3y^3, y^5)
-------------------------------
</example>
</description>


</command>
<!-- ===  COMMAND-rm More =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>multiplicity</title>
  <short_description>the multiplicity (degree) of a ring or quotient object</short_description>
<syntax>
multiplicity(R: <type>RING</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the multiplicity (or degree) of M,
i.e., the leading coefficient of the Hilbert polynomial multiplied by
the factorial of the degree of the Hilbert polynomial.
M can be a module or a quotient.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  multiplicity(R/ideal(x,y,z)^5);
35
</example>
</description>
<seealso>
  <see>HilbertFn</see>
  <see>HilbertSeries</see>
  <see>HVector</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>author: anna maria bigatti</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>N</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewFractionField</title>
  <short_description>create a new fraction field</short_description>
<syntax>
NewFractionField(R: <type>RING</type>): <rtn>RING</rtn>
</syntax>
<description>
NOTE: calling twice <tt>NewFractionField</tt> will produce
two different rings, even with identical input: equality test is
performed on the pointers.  See <ttref>ID</ttref>.
<example>
/**/  K := NewFractionField(NewPolyRing(QQ, ["a","b"]));
/**/  Use K;
/**/  M := mat([[1,2,3,a],[5,6,7,a*b]]);
/**/  LinKerBasis(M);
[[-1, 2, -1, 0], [(a*b -3*a)/2, (-a*b +5*a)/4, 0, -1]]
</example>
</description>
<seealso>
  <see>NewQuotientRing</see>
  <see>ID</see>
  <see>den</see>
  <see>num</see>
</seealso>
<keys>
  <key>rational functions</key>
  <key>RATFUN</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewFreeModule</title>
  <short_description>create a new FreeModule</short_description>

<syntax>
NewFreeModule(R: <type>RING</type>, N: <type>INT</type>): <rtn>MODULE</rtn>
NewFreeModule(R: <type>RING</type>, Shifts: <type>MAT</type>): <rtn>MODULE</rtn>
</syntax>
<description>
This function returns a free module which can be used as any
programming variable.
<par/>
NOTE: as for rings, calling twice <tt>NewFreeModule</tt> will produce
two different modules, even with identical input: equality test is
performed on the pointers.
<par/>
This function does accept shifts from version CoCoA-5.0.4.
<example>
/**/  F := NewFreeModule(R, 3);
/**/  zero(F);
[0, 0, 0]
/**/ type(zero(F));  -- is NOT a LIST
MODULEELEM
/**/ gens(F);
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]

/**/ F := NewFreeModule(R, matrix([[1],[2],[3]])); -- shifts
/**/ [wdeg(e) | e in gens(F)];
[[1], [2], [3]]
</example>
</description>
<seealso>
  <see>BaseRing</see>
  <see>RingOf</see>
</seealso>
<keys>
  <key>shifts</key>
</keys>
<types>
  <type>io</type>
  <type>printing</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewId [OBSOLETE]</title>
  <short_description>[OBSOLETE] create a new identifier</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewLine [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] string containing a newline</short_description>

<syntax>
NewLine(): <rtn>STRING</rtn> 
</syntax>
<description>
This function is <em>OBSOLESCENT</em> and exists only for backward
compatibility with old CoCoA code.
It returns a string containing just a newline; in CoCoA-5 it is
simpler to write <tt>\n</tt>.
<example>
/**/  str1 := "Line 1" + NewLine() + "Line 2"; --> old CoCoA-4 way
/**/  str2 := "Line 1\nLine 2";                --> more compact in CoCoA-5
/**/  str1 = str2;
True
/**/ Print str2;
Line 1
Line2
</example>
</description>
<seealso>
  <see>String Literals</see>
  <see>println</see>
  <see>ascii</see>
</seealso>
<types>
  <type>io</type>
  <type>printing</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewList</title>
  <short_description>create a new list</short_description>


<syntax>
NewList(N: <type>INT</type>): <rtn>LIST</rtn>
NewList(N: <type>INT</type>, E: <type>OBJECT</type>): <rtn>LIST</rtn>
</syntax>
<description>
The first form returns a list of length <tt>N</tt> filled with 0 (<tt>INT</tt>).
The second form returns a list of length <tt>N</tt>, filled with copies of <tt>E</tt>.

<example>
/**/  NewList(4,"a");
["a", "a", "a", "a"]

/**/  NewList(4);
[0, 0, 0, 0]
</example>
</description>

<seealso>
  <see>List Constructors</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewMat</title>
  <short_description>Zero matrix</short_description>
  
<syntax>
NewMat(R: <type>RING</type>, M: <type>INT</type>, N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function is kept for CoCoA-4 nostalgia: better use <ttref>ZeroMat</ttref>.
<example>
/**/  Use S ::= QQ[x,y,z];
/**/  NewMat(S,2,3);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[0, 0, 0],
  [0, 0, 0]])
/**/  ZeroMat(S,2,3);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[0, 0, 0],
  [0, 0, 0]])
</example>
</description>

<seealso>
  <see>matrix</see>
  <see>NewMatFilled</see>
</seealso>


</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewMatFilled</title>
  <short_description>matrix filled with value</short_description>
  
<syntax>
NewMatFilled(M: <type>INT</type>, N: <type>INT</type>, Val: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns an <tt>MxN</tt> matrix, filled with <tt>Val</tt>.
If <tt>Val</tt> is an integer or rational the ring of the matrix is
defined in <ttref>RingQQ</ttref>.
<example>
/**/  Use S ::= QQ[x,y,z];
/**/  NewMatFilled(1,3,x);
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[x, x, x]])

/**/  NewMatFilled(1,3, 0);
matrix(QQ,
 [[0, 0, 0]])
/**/  ZeroMat(QQ, 1, 3); --> same as NewMatFilled(1,3, 0)
matrix(QQ,
 [[0, 0, 0]])
</example>
</description>

<seealso>
  <see>NewMat</see>
  <see>matrix</see>
</seealso>


</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewPolyRing</title>
  <short_description>create a new PolyRing</short_description>

<syntax>
NewPolyRing(CoeffRing: <type>RING</type>, IndetNames: <type>LIST</type>: <rtn>RING</rtn>
NewPolyRing(CoeffRing: <type>RING</type>, IndetNames: <type>LIST</type>, OrdMat: <type>MAT</type>, GradingDim: <type>INT</type>: <rtn>RING</rtn>
</syntax>
<description>
This function returns a polynomial ring which can be used as any
programming variable (assigned with <tt>:=</tt>).
<par/>
The <tt>::=</tt> syntax starts the input method for a new polynomial ring,
with the special interpretation of brackets and symbols
(i.e. R ::= QQ[x] is not read as X := LL[i]).
The pre-defined orderings for the <tt>::=</tt> syntax are
<tt>Lex</tt> (no grading), <tt>DegLex</tt>, <tt>DegRevLex</tt> (standard grading).
For more orderings use the <tt>NewPolyRing</tt> function call
(see also <ttref>ElimMat</ttref>).
<par/>
NB: calling <tt>NewPolyRing</tt> twice with the same arguments gives
two <em>different rings</em>, therefore incompatible.  See <ttref>ID</ttref>.
<example>
/**/  R ::= QQ[x,y,alpha]; -- is equivalent to
/**/  R := NewPolyRing(RingQQ(), ["x","y","alpha"]);

/**/  R ::= QQ[x,y], DegRevLex; -- is equivalent to
/**/  R := NewPolyRing(RingQQ(), ["x","y"], StdDegRevLexMat(2), 1);

/**/  OrdM := matrix([[2,3],[1,0]]);
/**/  P := NewPolyRing(QQ, ["x","y"], OrdM, 1);
/**/  GradingDim(P);
1
/**/  P2 := NewPolyRing(RingZZ(), IndetSymbols(P));
/**/  Indets(P2);
[x, y]
/**/  P3 := NewPolyRing(P2, SymbolRange("alpha", 0,2));
/**/  indets(P3);
[alpha[0], alpha[1], alpha[2]]
</example>
</description>
<seealso>
  <see>ElimMat</see>
  <see>ID</see>
  <see>IndetSymbols</see>
  <see>SymbolRange</see>
  <see>GradingDim</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewQuotientRing</title>
  <short_description>create a new quotient ring</short_description>
  
<syntax>
NewQuotientRing(R: <type>RING</type>, I: <type>IDEAL</type>): <rtn>RING</rtn>
R/I
</syntax>
<description>
NOTE: calling twice <tt>NewQuotientRing</tt> will produce
two different rings, even with identical input: equality test is
performed on the pointers.  See <ttref>ID</ttref>.
<example>
/**/  Use Qi ::= QQ[i];
/**/  CC := Qi/ideal(i^2+1);  -- sort of  ;-)
/**/  Use CC[x];
/**/  (x+i)^2;
(2*i*x +x^2 -1)

/**/  R ::= QQ[x,y,z];
/**/  S := NewQuotientRing(R, ideal(indet(R,1)-3));
/**/  Use S;
/**/  (x+y)^2;
(y^2 +6*y +9)
</example>
</description>
<seealso>
  <see>ID</see>
  <see>QuotientBasis</see>
  <see>NewFractionField</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewRingFp</title>
  <short_description>create a new finite field</short_description>
<syntax>
NewRingFp(P: <type>INT</type>): <rtn>RING</rtn>
</syntax>
<description>
Create a new small prime finite field with characteristic <tt>P</tt>.
<par/>
Note: in ring definitions you can use the convenient notation <tt>ZZ/(p)</tt>
<par/>
NOTE: calling twice <tt>NewRingFp</tt> will produce
two different rings, even with identical input: equality test is
performed on the pointers.  See <ttref>ID</ttref>.
<example>
/**/ p := NextPrime(1000);
/**/ Fp := NewRingFp(p);
/**/ Use Fp[x];
/**/ product([x-i | i in 1..p]);
x^1009 - x
/**/ Use ZZ/(p)[x]; --> convenient shorthand in ring defn
/**/ product([x-i | i in 1..p]);
x^1009 - x
</example>
</description>
<seealso>
  <see>ID</see>
  <see>NewQuotientRing</see>
</seealso>
<keys>
  <key>finite field</key>
  <key>galois field</key>
  <key>Fp</key>
  <key>FFp</key>
  <key>NewZZMod</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NewRingTwinFloat</title>
  <short_description>create a new twin-float ring</short_description>
<syntax>
NewRingTwinFloat(Prec: <type>INT</type>): <rtn>RING</rtn>
</syntax>
<description>
Create a new twin-float ring with bit precision <tt>Prec</tt>.
<par/>
NOTE: calling twice <tt>NewRingTwinFloat</tt> will produce
two different rings, even with identical input: equality test is
performed on the pointers.  See <ttref>ID</ttref>.
<!--NOTE: this interface is preliminary, and may change.-->
<par/>
For more information see the article:
John Abbott, <quotes>Twin-float arithmetic</quotes>,
Journal of Symbolic Computation,
Volume 47 (2012), 536--551.
<example>
/**/ RR32 := NewRingTwinFloat(32);
/**/ Use RR32[x];
/**/ (3*x-1)/3;
x -0.3333333333333333333

/**/ RR64 := NewRingTwinFloat(64);
/**/ Use RR64[x];
/**/ (3*x-1)/3;
x -0.333333333333333333333333333333333333333
</example>
</description>
<seealso>
  <see>AsRAT</see>
  <see>ID</see>
</seealso>
<keys>
  <key>floating-point</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NextPrime</title>
  <short_description>find the next largest prime number</short_description>

<syntax>
NextPrime(N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the smallest prime number greater than <code>N</code>.  If
<code>N</code> is negative or too large then an error is signalled.  The upper
limit depends on the computer you are using; it is probably <formula>2^31</formula>
or <formula>2^63</formula>.

<example>
/**/  NextPrime(1000);
1009
</example>
</description>


<seealso>
  <see>IsPrime</see>
  <see>NextProbPrime</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NextProbPrime</title>
  <short_description>find the next largest probable prime number</short_description>

<syntax>
NextProbPrime(N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the smallest probable prime number greater than <code>N</code>.  If
<code>N</code> is negative, an error is generated.  To be absolutely certain the number
produced is prime, you must call <code>IsPrime</code> on it, but this may be very costly.

<example>
/**/  NextProbPrime(1000);
1009

/**/  NextProbPrime(10^50);
100000000000000000000000000000000000000000000000151
</example>
</description>


<seealso>
  <see>IsPrime</see>
  <see>IsProbPrime</see>
  <see>NextPrime</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NF</title>
  <short_description>normal form</short_description>

<syntax>
NF(F: <type>RINGELEM</type>, I: <type>IDEAL</type>): <rtn>RINGELEM</rtn>
NF(V: <type>MODULEELEM</type>, M: <type>MODULE</type>): <rtn>MODULEELEM</rtn>
</syntax>
<description>
The first function returns the normal form of F with respect to I.
It also computes a Groebner basis of I if that basis has not been
computed previously.
<par/>
The second function returns the normal form of V with respect to M. It
also computes a Groebner basis of M if that basis has not been
computed previously.
<par/>
Currently (v 5.0.3) only full reduction is computed: each monomial in
the result cannot be reduced.  CoCoA-4 allowed setting the flag
FullRed (of the panel GROEBNER) to False so that only the leading term
is reduced.
<par/>
Currently (v 5.0.3) polynomial ideals are implemented only with coeffs
in a field.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(z);
/**/  NF(x^2+x*y+x*z+y^2+y*z+z^2, I);
x^2 +x*y +y^2

/**/  I := ideal(z-1);
/**/  NF(x^2+x*y+x*z+y^2+y*z+z^2, I);
x^2 +x*y +y^2 +x +y +1
</example>
</description>


<seealso>
  <see>DivAlg</see>
  <see>GenRepr</see>
  <see>IsIn</see>
  <see>NR</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>normal form</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NFsAreZero [OBSOLETE]</title>
  <short_description>[OBSOLETE]test if normal forms are zero</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
<tt>NFsAreZero(L, I)</tt> is the same as <tt>IsContained(ideal(L), I)</tt>.
</description>
<seealso>
  <see>IsContained</see>
  <see>IsIn</see>
  <see>NF</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzComputation</title>
  <short_description>flexible access to Normaliz</short_description>
  
<syntax>
NmzComputation(Cone: <type>RECORD</type>): <rtn>RECORD</rtn>
NmzComputation(Cone: <type>RECORD</type>, ToCompute: <type>LIST</type>): <rtn>RECORD</rtn>
</syntax>
<description>
<tt>NmzComputation</tt> provides direct access to libnormaliz.  It faithfully
reflects the internal structure of the libnormaliz design.  Its first argument
should be a record representing the cone.  For the possible input options see
the Normaliz documentation.  With the second (optional) argument one can
specify what should be computed.  If it is omitted, everything that can be
computed by libnormaliz will be computed.
<example>
/**/ Cone := Record[ integral_closure := Mat([[1,2],[2,1]]),
/**/                 grading := Mat([[2,1]])];
/**/ NC2 := NmzComputation(Cone, ["HilbertBasis", "SupportHyperplanes", "HilbertSeries"]);
/**/ indent(NC2);

Record[
  Congruences := [],
  Deg1Elements := [],
  EmbeddingDim := 2,
  Equations := [],
  ExtremeRays := [[1, 2], [2, 1]],
  Generators := [[1, 2], [2, 1]],
  Grading := [2, 1],
  HilbertBasis := [[1, 1], [1, 2], [2, 1]],
  HilbertSeries := record[DenFactors := record[RemainingFactor := 1, factors := [-t +1, -t^20 +1], multiplicities := [1, 1]], num := t^18 -t^17 +t^15 +t^10 -t^9 +t^8 +t^3 -t +1],
  IsDeg1HilbertBasis := false,
  IsInhomogeneous := false,
  IsIntegrallyClosed := false,
  IsPointed := true,
  Multiplicity := 3/20,
  Rank := 2,
  SupportHyperplanes := [[-1, 2], [2, -1]]
]
</example>
</description>

<seealso>
  <see>NmzIntClosureToricRing</see>
  <see>NmzNormalToricRing</see>
  <see>NmzIntClosureMonIdeal</see>
  <see>NmzEhrhartRing</see>
  <see>NmzTorusInvariants</see>
  <see>NmzFiniteDiagInvariants</see>
  <see>NmzDiagInvariants</see>
  <see>NmzIntersectionValRings</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>normalizcomputation</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzDiagInvariants</title>
  <short_description>ring of invariants of a diagonalizable group action</short_description>
<syntax>
NmzDiagInvariants(M: <type>MAT</type>, M: <type>Ring</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function computes the ring of invariants of a diagonalizable
group D = T x G where T is a torus and G is a finite abelian
group, both acting diagonally on the polynomial
ring <formula>K[X_1,...,X_n]</formula>.
<par/>
The group actions are specified by the input matrices M and N. The
first matrix specifies the torus action, the second the action of the
finite group. See torusInvariants or finiteDiagInvariants for more
detail. The output is the monomial subalgebra of invariants.
<example>
/**/     Use R::=QQ[x,y,z,w];
/**/     T := matrix([[-1,-1,2,0],[1,1,-2,-1]]);
/**/     U := matrix([[1,1,1,1,5],[1,0,2,0,7]]);
/**/     NmzDiagInvariants(T,U,R);
</example>
</description>
<seealso>
  <see>NmzComputation</see>
  <see>NmzTorusInvariants</see>
  <see>NmzFiniteDiagInvariants</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzEhrhartRing</title>
  <short_description>Computes the Ehrhart ring</short_description>
<syntax>
NmzEhrhartRing(L: <type>LIST</type> of <type>RINGELEM</type>, s: <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
The exponent vectors of the given monomials are considered as vertices of a
lattice polytope <tt>P</tt>.  The Ehrhart ring of a (lattice) polytope <tt>P</tt>
is the monoid algebra defined by the monoid of lattice points in the cone
over the polytope <tt>P</tt>; see the book by Bruns and Gubeladze,
<i>Polytopes, Rings, and K-theory</i>, Springer 2009, pp. 228, 229.
The function returns the generators of the Ehrhart ring.  It uses the
indeterminate in the second argument as auxiliary indeterminate of the
Ehrhart ring.

<example>
/**/     Use R::=QQ[x,y,z,t];
/**/     NmzEhrhartRing([x^2,y^2,z^3],t);
[x^2*t, z^3*t, x*y*t, y^2*t]
</example>
</description>

<seealso>
  <see>NmzComputation</see>
  <see>NmzHilbertBasis</see>
  <see>NmzNormalToricRing</see>
  <see>NmzIntClosureMonIdeal</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>ehrhart</key>
  <key>ehrhartring</key>
  <key>ehrhart ring</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzFiniteDiagInvariants</title>
  <short_description>ring of invariants of a finite group action</short_description>
<syntax>
NmzFiniteDiagInvariants(M: <type>MAT</type>, M: <type>Ring</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function computes the ring of invariants of a finite abelian
group <formula>G</formula> acting diagonally on the surrounding polynomial
ring <formula>K[X_1,...,X_n]</formula>.
<par/>
The group is the direct product of cyclic groups generated by finitely many
elements <formula>g_1,...,g_w</formula>.
The element <formula>g_i</formula> acts on the indeterminate <formula>X_j</formula>
by <formula>g_i(X_j)= l_i^{u_{ij}} X_j</formula> where <formula>l_i</formula>
is a primitive root of unity of order equal to <formula>ord(g_i)</formula>.
<par/>
The ring of invariants is generated by all monomials satisfying the
system <formula>u_{i1} a_1+...+u_{in}</formula> and congruent 
to <formula>0 mod ord(g_i) i=1,...,w</formula>.
<par/>
The input to the function is the w times (n+1) matrix
<tt>U</tt> with rows <formula>u_{i1} ...u_{in} ord(g_i), i=1,...,w</formula>.
The output is the monomial subalgebra of invariants
<formula>R^G = {f in R : g_i f = f for all i=1,...,w}</formula>.
<example>
/**/     Use R::=QQ[x,y,z,w];
/**/     U := matrix([[1,1,1,1,5],[1,0,2,0,7]]);
/**/     NmzFiniteDiagInvariants(U,R);
</example>
</description>
<seealso>
  <see>NmzComputation</see>
  <see>NmzTorusInvariants</see>
  <see>NmzDiagInvariants</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzHilbertBasis</title>
  <short_description>Hilbert Basis of a monoid</short_description>
  
<syntax>
NmzHilbertBasis(M: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
Given a matrix M, this function returns a matrix whose rows represent
 the Hilbert Basis for the monoid generated by the rows of M.
<example>
/**/     M:= matrix([[0,1],[3,1]]);
/**/     NmzHilbertBasis(M);
--the Hilbert basis of the monoid generated by the vectors [0,1] and [3,1] is...
matrix(QQ,
 [[3, 1],
  [0, 1]])
-- ... ([3,1], [0,1])

-- Different result for...
/**/     HilbertBasisKer(M); 
-- the Hilbert basis of M is the Hilbert basis of the monoid of
-- elements in the kernel of M, namely...
[]
-- ...no elements! (except the zero-element) 
</example>
</description>

<seealso>
  <see>HilbertBasisKer</see>
  <see>NmzComputation</see>
  <see>NmzNormalToricRing</see>
  <see>NmzIntClosureMonIdeal</see>
</seealso>

<types>
</types>

<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>hilbert basis</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzIntClosureMonIdeal</title>
  <short_description>integral closure of a monomial ideal</short_description>
<syntax>
      NmzIntClosureMonRing(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
      NmzIntClosureMonRing(L: <type>LIST</type> of <type>RINGELEM</type>, s: <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>, 
</syntax>
<description>
Given a list <tt>L</tt> of power-products in a ring <tt>R</tt>, the function returns the 
generators of the integral closure of the ideal generated by <tt>L</tt>.

As second argument you can specify an indeterminate of the ring which is not
used in the power-products.  In this case the result is the normalisation of
its Rees algebra (or Rees ring); see Bruns and Herzog, <i>Cohen-Macaulay Rings</i>,
Cambridge University Press 1998, p. 182.

<example>
/**/     Use R::=QQ[x,y,z,t];
/**/     NmzIntClosureMonIdeal([x^2,y^2,z^3]);
-- the integral closure of the ideal generated by x^2,y^2 and z^3 is...
[y^2, x^2, x*y, z^3, y*z^2, x*z^2]
-- ...the ideal generated by y^2, x^2, x*y, z^3, y*z^2 and x*z^2
/**/     NmzIntClosureMonIdeal([x^2,y^2,z^3],t);
-- and the complete rees algebra is generated by
[z, z^3*t, y, y*z^2*t, y^2*t, x, x*z^2*t, x*y*t, x^2*t]
</example>
</description>

<seealso>
  <see>NmzComputation</see>
  <see>NmzHilbertBasis</see>
  <see>NmzNormalToricRing</see>
  <see>NmzEhrhartRing</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>integral closure</key>
  <key>integralclosure</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzIntClosureToricRing</title>
  <short_description>integral closure of a toric ring</short_description>

<syntax>
NmzIntClosureToricRing(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
Given a list L of power-products in a ring R, the function returns the 
generators of the integral closure of the algebra generated by the list. 
 
<example>
/**/     Use R::=QQ[x,y,t];
/**/     NmzIntClosureToricRing([x^3,x^2*y,y^3]);
-- the integral closure of QQ[x^3, x^2*y, y^3] is...
[y,x]
-- ... QQ[y, x]
</example>
</description>


<seealso>
  <see>NmzComputation</see>
  <see>NmzHilbertBasis</see>
  <see>NmzNormalToricRing</see>
  <see>NmzIntClosureMonIdeal</see>
  <see>NmzEhrhartRing</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>integral closure</key>
  <key>integralclosure</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzIntersectionValRings</title>
  <short_description>intersection of ring of valuations</short_description>
<syntax>
NmzIntersectionValRings(M: <type>MAT</type>, M: <type>Ring</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
A discrete monomial valuation <formula>v</formula> on <formula>R=K[X_1,...,X_n]</formula>
is determined by the values <formula>v(X_j)</formula> of the indeterminates. 
This function computes the subalgebra
<formula>S = {f in R: v_i(f) >= 0, i=1,...,r}</formula>
that is the intersection of the valuation rings of the given
valuations <formula>v_1, ...,v_r</formula>, i.e. it consists of all
elements of R that have a nonnegative value for all r valuations.
It takes as input the matrix <formula>V=(v_i(X_j))</formula> whose
rows correspond to the values of the indeterminates.
<example>
/**/     Use R::=QQ[x,y,z,w];
/**/     V := matrix([[0,1,2,3],[-1,1,2,1]]);
/**/     NmzIntersectionValRings(V,R);
[y, z, w, x*y, x^2*z, x*w, x*z]
</example>
</description>
<seealso>
  <see>NmzComputation</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzNormalToricRing</title>
  <short_description>normalization of a toric ring</short_description>

<syntax>
NmzNormalToricRing(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
Given a list L of power-products in a ring R, the function returns the 
generators of the normalization of the algebra generated by the list. 

<example>
/**/     Use R::=QQ[x,y,t];
/**/     NmzNormalToricRing([x^3,x^2*y,y^3]);
-- the normalization of QQ[x^3,x^2*y,y^3] is...
[y^3, x^2*y, x^3, x*y^2]
-- QQ[y^3, x^2*y, x^3, x*y^2]
</example>
</description>


<seealso>
  <see>NmzComputation</see>
  <see>NmzHilbertBasis</see>
  <see>NmzIntClosureToricRing</see>
  <see>NmzIntClosureMonIdeal</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>toric</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NmzTorusInvariants</title>
  <short_description>ring of invariants of torus action</short_description>
<syntax>
NmzTorusInvariants(M: <type>MAT</type>, M: <type>Ring</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
Let <tt>T=(K^*)^r</tt> be the r-dimensional torus acting on the polynomial ring
<tt>R=K[X_1,...,X_n]</tt> diagonally.  Such an action can be described as follows:
there are integers <formula>a_ij, i=1,...,r, j=1,...,n</formula> such that <formula>(l_1,...,l_r)</formula> in <tt>T</tt>
acts by the substitution  <formula>X_j</formula> maps to <formula>l_1^{a_{1j}} * ... * l_r^{a_{rj}} * Xj</formula> for j=1,...,n.

The function takes the matrix <formula>(a_{ij})</formula> and the ring R as input.
It computes the ring of invariants <formula>R^T = {f in R | lf = f for all l in T}</formula>.
<example>
/**/     Use R::=QQ[x,y,z,w];
/**/     T := matrix([[-1,-1,2,0],[1,1,-2,-1]]);
/**/     NmzTorusInvariants(T,R);
[x^2*z, x*y*z, y^2*z]
</example>
</description>
<seealso>
  <see>NmzComputation</see>
  <see>NmzDiagInvariants</see>
  <see>NmzFiniteDiagInvariants</see>
</seealso>
<keys>
  <key>author: soeger</key>
  <key>normaliz</key>
  <key>torus</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NonZero</title>
  <short_description>remove zeroes from a list</short_description>
<syntax>
NonZero(L: <type>LIST</type>|<type>MODULEELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list obtained by removing the zeroes from L.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  NonZero([0,0,3, ideal(y),0]);
[3, ideal(y)]
</example>
</description>
<seealso>
  <see>FirstNonZero</see>
  <see>FirstNonZeroPosn</see>
  <see>IsZero</see>
</seealso>
<keys>
  <key>non-zero</key>
  <key>non zero</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>not</title>
  <short_description>boolean "not" operator</short_description>
<syntax>
not(A: <type>BOOL</type>): <rtn>BOOL</rtn>
</syntax>
<description>
This function negates a boolean: <i>i.e.</i> if <tt>A</tt> gives <tt>true</tt>
then <tt>not(A)</tt> gives <tt>false</tt>, and vice versa.
<par/>
Note that from CoCoA-5.1 <tt>not</tt> is a function, so its argument must be
between brackets!
<example>
/**/  [n in 1..10 | not(IsPrime(n))];
[1,4,6,8,9]
</example>
</description>
<keys>
  <key>boolean operator</key>
  <key>logical operator</key>
  <key>logical not</key>
  <key>logical negation</key>
</keys>
<seealso>
  <see>and</see>
  <see>or</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NR</title>
  <short_description>normal reduction</short_description>
<syntax>
NR(X: <type>RINGELEM</type>, L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
NR(X: <type>MODULEELEM</type>, L: <type>LIST</type> of <type>MODULEELEM</type>): <rtn>MODULEELEM</rtn>
</syntax>
<description>
This function returns the normal remainder of X with respect to L,
i.e., it returns the remainder from the division algorithm.  To get
both the quotients and the remainder, use <ttref>DivAlg</ttref>.
<par/>
Note that if the list does not form a Groebner basis, the remainder
may not be zero even if X is in the ideal or module generated by L
(use <ttref>GenRepr</ttref> or <ttref>NF</ttref> instead).
<par/>
Currently (v 5.0.3) the internal code for computing 
<code>NF(F, I)</code> and <code>NR(F, GBasis(I))</code> is identical,
but the second is slower just for the overhead in interpreting a
possibly long list of polynomials.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := x^2*y +x*y^2 +y^2;
/**/  NR(F, [x*y-1, y^2-1]);
x +y +1

// NOT YET IMPLEMENTED for MODULEELEM
</example>
</description>
<seealso>
  <see>DivAlg</see>
  <see>GenRepr</see>
  <see>NF</see>
</seealso>
<keys>
  <key>normal reduction</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>num</title>
  <short_description>numerator</short_description>
<syntax>
num(N: <type>INT</type>): <rtn>INT</rtn>
num(N: <type>RAT</type>): <rtn>INT</rtn>
num(N: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the numerator of <tt>N</tt>.
<par/>
The OBSOLETE fragile syntax in CoCoA 4 <tt>N.Num</tt> and <tt>N.Den</tt> is no
longer supported.
<example>
/**/  num(3);
3

/**/  P ::= QQ[x,y];
/**/  F := NewFractionField(P);
/**/  Use F;
/**/  num(x/(x+y));
x
</example>
</description>
<seealso>
  <see>den</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumCols</title>
  <short_description>number of columns in a matrix</short_description>
<syntax>
NumCols(M: <type>MAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the number of columns in a matrix.
<example>
/**/  M := mat([[1,2,3], [4,5,6]]);
/**/  NumCols(M);
3
</example>
</description>

<seealso>
  <see>matrix</see>
  <see>NumRows</see>
</seealso>
<keys>
  <key>number of columns</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumCompts</title>
  <short_description>the number of components</short_description>

<syntax>
NumCompts(X: <type>MODULEELEM</type>|<type>MODULE</type>): <rtn>INT</rtn>
</syntax>
<description>
If <tt>X</tt> is a <tt>MODULEELEM</tt>, it returns the number of components of <tt>X</tt>.
If <tt>X</tt> is a <tt>MODULE</tt>, it returns the rank of the free module in which <tt>X</tt> is
defined.
<par/>
This function used to be called <tt>NumComps</tt> in CoCoA-4.
<example>
/**/  Use R ::= QQ[x,y];
/**/  R2 := NewFreeModule(R, 3);
/**/  M := SubmoduleRows(R2, matrix(R, mat([[x,0,y], [x^2+y^2,x^2,3]])));
/**/  NumCompts(M);
3
/**/  NumCompts(gens(M)[1]);
3
</example>
</description>

<seealso>
  <see>len</see>
</seealso>

<keys>
  <key>NumCompts</key>
  <key>free module rank</key>
  <key>FreeModuleRank</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumIndets</title>
  <short_description>number of indeterminates</short_description>

<syntax>
NumIndets(R: <type>RING</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the number of indeterminates of the current ring or
of R.

<example>
/**/  S ::= QQ[x,y];
/**/  R ::= QQ[x,y,z];
/**/  NumIndets(R);
3

/**/  NumIndets(S);
2
</example>
</description>

<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>indets</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumPartitions</title>
  <short_description>number of partitions of an integer</short_description>

<syntax>
NumPartitions(N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the number of partitions of a non-negative integer,
i.e. the number of distinct ways of writing <tt>N</tt> as a sum of positive integers.
<example>
/**/  NumPartitions(2); -- 2 and 1+1
2
/**/  NumPartitions(5);
7
</example>
</description>
<keys>
  <key>number of partitions</key>
  <key>combinatorics</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumRows</title>
  <short_description>number of rows in a matrix</short_description>

<syntax>
NumRows(M: <type>MAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the number of rows in a matrix.
<example>
/**/  M := mat([[1,2,3], [4,5,6]]);
/**/  NumRows(M);
2
</example>
</description>

<seealso>
  <see>matrix</see>
  <see>NumCols</see>
</seealso>
<keys>
  <key>number of rows</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>NumTerms</title>
  <short_description>number of terms in a polynomial</short_description>

<syntax>
NumTerms(F: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns the number of terms in a polynomial.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  NumTerms((x+y+z)^5) = binomial(3+5-1, 5);
true
</example>
</description>

<seealso>
  <see>len</see>
</seealso>
<keys>
  <key>length</key>
  <key>number of terms</key>
  <key>number of monomials</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>O</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>one</title>
  <short_description>one of a ring</short_description>

<syntax>
one(R: <type>RING</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function return the multiplicative identity of a ring.
For when you want to force the integer <tt>1</tt> to be a
<tt>RINGELEM</tt>.

<example>
/**/ P ::= ZZ/(101)[x,y,z];
/**/ N := 1;  Print N, " of type ",  type(N);
1 of type INT
/**/ N := one(P);  Print N, " of type ",  type(N);
1 of type RINGELEM
/**/ N := 300*1;  Print N, " of type ",  type(N);
300 of type INT
/**/ N := 300*one(P);  Print N, " of type ",  type(N);
-3 of type RINGELEM
</example>
</description>


<seealso>
  <see>zero</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convert</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenIFile</title>
  <short_description>open input file</short_description>

<syntax>
OpenIFile(S: <type>STRING</type>): <rtn>DEVICE</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function opens the file with name S for input.
Input from that file can then be read with <ttref>Get</ttref>.
<par/>
(Note: one would normally use <ttref>source</ttref> to read CoCoA commands from a file.)

<example>
  D := OpenOFile("my-test");  -- open "my-test" for output from CoCoA
  Print "hello world" On D;   -- print string into "mytest"
  Close(D);
  D := OpenIFile("my-test");  -- open "my-test" for input to CoCoA
  Get(D,3);  -- get the first three characters (in Ascii code)
[104, 101, 108]
-------------------------------
  ascii(It);  -- convert the ASCII code into characters
hel
-------------------------------
  Close(D);
</example>
</description>


<seealso>
  <see>close</see>
  <see>Introduction to IO</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
  <see>OpenSocket</see>
  <see>source</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenIString</title>
  <short_description>open input string</short_description>

<syntax>
OpenIString(S: <type>STRING</type>, T: <type>STRING</type>): <rtn>DEVICE</rtn>
OpenOString(S: <type>STRING</type>): <rtn>DEVICE</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function open strings for input.  The string S
serves as the name of the device opened for input or output; one may
use the empty string.  <tt>OpenIString</tt> is used to read input from the
string T with the help of <ttref>Get</ttref>.

<example>
  S := "hello world";
  D := OpenIString("", S);  -- open the string S for input to CoCoA
  L := Get(D,7);  -- read 7 characters from the string
  L;  -- ASCII code
[104, 101, 108, 108, 111, 32, 119]
-------------------------------
  ascii(L); -- convert ASCII code to characters
hello w
-------------------------------
  Close(D);  -- close device D
</example>
</description>


<seealso>
  <see>close</see>
  <see>Introduction to IO</see>
  <see>OpenOString</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>source</see>
  <see>sprint</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenLog</title>
  <short_description>open a log of a CoCoA session</short_description>

<syntax>
OpenLog(D: <type>DEVICE</type>)
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function opens the output device D and starts to record the
output from a CoCoA session on D.  The <ttref>CloseLog</ttref> closes the
device D and stops recording the CoCoA session on D.
<par/>
At present the choices for the device D are an output file (see
<ttref>OpenOFile</ttref>) or an output string (see <ttref>OpenOString</ttref>).  Several output
devices may be open at a time.  If the panel option <tt>Echo</tt> is set to
True, both the input and output of the CoCoA session are logged;
otherwise, just the output is logged.

<example>
  D := OpenOFile("MySession");
  OpenLog(D);
  1+1;
2
-------------------------------
  G := 1;
  Set Echo;
  2+2;
2 + 2
4
-------------------------------
  F := 2;
F := 2
  CloseLog(D);
CloseLog(D)
  UnSet Echo;
SET(Echo, False)

-- The contents of "MySession":
2
-------------------------------
2 + 2
4
-------------------------------
F := 2
CloseLog(D)
</example>
</description>


<seealso>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenOFile</title>
  <short_description>open output file</short_description>

<syntax>
OpenOFile(S: <type>STRING</type>): <rtn>DEVICE</rtn>
OpenOFile(S: <type>STRING</type>,"w" or "W"): <rtn>DEVICE</rtn>
</syntax>
<description>
This function opens the file with name S---creating it if it
does not already exist---for output.  If used with second argument
<tt>w</tt> or <tt>W</tt> then it immediately erases the file S.
The function <ttref>print on</ttref> is then used for appending output to S.

<example>
  D := OpenOFile("my-test");  -- open "my-test" for output from CoCoA
  Print "hello world" On D;   -- print string into "mytest"
  Print " test" On D;  -- append to the file "mytest"
  Close(D);  -- close the file
  D := OpenOFile("my-test","w"); -- clear "my-test"
  Print "goodbye" On D; -- "mytest" now consists only of the string "goodbye"
  Close(D);
</example>
</description>


<seealso>
  <see>close</see>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
  <see>source</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenOString</title>
  <short_description>open output string</short_description>

<syntax>
OpenOString(S: <type>STRING</type>): <rtn>DEVICE</rtn>
</syntax>
<description>
This function opens strings for output.  The string S
serves as the name of the device opened for input or output; one may
use the empty string.  <tt>OpenOString</tt> is used to write to a
string with the help of <tt>print on</tt>.

<example>
  D := OpenOString("");  -- open a string for output from CoCoA
  L := [1,2,3]; -- a list
  Print L On D;  -- print to D
  D;
record[Name := "", Type := "OString", Protocol := "CoCoALanguage"]
-------------------------------
  S := Cast(D, STRING);  -- S is the string output to D
  S; -- a string
[1, 2, 3]
-------------------------------
  Print " more characters" On D;  -- append to the existing output string
  Cast(D, STRING);
[1, 2, 3] more characters
-------------------------------
</example>
</description>


<seealso>
  <see>close</see>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>source</see>
  <see>sprint</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OpenSocket</title>
  <short_description>open a socket connection</short_description>

<syntax>
OpenSocket(Machine: <type>STRING</type>, Port: <type>STRING</type>): <rtn>DEVICE</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function opens a client socket (I/O) connection.
It requires the name of the machine with the server socket and the
port number (expressed as a STRING).
<par/>
CoCoA-4  communicates with the CoCoAServer via socket which, by
default, runs on <tt>localhost</tt> on
port <tt><quotes>0xc0c0</quotes></tt>.
To change these settings redefine in your <tt>userinit.coc</tt> or
<tt>.cocoarc</tt> the variables
<verbatim>
  MEMORY.CoCoAServerMachine := <quotes>localhost</quotes>;
  MEMORY.CoCoAServerPort := <quotes>0xc0c0</quotes>;
</verbatim>

<example>
  D := OpenSocket("localhost", "10000");
  Print 100^6 On D;
  Source D;
  Close(D);
</example>
</description>


<seealso>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Option [OBSOLETE]</title>
  <short_description>[OBSOLETE] status of a panel option</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>or</title>
  <short_description>boolean "or" operators</short_description>

<syntax>
A or B         (where A, B: <type>BOOL</type>, return <rtn>BOOL</rtn>)
</syntax>
<description>
This operator represents the logical disjunction of <tt>A</tt> and <tt>B</tt>.
CoCoA first evaluates <tt>A</tt>; if that gives <tt>true</tt> then the result is
<tt>true</tt>, and <tt>B</tt> is not evaluated.  Otherwise, if <tt>A</tt> gives
<tt>false</tt> then <tt>B</tt> is evaluated, and its value is the final result.
<example>
/**/  Define IsUnsuitable(X)
/**/    Return X &lt; 0 or isqrt(X) >= 2^16;
/**/  EndDefine;
/**/  IsUnsuitable(-9);
true
/**/  IsUnsuitable(9);
false
</example>
</description>

<keys>
  <key>|</key>
  <key>||</key>
  <key>boolean operator</key>
  <key>logical operator</key>
  <key>logical or</key>
  <key>disjunction</key>
</keys>

<seealso>
  <see>and</see>
  <see>not</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>OrdMat</title>
  <short_description>matrix defining a term-ordering</short_description>

<syntax>
OrdMat(R: <type>RING</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns a matrix which describes the term-ordering
of the ring <tt>R</tt>.

<example>
/**/  Use S ::= QQ[x,y,z];
/**/  M := mat([ [1,2,3], [3,4,5], [0,0,1]]);
/**/  P := NewPolyRing(CoeffRing(S), IndetSymbols(S), M, 2);
/**/  GradingDim(P);
2
/**/  OrdMat(P);
matrix(QQ,
 [[1, 2, 3],
  [3, 4, 5],
  [0, 0, 1]])

/**/  GradingDim(S);
1
/**/  OrdMat(S);
matrix(QQ,
 [[1, 1, 1],
  [0, 0, -1],
  [0, -1, 0]])
</example>
</description>


<seealso>
  <see>StdDegLexMat</see>
  <see>StdDegRevLexMat</see>
  <see>LexMat</see>
  <see>RevLexMat</see>
  <see>XelMat</see>
  <see>elim</see>
  <see>GradingDim</see>
  <see>Orderings</see>
  <see>NewPolyRing</see>
</seealso>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>P</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Packages</title>
  <short_description>list of loaded packages</short_description>
<syntax>
packages(): <rtn>LIST</rtn> of <rtn>STRING</rtn>
</syntax>
<description>
This function returns the names of the loaded packages as a list of
strings.
<par/>
The old CoCoA-4 names <tt>$user</tt> and <tt>$builtin</tt> are no
longer used.
<example>
/**/  packages();
["$BackwardCompatible", "$BringIn", (...) ]
</example>
</description>
<seealso>
  <see>CoCoA Packages</see>
  <see>Supported Packages</see>
</seealso>
<types>
  <type>packages</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>panel [OBSOLETE]</title>
  <short_description>[OBSOLETE] print status of a panel&apos;s options</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>panels [OBSOLETE]</title>
  <short_description>[OBSOLETE] list of CoCoA panels</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>partitions</title>
  <short_description>partitions of an integer</short_description>

<syntax>
partitions(N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
These function returns all integer partitions of N, positive integer

<example>
/**/  partitions(3);
[[3], [1, 2], [1, 1, 1]]
</example>
</description>


<seealso>
  <see>subsets</see>
  <see>tuples</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>permutations</title>
  <short_description>returns all permutations of the entries of a list</short_description>

<syntax>
permutations(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function computes all permutations of the entries of a list (set).
If L has repeated elements it will return repeated elements.

<example>
/**/  permutations(3..5);
[[3, 4, 5], [3, 5, 4], [4, 3, 5], [4, 5, 3], [5, 3, 4], [5, 4, 3]]

/**/  permutations([2, 2, x]);
[[2, 2, x], [2, x, 2], [2, 2, x], [2, x, 2], [x, 2, 2], [x, 2, 2]]

/**/  MakeSet(permutations([2, 2, x]));
[[2, 2, x], [2, x, 2], [x, 2, 2]]
</example>
</description>


<seealso>
  <see>subsets</see>
  <see>tuples</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PerpIdealOfForm</title>
  <short_description>Ideal of derivations annihilating a form</short_description>

<syntax>
PerpIdealOfForm(F: <type>RINGELEM</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
Thanks to Enrico Carlini.
<par/>
Given a form <tt>F</tt> computes the ideal of derivations killing it.
<par/>
For the sake of simplicity Forms/Polynomials and Derivations live in
the same ring, the distinction between them is purely formal.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  PerpIdealOfForm(x^3+x*y*z);
ideal(z^2, y^2, x^2 -6*y*z)

/**/  Hilbert(R/It);
H(0) = 1
H(1) = 3
H(2) = 3
H(3) = 1
H(t) = 0   for t >= 4
</example>
</description>

<seealso>
  <see>InverseSystem</see>
  <see>DerivationAction</see>
</seealso>
<keys>
  <key>author: enrico carlini</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>pfaffian</title>
  <short_description>the Pfaffian of a skew-symmetric matrix</short_description>
<syntax>
pfaffian(M: <type>MAT</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the Pfaffian of M.
<example>
/**/  Use R ::= QQ[x,y];
/**/  pfaffian(mat([[0,y],[-y,0]]));
y
</example>
</description>

<seealso>
  <see>det</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PkgName</title>
  <short_description>returns the name of a package</short_description>

<syntax>
PkgName(): <rtn>STRING</rtn>
S.PkgName(): <rtn>STRING</rtn>

where S is the identifier or alias for a package.
</syntax>
<description>
This function returns the (long) name of a package.  The first form
returns <tt>$coclib</tt> and the second returns the name of the package
whose name or alias is S.  This function is useful as a shorthand,
when S is an alias, for the full name a package.

<example>
  GB.PkgName();
$gb
-------------------------------
  $gb.PkgName();
$gb
-------------------------------
  PkgName();
$coclib
-------------------------------
</example>
</description>


<types>
  <type>packages</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PlotPoints</title>
  <short_description>outputs the coordinates of the points to a file</short_description>

<syntax>
PlotPoints(L: <type>LIST</type> of points)
</syntax>
<description>
This function outputs the coordinates of the points (with two
components) to a file called <quotes>CoCoAPlot</quotes>.
See <ttref>PlotPointsOn</ttref> for outputting to another file.
<par/>
This result can be plotted using your preferred plotting program.
For example, start <quotes>gnuplot</quotes> and then give it the command
<verbatim>  plot <quotes>CoCoAPlot</quotes></verbatim>
to see the plot.

<example>
/**/  PlotPoints([ [X, X^2-X+14] | X In -10..10]);
Plotting points...100%
21 plotted points have been placed in the file CoCoAPlot
</example>

</description>

<seealso>
  <see>ImplicitPlot</see>
  <see>PlotPointsOn</see>
</seealso>

<keys>
  <key>gnuplot</key>
  <key>plot points</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PlotPointsOn</title>
  <short_description>outputs the coordinates of the points to a file</short_description>

<syntax>
PlotPointsOn(L: <type>LIST</type> of points, S: <type>STRING</type>)
</syntax>
<description>
This function is the same as <ttref>PlotPoints</ttref> with a second
argument giving the name of the file to print on.
<par/>
Note that the last argument is a STRING, the name of the file, and not
a DEVICE, as for <ttref>print on</ttref>.

<example>
/**/  PlotPointsOn([ [1/(X+1/2), X^2-X+14] | X In -10..10], "PLOT-points");
Plotting points...100%
21 plotted points have been placed in the file points

/**/  ImplicitPlotOn(x^2*y -(59/4)*x^2 +2*x -1, [-3,3], [0,250], "PLOT-curve");
Plotting points...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
735 plotted points have been placed in the file curve
</example>
After having produced the plot files using CoCoA-4,
start <quotes>gnuplot</quotes> and then give it the following commands:
<verbatim>  plot <quotes>curve</quotes>
  replot <quotes>points</quotes>
</verbatim>

</description>

<seealso>
  <see>ImplicitPlot</see>
  <see>PlotPoints</see>
</seealso>

<keys>
  <key>gnuplot</key>
  <key>plot points</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>poincare [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] the Hilbert-Poincare series</short_description>
<syntax>
[OBSOLESCENT]poincare(M: <type>RING</type>|<type>IDEAL</type>):TAGGED("$hp.PSeries")
</syntax>
<description>
(sorry Poincare' for the lower-case: here we follow the naming
convention <em>single name goes lower-case</em>)
<par/>
[OBSOLESCENT] Now called <ttref>HilbertSeries</ttref>.
</description>
<seealso>
  <see>HilbertSeries</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PoincareMultiDeg [OBSOLETE]</title>
  <short_description>[OBSOLETE]</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] now called <ttref>HilbertSeriesMultiDeg</ttref>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PoincareShifts [OBSOLETE]</title>
  <short_description>[OBSOLETE]</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]  now called <ttref>HilbertSeriesShifts</ttref>
</description>
</command>
<!-- ===  COMMAND-rm Poly =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PolyAlgebraHom</title>
  <short_description>homomorphism of polynomial algebras</short_description>
<syntax>
PolyAlgebraHom(Domain: <type>RING</type>, Codomain: <type>RING</type>, images: <type>LIST</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
This function creates the homomorphism of (polynomial) algebras from
<tt>R</tt> to <tt>S</tt> with the same ring of coefficients.  This is
uniquely defined by the images of the indeterminates of <tt>R</tt> which
are specified by the entries of <tt>images</tt>.
<par/>
This is a cleaner mathematical implementation of the function
<ttref>image [OBSOLESCENT]</ttref> in CoCoA-4.
<example>
/**/ Use R ::= QQ[x,y,z];
/**/ S ::= QQ[x[1..3]];
/**/ phi := PolyAlgebraHom(R, S, indets(S));
/**/ phi(x^2-y);
x[1]^2 -x[2]

/**/ S ::= QQ[a];
/**/ phi := PolyAlgebraHom(R, S, [RingElem(S,"a"),1,0]);
/**/ phi(x^2-y);
a^2 -1

/**/ phi := PolyAlgebraHom(R, QQ, [2,1,0]); --> evaluate at [2,1,0]
/**/ phi(x^2-y);
3
</example>
</description>
<seealso>
  <see>apply</see>
  <see>CanonicalHom</see>
</seealso>
<keys>
  <key>map</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PolyRingHom</title>
  <short_description>homomorphism of polynomial rings</short_description>

<syntax>
PolyRingHom(R: <type>RING</type>, S: <type>RING</type>, CoeffHom: <type>RINGHOM</type>, images: <type>LIST</type>): <rtn>RINGHOM</rtn>
</syntax>
<description>
This function create the homomorphism of (polynomial) algebras between
R and S.
This is uniquely defined by the images of the indeterminated of R and
the homomorphism CoeffRing(R) into S.
<example>
/**/ R ::= QQ[x,y];
/**/ S ::= QQ[a,b,c];
/**/ SmodJ := NewQuotientRing(S, ideal(RingElem(S,"a")^2-1));

/**/ Use SmodJ;
/**/ phi := PolyRingHom(R, SmodJ, CanonicalHom(QQ,SmodJ), [a,b]);
/**/ Use R;
/**/ phi(x);
(a)
</example>
</description>


<seealso>
  <see>apply</see>
  <see>CanonicalHom</see>
</seealso>
<keys>
  <key>map</key>
</keys>

</command>
<!-- ===  COMMAND-rm PositiveGrading4 ==================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PowerMod</title>
  <short_description>compute a modular power efficiently</short_description>

<syntax>
PowerMod(A: <type>INT</type>, B: <type>INT</type>, M: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function calculates efficiently an integer power modulo a given
modulus.  Thus <tt>PowerMod(A, B, M)</tt> is equal to <tt>mod(A^B, M)</tt>, but the former
is computed faster.  <tt>B</tt> must be non-negative.
<example>
/**/  PowerMod(12345,41041,41041); -- 41041 is a Carmichael number
12345

/**/  PowerMod(123456789,987654321,32003); -- cannot compute 123456789^987654321 directly
2332
</example>
</description>

<keys>
  <key>modular power</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PreImage</title>
  <short_description>preimage of a RINGELEM</short_description>
<syntax>
PreImage(phi: <type>RINGHOM</type>, f: <type>RINGELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns the preimage of <tt>f</tt> via <tt>phi</tt>.
More precisely it returns a record with fields <tt>IsInImage</tt> and <tt>ker</tt>,
and <tt>OnePreImage</tt> if <tt>f</tt> is in the image of <tt>phi</tt>.
<example>
/**/  QQxyz ::= QQ[x,y,z];
/**/  QQab  ::= QQ[a,b];

/**/  Use QQab;
/**/  phi := PolyAlgebraHom(QQxyz, QQab, [a+1, a*b+3, b^2]);
/**/  IsInjective(phi);
false
/**/  ker(phi);
ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)
/**/  IsSurjective(phi);
false

/**/  Use QQab;
/**/  PreImage(phi, b);
record[IsInImage := false, ker := ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)]

/**/  indent(PreImage(phi, a^2));
Record[
  IsInImage := true,
  OnePreImage := x^2 -2*x +1,
  ker := ideal(-x^2*z +y^2 +2*x*z -6*y -z +9)
]
/**/  phi(ReadExpr(QQxyz, "x^2 - 2*x + 1"));
a^2
/**/  phi(ReadExpr(QQxyz, "x^2 - 2*x + 1 + (-x^2*z +y^2 +2*x*z -6*y -z +9)"));
a^2
</example>
</description>
<seealso>
  <see>ker</see>
  <see>IsSurjective</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PreprocessPts</title>
  <short_description>Reduce redundancy in a set of approximate points</short_description>

<syntax>
PreprocessPts(Pts: <type>MAT</type>, Toler: <type>MAT</type>): <rtn>RECORD</rtn>
PreprocessPtsGrid(Pts: <type>MAT</type>, Toler: <type>MAT</type>): <rtn>RECORD</rtn>
PreprocessPtsAggr(Pts: <type>MAT</type>, Toler: <type>MAT</type>): <rtn>RECORD</rtn>
PreprocessPtsSubDiv(Pts: <type>MAT</type>, Toler: <type>MAT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
Thanks to Maria-Laura Torrente.
<par/>
These functions detect groupings of close points, and choose a single
representative for them (which lies within the given tolerance of each
original point); the result is the list of these representatives, and the
number of original points associated to each representative.
<par/>
The first argument is a matrix whose rows represent a set of points in
k-dimensional space, and the second argument is row-matrix of k tolerances
(one for each dimension).
<par/>
The return value is a record containing two fields: <tt>NewPoints</tt> contains a
matrix whose rows represent a list of <em>well-separated</em> points, and <tt>weights</tt>
which contains the number of input points associated to each output point.
<par/>
There are three underlying algorithms: <tt>Grid</tt> is fast but crude;
<tt>Subdiv</tt> works best when the original points are densely packed
(so the result will be a small list); finally <tt>Aggr</tt> is best
suited to situations where the original points are less densely packed.
<par/>
The function <tt>PreprocessPts</tt> automatically chooses between <tt>Subdiv</tt>
and <tt>Aggr</tt> with the aim of minimising computation time.  Note that the
<tt>Aggr</tt> and <tt>Subdiv</tt> methods regard the tolerances as being slightly
flexible.
<par/>
For a full description of the algorithms we refer to the paper
J.Abbott, C.Fassino, L.Torrente
<em>Thinning Out Redundant Empirical Data</em> (Mathematics in Computer Science, 2007).

<example>
/**/  Pts := matrix([[-1,0],[0,0],[1,0],[99,1],[99,0],[99,-1]]);
/**/  Toler := RowMat([3,3]);
/**/  PreprocessPts(Pts, Toler);
record[NewPoints := matrix(QQ,
 [[99, 0],
  [0, 0]]), weights := [3, 3]]

/**/  PreprocessPts(Pts, RowMat([0.8,0.8]));
record[Points := matrix(QQ,
 [[-1/2, 0],
  [1, 0],
  [99, 1/2],
  [99, -1]], Weights := [2, 1, 2, 1]]

/**/  PreprocessPtsAggr(Pts, RowMat([0.9,0.9])); -- exhibits tolerance flex
record[Points := matrix(QQ,
 [[0, 0],
  [99, 0]], Weights := [3, 3]]
</example>
</description>
<keys>
  <key>abbott fassino torrente</key>
  <key>preprocessing points</key>
  <key>author: maria-laura torrente</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrimaryDecomposition</title>
  <short_description>primary decomposition of an ideal</short_description>

<syntax>
PrimaryDecomposition(I: <type>IDEAL</type>): <rtn>LIST</rtn> of <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the primary decomposition of the ideal I.
Currently it is implemented ONLY for squarefree monomial ideals
using the Alexander dual technique.
See <ttref>FrbPrimaryDecomposition</ttref> for monomial ideals.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  PrimaryDecomposition(***Ideal(xy, yz, zx)***);
[ideal(y, z), ideal(x, z), ideal(x, y)]
</example>
</description>

<seealso>
  <see>FrbPrimaryDecomposition</see>
  <see>EquiIsoDec</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrimaryPoincare</title>
  <short_description>primary</short_description>

<syntax>
PrimaryPoincare(I: <type>IDEAL</type>, Q: <type>I</type>deal): TAGGED("PSeries")
</syntax>
<description>
Let P be a polynomial ring, M the maximal ideal generated by the
indeterminates.  This function computes the Hilbert-Poincare' series
of (P/I)/((Q+I)/I), where (Q+I)/I is a primary ideal for M/I.

<example>
/**/  Use S ::= QQ[x,y,z];
/**/  I := ideal(x^3-y*z, y^2-x*z, z^2-x^2*y);
/**/  Q := ideal(y, z);
/**/  PS := PrimaryPoincare(I, Q); PS;

/**/  Use S ::= ZZ/(32003)[x,y,z,w];
/**/  I := ***Ideal(x^5 - yz, y^4 - xz^2, xy^3 - zw, x^2z - yw,
/**/  y^2z^2 - w^3, y^3z - x^2w^2, x^3w - z^2, xyw^2 - z^3,
/**/  x^3y^2 - w^2, xz^4 - y^2w^3, yz^5 - xw^5, y^3w^5 - z^7,
/**/  x^2w^7 - z^8, z^9 - yw^8)***;
/**/  Q  := ideal(x, y, z);
/**/  PS := PrimaryPoincare(I, Q); PS;
/**/  $hp.PSerToHilbert(PS);

/**/  Use S ::= ZZ/(32003)[x,y,z];
/**/  I  := ideal(S, []);  -- ideal in S with no generators
/**/  Q  := ideal(x, y, z^2);
/**/  PS := PrimaryPoincare(I, Q); PS;
/**/  $hp.PSerToHilbert(PS);
/**/  HV := $hp.PSerHVector(PS); -- the H-vector associated to PS

/**/  Use S ::= ZZ/(32003)[x,y,z,w];
/**/  I  := ***Ideal(-yz + xw, z^3 - yw^2, -xz^2 + y^2w, -y^3 + x^2z)***;
/**/  Q  := ideal(x, y, z^2, w^3);
/**/  PS := PrimaryPoincare(I, Q); PS;
/**/  $hp.PSerToHilbert(PS);
/**/  HV := $hp.PSerHVector(PS);
/**/  $primary.E(0, HV);
/**/  [ $primary.E(J,HV) | J In 0..($hp.PSerDim(PS)-2) ];
/**/  [ $primary.E(J,HV) | J In 0..(len(HV)-1) ];

/**/  Use S ::= ZZ/(32003)[x,y,z,w];
/**/  I  := ***Ideal(x^3-y^7, x^2y - xw^3-z^6)***;
/**/  Q  := ideal(x, y, z, w);
/**/  PS := PrimaryPoincare(I, Q); PS;
/**/  $hp.PSerToHilbert(PS);
/**/  HV := $hp.PSerHVector(PS);
/**/  [ $primary.E(J,HV) | J In 0..($hp.PSerDim(PS)-2) ];
/**/  [ $primary.E(J,HV) | J In 0..(len(HV)-1) ];

/**/  Use S ::= ZZ/(32003)[x,y,z];
/**/  I  := ideal(z^3);
/**/  Q  := ideal(x^2, y^2, x*z, y*z);
/**/  PS := PrimaryPoincare(I, Q); PS;
/**/  $hp.PSerToHilbert(PS);
/**/  HV := $hp.PSerHVector(PS);
/**/  [ $primary.E(J,HV) | J In 0..($hp.PSerDim(PS)-2) ];
/**/  [ $primary.E(J,HV) | J In 0..(len(HV)-1) ];
</example>
</description>

<seealso>
  <see>InitialIdeal</see>
  <see>TgCone</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrimitiveRoot</title>
  <short_description>find a primitive root modulo a prime</short_description>

<syntax>
PrimitiveRoot(P: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
Find a primitive root modulo the prime <tt>P</tt>, <i>i.e.</i> a generator of
 the cyclic multiplicative group of non-zero integers mod <tt>P</tt>.
<par/>
Currently, the function produces the least positive primitive root.
<example>
/**/  PrimitiveRoot(17551561);
97
/**/ PrimitiveRoot(4111);
12;
</example>
</description>

<seealso>
  <see>IsPrime</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>print</title>
  <short_description>print the value of an expression</short_description>
<syntax>
print E_1, ..., E_n
</syntax>
<description>
This command displays the value of each of the expressions <tt>E_i</tt>.
To insert a newline write <tt>\n</tt>.
<par/>
The similar command <ttref>println</ttref> is equivalent to <tt>print</tt>
with a final newline.
<example>
/**/  for I := 1 To 10 Do  print I^2, " ";  endfor;
1 4 9 16 25 36 49 64 81 100

/**/  print "a\nb";
a
b
</example>
</description>
<seealso>
  <see>print on</see>
  <see>println</see>
  <see>format</see>
  <see>LaTeX</see>
  <see>StarPrint, StarSprint</see>
</seealso>
<types>
  <type>io</type>
  <type>printing</type>
</types>
<keys>
  <key>printing</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>print on</title>
  <short_description>print to an output device</short_description>
<syntax>
print  E: <type>OBJECT</type>  on  D: <type>DEVICE</type>
</syntax>
<description>
This command prints the value of expression E to the device D.
Currently, the command can be used to print to files, strings, or the
CoCoA window.  In the first two cases, the appropriate device must be
opened with <ttref>OpenOFile</ttref> or <ttref>OpenOString</ttref>.
<example>
/**/  D := OpenOFile("my-test");  -- open "my-test" for output from CoCoA
/**/  Print "hello world" On D;   -- print string into "mytest"
/**/  close(D);  -- close the file
</example>
See <ttref>OpenOFile</ttref> for an example using output strings.
For printing to the CoCoA window, just use <tt>print E</tt> which is short for
<tt>print E On DEV.OUT</tt>.
</description>
<seealso>
  <see>Introduction to IO</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenIString</see>
  <see>OpenOString</see>
  <see>print</see>
  <see>println</see>
</seealso>
<types>
  <type>io</type>
  <type>printing on file</type>
</types>
<keys>
  <key>printing</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrintBettiDiagram</title>
  <short_description>the diagram of the graded Betti numbers</short_description>
<syntax>
PrintBettiDiagram(X: <type>IDEAL</type> or (quotient)<type>RING</type> or <type>MODULE</type>)
PrintBettiDiagram(X: <type>LIST</type>(res) or <type>RECORD</type>(diagram))
</syntax>
<description>
This function prints the (<quotes>Macaulay-style</quotes>) Betti diagram for <tt>M</tt>.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  I := ideal(x^2-y*t, x*y-z*t, x*y);
/**/  RES := res(I);
/**/  PrintRes(RES);
0 --> R(-5)^2 --> R(-4)^4 --> R(-2)^3
/**/  B := BettiDiagram(RES);  indent(B);
Record[
  Diagram := matrix(ZZ,
 [[3, 0, 0],
  [0, 4, 2]]),
  FirstShift := 2
]
/**/  PrintBettiDiagram(RES); -- same as PrintBettiDiagram(I or B)
        0    1    2
--------------------
 2:     3    -    -
 3:     -    4    2
--------------------
Tot:    3    4    2
</example>
</description>
<seealso>
  <see>BettiDiagram</see>
  <see>BettiMatrix</see>
  <see>PrintRes</see>
  <see>PrintBettiMatrix</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrintBettiMatrix</title>
  <short_description>print the matrix of the graded Betti numbers</short_description>

<syntax>
PrintBettiMatrix(M: <type>IDEAL</type>|<type>MODULE</type>|Resolution)
</syntax>
<description>
This function returns the Betti matrix for M.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  I := ideal(x^2-y*t, x*y-z*t, x*y);
/**/  PrintRes(I);
0 --> R^2(-5) --> R^4(-4) --> R^3(-2)
-------------------------------
/**/  PrintBettiMatrix(I);
   0    0    0
   0    0    3
   0    0    0
   0    4    0
   2    0    0
</example>
</description>
<seealso>
  <see>PrintRes</see>
  <see>PrintBettiDiagram</see>
</seealso>
<types>
  <type>groebner</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>println</title>
  <short_description>print the value of an expression</short_description>
<syntax>
println E_1,...,E_n
PrintLn E_1,...,E_n
</syntax>
<description>
This command is equivalent to <ttref>print</ttref> with a final newline;
in other words, it prints the values of its arguments, then moves the
cursor to the next line.
<example>
/**/  for i := 1 to 3 do  print i;  endfor;
123

/**/  for i := 1 to 3 do  println i;  endfor;
1
2
3
</example>
</description>
<seealso>
  <see>print</see>
  <see>print on</see>
</seealso>
<types>
  <type>io</type>
  <type>printing</type>
</types>
<keys>
  <key>printing</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PrintRes</title>
  <short_description>print free resolution</short_description>
  
<syntax>
PrintRes(M)
</syntax>
<description>
This function prints the minimal free resolution of <tt>M</tt>.
(see <ttref>res</ttref>).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x, y, z^2);
/**/  RES := res(I);
/**/  PrintRes(I);   -- recomputes resolution
0 --> R(-4) --> R(-2)(+)R(-3)^2 --> R(-1)^2(+)R(-2)
/**/  PrintRes(RES); -- just prints RES
0 --> R(-4) --> R(-2)(+)R(-3)^2 --> R(-1)^2(+)R(-2)
/**/  PrintBettiDiagram(RES); -- just prints the BettiDiagram for RES
        0    1    2
--------------------
  1:    2    1    -
  2:    1    2    1
--------------------
Tot:    3    3    1
</example>
</description>
<seealso>
  <see>PrintBettiDiagram</see>
  <see>PrintBettiMatrix</see>
  <see>res</see>
</seealso>
<keys>
  <key>resolutions</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>product</title>
  <short_description>the product of the elements of a list</short_description>

<syntax>
product(L: <type>LIST</type>): <rtn>OBJECT</rtn>
product(L: <type>LIST</type>, InitVal: <type>OBJECT</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
This function returns the product of the objects in the list <tt>L</tt> (together
with <tt>InitVal</tt>, if specified).  When writing a program, if the list <tt>L</tt>
may be empty, you must specify <tt>InitVal</tt>.


<example>
/**/  Use R ::= QQ[x,y];
/**/  product([3, x, y^2]);
3*x*y^2

/**/  product(1..40) = factorial(40);
true

/**/  product([]);  -- gives 1 of type INT
1
/**/  product([], y);
y
/**/  product([3, x], y);
3*x*y
</example>
</description>


<seealso>
  <see>Algebraic Operators</see>
  <see>sum</see>
</seealso>

<types>
  <type>IDEAL</type>
  <type>INT</type>
  <type>MAT</type>
  <type>RINGELEM</type>
  <type>RAT</type>
  <type>MODULEELEM</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>protect</title>
  <short_description>protect a variable from being overwritten</short_description>
<syntax>
protect X;
protect X : reason;
  where reason: <type>STRING</type>
</syntax>
<description>
This command protects the variable <tt>X</tt> from being assigned to.
Attempting to assign to it will produce an error; if a <tt>reason</tt>
(STRING) was given it is printed in the error message.
<example>
/**/  MaxSize := 99;
/**/  protect MaxSize : "size limit for fast computation";
-- /**/  MaxSize := 1000; --> !!! ERROR !!!
ERROR: Cannot set "MaxSize" (size limit for fast computation)

/**/  unprotect MaxSize;  --> remove protection, X may be assigned to now
/**/  MaxSize := 1000; --> OK
</example>
</description>

<seealso>
  <see>unprotect</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>PthRoot</title>
  <short_description>Compute p-th root</short_description>

<syntax>
PthRoot(X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the p-th root of a polynomial over a finite
field.  If no p-th root exists then an error is signalled.  p is
the characteristic of the field.

<example>
/**/  Use R ::= ZZ/(7)[x,y];
/**/  F := x^7-y^14+3;
/**/  PthRoot(F);
-y^2+x+3
</example>
</description>


<seealso>
  <see>IsFiniteField</see>
  <see>IsPthPower</see>
</seealso>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>Q</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>QQ</title>
  <short_description>the ring of rationals</short_description>
  
<syntax>
QQ
</syntax>
<description>
This system variable is constant; its value is the field of rationals.
Its name is protected so that it cannot be re-assigned to any other value.
<example>
/**/ Use QQ;

/**/ type(5);
INT
/**/ type(RingElem(QQ, 5));
RINGELEM
</example>
</description>
<seealso>
  <see>ZZ</see>
  <see>NewQuotientRing</see>
</seealso>
<keys>
  <key>field of rationals</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>quit</title>
  <short_description>quit CoCoA</short_description>

<syntax>
quit
</syntax>
<description>
This command is used to quit CoCoA.  It may be used only at top level.
</description>


<seealso>
  <see>ciao</see>
</seealso>

<types>
  <type>system</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>QuotientBasis</title>
  <short_description>vector space basis for zero-dimensional quotient rings</short_description>

<syntax>
QuotientBasis(I: <type>IDEAL</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function determines a vector space basis (of power products)
for the quotient space associated to a zero-dimensional ideal.
That is, if R is a polynomial ring with field of coefficients k, and
I is a zero-dimensional ideal in R then QuotientBasis(I) is a set of
power products forming a k-vector space basis of R/I.
<par/>
The actual set of power products chosen depends on the term ordering
in the ring R: the power products chosen are those not divisible by
the leading term of any member of the reduced Groebner basis of I
(and consequently they form a factor-closed set).

<example>
/**/  Points := [[Rand(-9,9) | N In 1..3] | S In 1..25];
/**/  Use P ::= QQ[x,y,z];
/**/  I := IdealOfPoints(P, mat(QQ, Points));
/**/  QuotientBasis(I);
[1, z, z^2, z^3, z^4, y, y*z, y*z^2, y*z^3, y^2, y^2*z, y^2*z^2, y^3, x,
x*z, x*z^2, x*z^3, x*y, x*y*z, x*y*z^2, x*y^2, x^2, x^2*z, x^2*y, x^3]

/**/  Use P ::= QQ[x,y,z], Lex;
/**/  I := IdealOfPoints(P, mat(QQ,Points));
/**/  QuotientBasis(I);     -- power products underneath the Lex reduced GBasis
[1, z, z^2, z^3, z^4, z^5, z^6, z^7, z^8, z^9, z^10, z^11, z^12, y, y*z,
y*z^2, y*z^3, y*z^4, y*z^5, y*z^6, y^2, y^2*z, y^2*z^2, y^2*z^3, y^3]
</example>
</description>

<seealso>
  <see>IdealOfPoints</see>
  <see>IsFactorClosed</see>
</seealso>

<keys>
  <key>points</key>
  <key>quotient basis</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>QZP</title>
  <short_description>change field for polynomials and ideals</short_description>

<syntax>
QZP(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
QZP(F: <type>LIST</type> of POLY): <rtn>LIST</rtn> of POLY
QZP(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
The functions <tt>QZP</tt> and <ttref>ZPQ</ttref> map polynomials and
ideals of other rings into ones of the current ring.
When mapping from one ring to another, one of the rings must have
coefficients in the rational numbers and the other must have
coefficients in a finite field.  The indeterminates in both
rings must be identical.
<par/>
The function <tt>QZP</tt> maps polynomials with rational coefficients to
polynomials with coefficients in a finite field; the function <ttref>ZPQ</ttref>
does the reverse, mapping a polynomial with finite field coefficients
into one with rational (actually, integer) coefficients.  The function
<ttref>ZPQ</ttref> is not uniquely defined mathematically, and currently for each
coefficient the least non-negative equivalent integer is chosen.
Users should not rely on this choice, though any change will be
documented.

<example>
  Use R ::= QQ[x,y,z];
  F := 1/2*x^3 + 34/567*x*y*z - 890; -- a poly with rational coefficients
  Use S ::= ZZ/(101)[x,y,z];
  QZP(F);                            -- compute its image with coeffs in ZZ/(101)
-50x^3 - 19xyz + 19
-------------------------------
  G := It;
  Use R;
  ZPQ(G);                      -- now map that result back to QQ[x,y,z]
                               -- it is NOT the same as F...
51x^3 + 82xyz + 19
-------------------------------
  H := It;
  F - H;                       -- ... but the difference is divisible by 101
-101/2x^3 - 46460/567xyz - 909
-------------------------------
  Use S;
  QZP(H) - G;                  -- F and H have the same image in ZZ/(101)[x,y,z]
0
-------------------------------
</example>
</description>


<seealso>
  <see>Accessing Other Rings</see>
  <see>BringIn</see>
</seealso>

<keys>
  <key>change ring</key>
  <key>author: john abbott</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>R</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>radical</title>
  <short_description>radical of an ideal</short_description>

<syntax>
radical(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function computes the radical of I using the algorithm described
in the paper
<par/>
  M. Caboara, P.Conti and C. Traverso: <em>Yet Another Ideal
  Decomposition Algorithm.</em> Proc. AAECC-12, pp 39-54, 1997, Lecture
  Notes in Computer Science, n.1255 Springer-Verlag.
<par/>
NOTE: at the moment, this implementation works only if the coefficient
ring is the rationals or has large enough characteristic.

<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x,y)^3;
/**/  radical(I);
ideal(y, x)
</example>
</description>


<seealso>
  <see>IsInRadical</see>
  <see>EquiIsoDec</see>
  <see>RadicalOfUnmixed</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RadicalOfUnmixed</title>
  <short_description>radical of an unmixed ideal</short_description>

<syntax>
RadicalOfUnmixed(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function computes the radical of an unmixed ideal.
<par/>
NOTE: at the moment, this implementation works only if the coefficient
ring is the rationals or has large enough characteristic.

<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x^2 - y^2 - 4*x + 4*y, x - 2);
/**/  RadicalOfUnmixed(I);
ideal(x^2 -y^2 -4*x +4*y, x -2, y -2)
/**/ interreduced(gens(It)); -- the result may not be in its simplest form
[y -2, x -2]
</example>
</description>


<seealso>
  <see>EquiIsoDec</see>
  <see>radical</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>random</title>
  <short_description>random integer</short_description>

<syntax>
random(X: <type>INT</type>, Y: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
The function returns a random integer between X and Y, inclusive.  The range
|X-Y| should be less than <formula>2^33</formula> to assure a more random distribution.
<par/>
NB: every time you restart CoCoA the sequence of random numbers will
be the same (as happens in many programming languages).  If you want better
randomness, see <ttref>seed</ttref>.

<example>
/**/  random(1,100);
6

/**/  random(-10^4,0);
-3263
</example>
</description>


<seealso>
  <see>randomize</see>
  <see>randomized</see>
  <see>seed</see>
</seealso>

<types>
  <type>miscellaneous</type>
</types>

<keys>
  <key>random</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>randomize</title>
  <short_description>randomize the coefficients of a given polynomial</short_description>

<syntax>
Randomize(V: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED: use random *****
<par/>
This function replaces the coefficients of terms of the polynomial
contained in V with randomly generated coefficients.  The result is
stored in V, overwriting the original polynomial.
<par/>
Note: It is possible that some coefficients will be replaced by
zeroes, i.e., some terms from the original polynomial may disappear in
the result.
<par/>
The similar function <ttref>randomized</ttref> performs the same operation,
but returns the randomized polynomial without modifying the argument.
<par/>
NB: every time you restart CoCoA the sequence of random numbers will
be the same (as in other programming languages).  If you want total
randomness read <ttref>seed</ttref>.

<example>
  Use R ::= QQ[x];
  F := 1+x+x^2;
  Randomized(F);
-2917104644x^2 + 3623608766x - 2302822308
-------------------------------
  F;
x^2 + x + 1
-------------------------------
  Randomize(F);
  F;
-1010266662x^2 + 1923761602x - 4065654277
-------------------------------
</example>
</description>


<seealso>
  <see>random</see>
  <see>randomized</see>
  <see>seed</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>randomized</title>
  <short_description>randomize the coefficients of a given polynomial</short_description>

<syntax>
Randomized(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
Randomized(F: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED: use random *****
<par/>
This function with a polynomial argument returns a polynomial
obtained by replacing the coefficients of F with randomly generated
coefficients.  The original polynomial, F, is unaffected.  With an
integer argument, it returns a random integer.
<par/>
Note: It is possible that some coefficients will be replaced by
zeroes, i.e., some terms from the original polynomial may disappear in
the result.
<par/>
The similar function <ttref>randomize</ttref> performs the same operation,
but returns NULL and modifies the argument.
<par/>
NB: every time you restart CoCoA the sequence of random numbers will
be the same (as in other programming languages).  If you want total
randomness read <ttref>seed</ttref>.

<example>
  Use R ::= QQ[x];
  F := 1 + x + x^2;
  Randomized(F);
-2917104644x^2 + 3623608766x - 2302822308
-------------------------------
  F;
x^2 + x + 1
-------------------------------
  Randomized(23);
-3997312402
-------------------------------
  Use R ::= ZZ/(7)[x,y];
  Randomized(x^2 + 3x - 5);
3x^2 + 2x - 2
-------------------------------
</example>
</description>


<seealso>
  <see>random</see>
  <see>randomize</see>
  <see>seed</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>rank</title>
  <short_description>rank of a matrix or module</short_description>
<syntax>
rank(M: <type>MAT</type>): <rtn>INT</rtn>
rank(M: <type>MODULE</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes the rank of M.  For a module M this is defined
as the vector space dimension of the subspace generated by the generators
of M over the quotient field of the base ring -- contrast this with the
function <ttref>NumCompts</ttref> which simply counts the number of
components the module has.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  rank(IdentityMat(R, 4));
4

  Rank(Module([x,y,z,0])); --***WORK IN PROGRESS***
1
-------------------------------
  Rank(Module([[1,2,3],[2,4,6]]));   --***WORK IN PROGRESS***
1
-------------------------------
  Rank(Module([[1,2,3],[2,5,6]]));   --***WORK IN PROGRESS***
2
-------------------------------
</example>
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RationalAffinePoints</title>
  <short_description>Affine rational solutions</short_description>
<syntax>
RationalAffinePoints(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of LIST of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the list of affine rational solutions (points) of a
0-dimensional polynomial system <tt>L</tt>.
See also <ttref>RationalSolve</ttref>
<example>
/**/ Use QQ[x,y,z];
/**/ L := [x^3-y^2+z-1, x-2, (y-3)*(y+2)];
/**/ RationalAffinePoints(L);
[[2, -2, -3], [2, 3, 2]]
</example>
</description>
<seealso>
  <see>LinSolve</see>
  <see>RationalSolve</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RationalProjectivePoints</title>
  <short_description>Projective rational solutions</short_description>
<syntax>
RationalProjectivePoints(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of LIST of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the list of projective rational solutions (points) of a
0-dimensional polynomial system <tt>L</tt>.
See also <ttref>RationalSolve</ttref>
<example>
/**/ Use QQ[x,y,z];
/**/ L := [x^3-y^2*x, x-2*z];
/**/ RationalProjectivePoints(L);
[[0, 1, 0], [1, -1, 1/2], [1, 1, 1/2]]
</example>
</description>
<seealso>
  <see>LinSolve</see>
  <see>RationalSolve</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RationalSolve</title>
  <short_description>Rational solutions for polynomial system</short_description>
<syntax>
RationalSolve(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of LIST of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the list of rational solutions (points) of a
0-dimensional polynomial system <tt>L</tt> (see also <ttref>ApproxSolve</ttref>).
Tries to be clever: if some indeterminates do not appear in <tt>L</tt>
they are ignored, if the polynomials in <tt>L</tt> are homogeneous it
returns the projective points.
<example>
/**/ Use QQ[x,y,z];
/**/ L := [x^3-y^2+z-1, x-2, (y-3)*(y+2)];
/**/ RationalSolve(L);
[[2, -2, -3], [2, 3, 2]]

/**/ L := [x^3-y^2+z-1, x^2-2, (y-3)*(y+2)];
/**/ RationalSolve(L);
[]
/**/ len(ApproxSolve(L));
4

/**/ L := [x^3-y^2+1, (y-3)*(y+2)];  -- ignores the indeterminate z
/**/ RationalSolve(L);
[[2, 3]]
</example>
</description>
<seealso>
  <see>ApproxSolve</see>
  <see>LinSolve</see>
  <see>RationalAffinePoints</see>
  <see>RationalProjectivePoints</see>
</seealso>
<keys>
  <key>polynomial system solving</key>
  <key>polynomialsystemsolving</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RatReconstructByContFrac, RatReconstructByLattice</title>
  <short_description>rational reconstruction from modular image</short_description>
<syntax>
RatReconstructByContFrac(X: <type>INT</type>, M: <type>INT</type>): <rtn>RECORD</rtn>
RatReconstructByContFrac(X: <type>INT</type>, M: <type>INT</type>, threshold: <type>INT</type>): <rtn>RECORD</rtn>
RatReconstructByLattice(X: <type>INT</type>, M: <type>INT</type>): <rtn>RECORD</rtn>
RatReconstructByLattice(X: <type>INT</type>, M: <type>INT</type>, threshold: <type>INT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
These functions attempt to reconstruct rational numbers from a modular image
<tt>X mod M</tt>.  The algorithms are fault-tolerant: they will succeed provided
that <tt>X</tt> is correct modulo a sufficiently large factor of <tt>M</tt>.

The result is a record: the boolean field <tt>failed</tt> is <tt>true</tt> if no
"convincing" result was found; otherwise it is <tt>false</tt>, and a second field,
called <tt>ReconstructedRat</tt>, contains the value reconstructed.

An optional third argument, <tt>threshold</tt>, determines what "convincing" means:
a higher value gives a more reliable answer, but may need a larger modulus
before the answer is found.

There are two different underlying heuristic algorithms: a faster one based on
continued fractions, and a slower one based on 2-dimensional lattice reduction.
See arXiv: <tt>http://arxiv.org/abs/1303.2965</tt>

<example>
/**/  X := 3333333333;
/**/  M := 10^10;
/**/  RatReconstructByContFrac(X,M);
record[ReconstructedRat := -1/3, failed := false]

/**/  X := 3141592654;
/**/  M := 10^10;
/**/  RatReconstructByContFrac(X,M);
record[failed := true]
</example>
</description>
<seealso>
  <see>RatReconstructWithBounds</see>
  <see>CRT</see>
</seealso>
<keys>
  <key>rational reconstruction</key>
  <key>fault-tolerant</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RatReconstructWithBounds</title>
  <short_description>deterministic rational reconstruction from modular image</short_description>
<syntax>
RatReconstructWithBounds(e: <type>INT</type>, P: <type>INT</type>, Q: <type>INT</type>, res: <type>LIST</type> of INT, mod: <type>LIST</type> of INT): <rtn>RECORD</rtn>
</syntax>
<description>
This function attempts to reconstruct a rational number from a collection of
residue-modulus pairs <tt>(res[i],mod[i])</tt>.  The function also requires the
input of three bounds: <tt>e</tt> is an upper bound on the number of bad moduli,
and <tt>P</tt> and <tt>Q</tt> are upper bounds for (respectively the numerator
and denominator of) the rational to be reconstructed.
<par/>
The result is a record: the boolean field <tt>failed</tt> is <tt>true</tt> if no
result exists; otherwise it is <tt>false</tt>, and a second field, called <tt>ReconstructedRat</tt>,
contains the value reconstructed.

<example>
/**/  moduli := [11,13,15,17,19];
/**/  residues := [-2, -5, 0, 7, 4];
/**/  RatReconstructWithBounds(1,10,10,residues,moduli);
record[ReconstructedRat := 1/5, failed := false]

/**/  RatReconstructWithBounds(0,10,10,residues,moduli);
record[failed := true]
</example>
</description>
<seealso>
  <see>CRT</see>
  <see>RatReconstructByContFrac, RatReconstructByLattice</see>
</seealso>
<keys>
  <key>rational reconstruction</key>
  <key>fault-tolerant</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ReadExpr</title>
  <short_description>Read RINGELEM expression from string</short_description>
<syntax>
ReadExpr(R: <type>RING</type>, expr: <type>STRING</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function reads a <tt>RINGELEM</tt> expression from a <tt>STRING</tt>.
It is handy to input elements defined in different rings without
calling <ttref>use</ttref>.
<example>
/**/  P ::= QQ[a,b];
/**/  S := NewPolyRing(NewFractionField(P), ["x", "y"]);
/**/  ReadExpr(S, "(a^2-b^2)*(x+y)/(a+b)");
(a -b)*x +(a -b)*y
</example>
</description>
<seealso>
  <see>RingElem</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RealRootRefine</title>
  <short_description>refine a real root of a univariate polynomial</short_description>

<syntax>
RealRootRefine(Root: <type>RECORD</type>, Precision: <type>RAT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function computes a refinement of a real root of a univariate
polynomial over QQ to the desired precision (width of isolating
interval).  The starting root must be a record produced by <ttref>RealRoots</ttref>.

<example>
/**/  RR := RealRoots(x^2-2);
/**/  RealRootRefine(RR[1], 1/2);
record[CoeffList := [-1, 0, 2], inf := -3/2, sup := -5/4]

/**/  RR := [RealRootRefine(Root, 10^(-20)) | Root In RR];
/**/  FloatStr(RR[1].inf);
-1.414213562*10^0
</example>
</description>


<seealso>
  <see>RealRoots</see>
  <see>RealRootsApprox</see>
  <see>RootBound</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RealRoots</title>
  <short_description>computes the real roots of a univariate polynomial</short_description>

<syntax>
RealRoots(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
RealRoots(F: <type>RINGELEM</type>, Precision: <type>RAT</type>): <rtn>LIST</rtn>
RealRoots(F: <type>RINGELEM</type>, Precision: <type>RAT</type>, Interval:[RAT, RAT]): <rtn>LIST</rtn>
</syntax>
<description>
This function computes isolating intervals for the real roots of a
univariate polyomial over QQ.
It returns the list of the real roots, where a root is represented as
a record containing either the exact root (if the fields <tt>inf</tt>
and <tt>sup</tt> are equal), or an open interval (inf, sup) containing
the root.
A third field (called CoeffList) has an obscure meaning.
<par/>
An optional second argument specifies the maximum width an isolating
interval may have.  An optional third argument specifies a closed
interval in which to search for roots.
<par/>
The interval represented by a root record may be refined by using the
function <ttref>RealRootRefine</ttref>.
The function <ttref>RealRootsApprox</ttref> may be more useful to you:
it produces rational approximations to the real roots (but these
cannot later be refined).
<example>
/**/  indent(RealRoots(x^2-2));
[
  record[CoeffList := [-1, 0, 2], inf := -4, sup := 0],
  record[CoeffList := [1, 0, -2], inf := 0, sup := 4]
]

/**/  RR := RealRoots((x^2-2)*(x-1), 10^(-5));
/**/  FloatStr(RR[1].inf);  -- left end of interval
-1.414213562*10^0

/**/  FloatStr(RR[1].sup);  -- right end of interval
-1.414213561*10^0

/**/  RR := RealRoots(x^2-2, 10^(-20), [0, 2]);

/**/  RR[1].inf;                -- incomprehensible
60153992292001127886258443119406264231/42535295865117307932921825928971026432
/**/  FloatStr(RR[1].inf, 20);  -- comprehensible
1.4142135623730950488*10^0
</example>
</description>

<seealso>
  <see>RealRootRefine</see>
  <see>RealRootsApprox</see>
  <see>RootBound</see>
</seealso>


<keys>
  <key>author: john abbott</key>
  <key>solve</key>
  <key>solutions</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RealRootsApprox</title>
  <short_description>computes approximations to the real roots of a univariate polynomial</short_description>

<syntax>
RealRootsApprox(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
RealRootsApprox(F: <type>RINGELEM</type>, Precision: <type>RAT</type>): <rtn>LIST</rtn>
RealRootsApprox(F: <type>RINGELEM</type>, Precision: <type>RAT</type>, Interval:[RAT, RAT]): <rtn>LIST</rtn>
</syntax>
<description>
This function computes rational approximations to the real roots of a
univariate polyomial (with rational coefficients).
<par/>
An optional second argument specifies the maximum separation between
the approximations produced and the corresponding exact root.  An
optional third argument specifies a closed interval in which to search
for roots.

<example>
/**/  RealRootsApprox(x^2-2);
[-3037000499/2147483648, 3037000499/2147483648]

/**/  RR := RealRootsApprox(x^2-2, 10^(-15), [0, 2]);
/**/  RR;
[6521908912666391107/4611686018427387904]

/**/  FloatStr(RR[1], 15);
1.41421356237310*10^0
</example>
</description>


<seealso>
  <see>RealRoots</see>
  <see>RootBound</see>
</seealso>
<keys>
  <key>author: john abbott</key>
  <key>solve</key>
  <key>solutions</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>record</title>
  <short_description>create a record</short_description>
<syntax>
record[F_1 := OBJECT,..., F_n := OBJECT]
  where each F_i is a field name
  returns <rtn>RECORD</rtn>
</syntax>
<description>
This constructor creates a record with fields called <tt>F_1</tt>,...,<tt>F_n</tt>.  
The empty record is given by <tt>record[]</tt>.

Records in CoCoA are <em>open</em> in the sense that new fields may be
added after the record is first defined.
The names allowed for the fields are the same as those allowed for variables.
<par/>
The dot operator is used to access the fields in a record.
<example>
/**/  P := record[height := 10, width := 5];
/**/  P.height * P.width;
50

/**/  P.area := It;  --> creates a new field called "area"
/**/  P;
record[area := 50, height := 10, width := 5]
</example>
</description>
<seealso>
  <see>record field selector</see>
  <see>fields</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>record field selector</title>
  <short_description>select a field of a record</short_description>
<syntax>
R.FieldName
R["FieldName"]
  where R is a <type>RECORD</type>
</syntax>
<description>
A record is a data structure containing named entries.  They are created
using the command <ttref>record</ttref>.  Each entry may be selected
using the "dot operator", or equivalently a string index.
<example>
/**/  rec := record[name := "David", year := 1961];
/**/  rec.name;
David

/**/  rec.year := 1849;             --> change value of a field
/**/  rec.surname := "Copperfield"; --> create a new field
/**/  rec["year"];  -- alternative syntax
1849

/**/  foreach F in fields(rec) do print rec[F]; endforeach;
DavidCopperfield1849
</example>
</description>
<seealso>
  <see>record</see>
</seealso>
<keys>
  <key>dot</key>
  <key>dot operator</key>
  <key>field index</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ReducedGBasis</title>
  <short_description>compute reduced Groebner basis</short_description>

<syntax>
ReducedGBasis(I: <type>IDEAL</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
ReducedGBasis(I: <type>MODULE</type>): <rtn>LIST</rtn> of <rtn>MODULEELEM</rtn>
</syntax>
<description>
This function returns a list whose components form a reduced Groebner basis
for the ideal (or module) <tt>I</tt> with respect to the term-ordering of the
polynomial ring of <tt>I</tt>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x^4-x^2, x^3-y);
/**/  ReducedGBasis(I);
[x*y -y^2, x^2 -y^2, y^3 -y]
</example>
</description>
<seealso>
  <see>GBasis</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>grobner basis</key>
  <key>groebner basis</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ref</title>
  <short_description>passing function parameters by reference</short_description>
<syntax>
ref X
  where X is the identifier of a CoCoA variable.
</syntax>
<description>
The keyword <tt>ref</tt> is used to pass a parameter "by reference" to a
function which may modify its value (<i>e.g.</i> <ttref>append</ttref>).
The keyword <tt>ref</tt> alerts the programmer to the possibility that the
value may be changed during the call.
<par/>
To write a new function which can modify some parameters use the same
keyword <tt>ref</tt> to identify which formal parameters are to be passed
by reference.  The following example illustrates the difference between
passing by reference and passing by value.
<example>
/**/ Define CallByRef(ref L)  -- "call by reference": The variable referred
/**/   L := "new value";       -- to by L is changed.
/**/ EndDefine;
/**/ M := "old value";
/**/ CallByRef(ref M);  -- here "ref" recalls that M might change
/**/ PrintLn M;
new value

/**/ Define CallByVal(L)  -- "call by value": The value of L is passed to
/**/   L := "new value";  -- the function.
/**/   Return L;
/**/ EndDefine;
/**/ L := "old value";
/**/ CallByVal(L);
new value

/**/  PrintLn L;
old value
</example>
</description>
<seealso>
  <see>define</see>
</seealso>
<types>
  <type>FUNCTION</type>
</types>
<keys>
  <key>var</key>
  <key>reference</key>
  <key>pointer</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RefineGCDFreeBasis</title>
  <short_description>refine an integer GCD free basis</short_description>

<syntax>
RefineGCDFreeBasis(B: <type>LIST</type> of <type>INT</type>, N: <type>INT</type>): <rtn>LIST</rtn> of <type>INT</type>
</syntax>
<description>
This function computes a refined GCD free basis by adjoining a given
integer to it.  The value returned is [NewB, N2] where NewB is the
refined basis and N2 is the part of N coprime to every element of B.

<example>
/**/  B := GCDFreeBasis([Fact(10), binomial(20,10)]);  B;
[14175, 4, 46189]

/**/  RefineGCDFreeBasis(B, 15);
[[7, 3, 5, 4, 46189], 1]
</example>
</description>


<seealso>
  <see>GCDFreeBasis</see>
</seealso>
<keys>
  <key>greatest common divisor</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Reg, Reg5</title>
  <short_description>Castelnuovo-Mumford regularity of a module</short_description>

<syntax>
Reg(M: <type>IDEAL</type> or TAGGED("Quotient")): <rtn>INT</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
These functions computes the Castelnuovo-Mumford regularity of a module.
The implementation of <tt>Reg</tt> is just implementation of the
definition (i.e. computes the resolution).
The implementation of <tt>Reg5</tt> implements Bermejo-Gimenez
Algorithm and uses functions from the CoCoAServer (linked with the
Frobby library).  This algorithm has a chance when the computation of the
resolution is unfeasable.

<par/>
Note: this is different from <ttref>RegularityIndex</ttref>, the regularity
of a Hilbert Function.

<example>
  Use R ::= QQ[x,y,z];
  I := ideal(x^3, y^2);
  Res(I);
0 --> R(-5) --> R(-2)(+)R(-3)
-------------------------------
  BettiDiagram(I);
        0    1
---------------
 2:     1    -
 3:     1    -
 4:     -    1
---------------
Tot:    2    1
-------------------------------
  Reg(I);
4
-------------------------------
  Reg(R/I);
3
-------------------------------
  Reg5(I);
4
-------------------------------
</example>
</description>


<seealso>
  <see>res</see>
  <see>PrintRes</see>
  <see>PrintBettiDiagram</see>
  <see>PrintBettiMatrix</see>
  <see>RegularityIndex</see>
</seealso>
<keys>
  <key>castelnuovo-mumford regularity</key>
  <key>castelnuovomumford regularity</key>
</keys>

</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RegularityIndex</title>
  <short_description>regularity index of a Hilbert function or series</short_description>
<syntax>
RegularityIndex(R: <type>RING</type> or TAGGED("Quotient")): <rtn>INT</rtn>
</syntax>
<description>
This function computes the regularity index of a Hilbert function.
The input might be expressed as a Hilbert function or as the
corresponding Hilbert series (computed with standard weights).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  Quot := R/ideal(x^3, y^2);
/**/  HilbertFn(Quot);
H(0) = 1
H(1) = 3
H(2) = 5
H(t) = 6   for t >= 3
/**/  RegularityIndex(HilbertFn(Quot));
3
/**/  RegularityIndex(HilbertSeries(Quot));
3
</example>
</description>
<seealso>
  <see>HilbertFn</see>
  <see>HilbertSeries</see>
</seealso>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RelNotes</title>
  <short_description>print the release notes</short_description>

<syntax>
RelNotes()
</syntax>
<description>
This function prints the release notes of the version you are running.
<example>
  RelNotes();
</example>
</description>

<keys>
  <key>release notes</key>
  <key>rel notes</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ReloadMan</title>
  <short_description>Reload CoCoAManual/CoCoAHelp.xml</short_description>
<syntax>
ReloadMan()
</syntax>
<description>
This function reloads the xml source of the manual <tt>CoCoAHelp.xml</tt>
(in directory <tt>CoCoAManual</tt>) and recreates the internal manual
index in a running CoCoA-5 (instead of closing and re-opening CoCoA....).
<par/>
It is useful <em>only for developers</em> working on the manual and making
substantial changes to <tt>CoCoAHelp.xml</tt>.
<par/>
After adding a new entry the index needs updating, but
if the change is just in the description of an existing entry (so the
internal index is still valid) there is no need to reload the manual:
the description is always searched in the current file.
<example>
/**/  ReloadMan();
</example>
</description>
<keys>
  <key>reload manual</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>remove</title>
  <short_description>remove an object in a list</short_description>
<syntax>
remove(ref L:<type>LIST</type>, N: <type>INT</type>)
</syntax>
<description>
This function removes the <tt>N</tt>-th component from <tt>L</tt>; it changes the value of <tt>L</tt>.
Use the function <ttref>WithoutNth</ttref> to create a new list containing the
elements of <tt>L</tt> except the <tt>N</tt>-th (without changing <tt>L</tt>).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  L := indets(R);
/**/  L;
[x, y, z]

/**/  remove(ref L,2);
/**/  L;
[x, z]
</example>
</description>

<seealso>
  <see>WithoutNth</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>repeat</title>
  <short_description>loop command</short_description>
<syntax>
repeat C until B
repeat C endrepeat
(where C is a sequence of commands and B is BOOL)
</syntax>
<description>
In the first form, the command sequence <tt>C</tt> is repeated until <tt>B</tt>
evaluates to <tt>false</tt>.
Unlike the <ttref>while</ttref> command, <tt>C</tt> is executed at least once.
Note that there is no <tt>endrepeat</tt> following <tt>B</tt>.
<example>
/**/      Define GCD_Euclid(A, B)
/**/        Repeat
/**/          R := mod(A, B);
/**/          A := B;
/**/          B := R;
/**/         Until B = 0;
/**/        Return A;
/**/      EndDefine;

/**/  GCD_Euclid(6,15);
3

/**/  N := 0;
/**/  repeat 
/**/    N := N+1;
/**/    PrintLn N;
/**/    If N > 5 Then Break; EndIf;
/**/  endrepeat;
1
2
3
4
5
</example>
</description>
<seealso>
  <see>for</see>
  <see>foreach</see>
  <see>while</see>
</seealso>
<types>
  <type>command</type>
  <type>programming</type>
  <type>loops</type>
</types>
<keys>
  <key>until</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>res</title>
  <short_description>free resolution</short_description>  
<syntax>
res(M: <type>IDEAL</type>): <rtn>LIST</rtn>
res(M: <type>MODULE</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the minimal free resolution of <tt>M</tt>.
<tt>res</tt> only works in the homogeneous context, and the coefficient ring
must be a field.
<par/>
NOTE: the current implementation (CoCoA-5.1.0) is very naive so it
might be very slow (better slow than nothing?).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x, y, z^2);
/**/  PrintRes(R/I);
0 --> R(-4) --> R(-2)(+)R(-3)^2 --> R(-1)^2(+)R(-2) --> R
/**/  indent(Res(R/I),2);
[
  QuotientRing(RingDistrMPolyClean(QQ, 3), ideal(x, y, z^2)),
  ideal(
    y,
    x,
    z^2
  ),
  SubmoduleRows(F, matrix([
    [x, -y, 0],
    [0, z^2, -x],
    [z^2, 0, -y]
  ])),
  SubmoduleRows(F, matrix([
    [z^2, y, -x]
  ]))
]
</example>
</description>
<seealso>
  <see>PrintBettiDiagram</see>
  <see>PrintBettiMatrix</see>
  <see>PrintRes</see>
</seealso>
<types>
  <type>groebner</type>
</types>
<keys>
  <key>resolutions</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Reset [OBSOLETE]</title>
  <short_description>[OBSOLETE] reset panels and random number seed to defaults</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ResetPanels [OBSOLETE]</title>
  <short_description>[OBSOLETE] reset panels to their default values</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>resultant</title>
  <short_description>the resultant of two polynomials</short_description>

<syntax>
resultant(F: <type>RINGELEM</type>, G: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the resultant of the polynomials F and G with
respect to the indeterminate X.

<example>
/**/  Use R ::= QQ[p,q,x];
/**/  F := x^3+p*x-q;   G := deriv(F, x);
/**/  resultant(F, G, x);
4*p^3 +27*q^2
</example>
</description>


<seealso>
  <see>discriminant</see>
  <see>sylvester</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>return</title>
  <short_description>exit from a function</short_description>
<syntax>
return
return E
</syntax>
<description>
This command is used to exit from a procedure/function.
The latter form returns the value of the expression E to the user.
As a safety measure all <tt>return</tt>s in a function/procedure must
be of the same kind: either they all return a value (function) or none
returns a value (procedure).
To exit from a loop see <ttref>break</ttref>.
<example>
/**/  Define Rev(L) -- reverse a list
/**/    If len(L) &lt; 2 Then Return L; EndIf;
/**/    M := Rev(Tail(L)); -- recursive function call
/**/    append(ref M, L[1]);
/**/    Return M;
/**/  EndDefine;

/**/  Rev([1,2,3,4]);
[4, 3, 2, 1]

----  mixing function/procedure returns is not allowed
-- /**/  Define AFailingExample(X)
-- /**/    If X=1 Then Return 123456;
-- /**/    Else Return; -- .....  --> !!! ERROR !!!
 ERROR: Inside a function definition all Return statements must be
  either with or without an expression
    Else Return;
         ^^^^^^^
</example>
</description>
<seealso>
  <see>break</see>
  <see>define</see>
</seealso>
<types>
  <type>command</type>
  <type>FUNCTION</type>
  <type>loops</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>reverse, reversed</title>
  <short_description>reverse a list</short_description>
<syntax>
reverse(ref L: <type>LIST</type>)
reversed(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
The the function <tt>reverse</tt> reverses the order of the elements of the
list in <tt>L</tt>; it changes the value of <tt>L</tt> and returns nothing.
The function <tt>reversed</tt> returns the reversed list without changing <tt>L</tt>.

<example>
/**/  L := [1,2,3,4];
/**/  reverse(ref L);
/**/  L;  -- L has been modified
[4, 3, 2, 1]

/**/  M := [1,2,3,4];
/**/  reversed(M);  -- the reversed list is returned
[4, 3, 2, 1]

/**/  M;  -- M has not been modified
[1, 2, 3, 4]
</example>
</description>

<seealso>
  <see>sort</see>
  <see>sorted</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RevLexMat</title>
  <short_description>matrices for std. term-orderings</short_description>

<syntax>
RevLexMat(N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix defining a standard ordering (which is
not a term-ordering!).

<example>
/**/  RevLexMat(3);
matrix([
  [0, 0, -1],
  [0, -1, 0],
  [-1, 0, 0]
])
</example>
</description>


<seealso>
  <see>OrdMat</see>
  <see>Orderings</see>
  <see>StdDegRevLexMat</see>
  <see>StdDegLexMat</see>
  <see>LexMat</see>
  <see>XelMat</see>
</seealso>
</command>
<!-- ===  COMMAND-rm Ring =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingElem</title>
  <short_description>convert an expression into a RINGELEM</short_description>

<syntax>
RingElem(R: <type>RING</type>, E: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
RingElem(R: <type>RING</type>, E: <type>INT</type>): <rtn>RINGELEM</rtn>
RingElem(R: <type>RING</type>, E: <type>RAT</type>): <rtn>RINGELEM</rtn>
RingElem(R: <type>RING</type>, E: <type>STRING</type>): <rtn>RINGELEM</rtn>
RingElem(R: <type>RING</type>, E:[STRING, INT, .., INT]): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function converts the expression E into a RINGELEM in R, if possible.
<par/>
Can be used for mapping ring element between rings when
a <ttref>CanonicalHom</ttref> exists.  For other homomorphisms
search see <ttref>RINGHOM</ttref>.
<par/>
In some cases <ttref>ReadExpr</ttref> may be handier: it reads a whole
expression <i>without function calls</i> from a <tt>STRING</tt>.
<example>
/**/  Use P ::= QQ[x,y,z];
/**/  -- RINGELEM (via CanonicalHom)
/**/  F := 2*x-3;
-- /**/  F/LC(F); -- !!! ERROR !!!  LC(F) in CoeffRing(P)
/**/  F/RingElem(P,LC(F));
x +1
-- /**/  1/x; -- !!! ERROR !!!  x in P is not invertible
/**/  K := NewFractionField(P);
/**/  1/RingElem(K, x); -- x in K is invertible
1/x

/**/  Use P ::= ZZ/(5)[x,y,z];
/**/  -- INT and RAT
/**/  RingElem(P, 7);
2
/**/  RingElem(P, 3/2);
-1

/**/  -- STRING (indet name, symbol)
/**/  S ::= QQ[x,y,z[1..4,3..7]];
/**/  7*RingElem(P, "x");  --> x as an element of P
2*x
/**/  7*RingElem(S, "x");  --> x as an element of S
7*x
/**/  7*RingElem(S, ["z",2,5]);
7*z[2,5]
/**/  ReadExpr(S, "((7/3)*z[2,5] - 1)^2" ); -- expr without function calls
49*z[2,5]^2 -14*z[2,5] +1
</example>
</description>
<seealso>
  <see>RingOf</see>
  <see>AsINT</see>
  <see>AsRAT</see>
  <see>IndetName</see>
  <see>IndetSubscripts</see>
  <see>CanonicalHom</see>
  <see>ReadExpr</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convert</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingEnv [OBSOLETE]</title>
  <short_description>[OBSOLETE] name of the ring environment</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
See <ttref>RingOf</ttref>.
</description>
<seealso>
  <see>RingOf</see>
</seealso>
</command>
<!-- ===  COMMAND-rm RingEnvs =============================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingOf</title>
  <short_description>the ring of the object</short_description>


<syntax>
RingOf(E: <type>RINGELEM</type>|<type>IDEAL</type>|<type>MAT</type>|<type>MODULE</type>): <rtn>RING</rtn>
</syntax>
<description>
This function returns the ring on which the object <tt>E</tt> is defined.
<par/>
NB A ring contains many information and two separate rings, even when
defined with the same commands, are not <quotes>equal</quotes>.
When a ring is printed only a few informations are shown, so different
rings might look the same.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x,y);  
/**/  RingOf(I);
RingDistrMPolyClean(QQ, 3)

/**/  RingOf(mat([[1,2],[3,4]]));
QQ

/**/  Use Qabc ::= QQ[a,b,c];
/**/  F := a^2+b;
/**/  G := a*b+b^2;
/**/  Use S ::=ZZ/(3)[x,y];
/**/  RingOf(F+G);  -- F+G is computed in the ring of definition
RingDistrMPolyClean(QQ, 3)
/**/  indets(RingOf(F));
[a, b, c]
</example>
</description>

<seealso>
  <see>CurrentRing</see>
  <see>RingSet</see>
  <see>BaseRing</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingQQ</title>
  <short_description>the ring of rationals</short_description>
 
<syntax>
RingQQ(): <rtn>RING</rtn>
</syntax>
<description>
This function returns the ring of rationals.
It is particularly useful when you want to use <tt>QQ</tt>
(which is a pre-defined top-level variable) inside a function.
<par/>
NB calling <tt>RingQQ</tt> twice gives the same identical ring,
whereas calling <ttref>NewPolyRing</ttref> or
<ttref>NewFractionField</ttref> return each time a new ring.
<example>
/**/  Two := RingElem(RingQQ(), 2);   Two;
2
/**/  type(Two);
RINGELEM;
/**/  RingOf(Two) = RingQQ();
true
</example>
</description>
<keys>
  <key>ring of rationals</key>
</keys>
<seealso>
  <see>TopLevel</see>
  <see>RingQQt</see>
  <see>RingZZ</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingQQt</title>
  <short_description>pre-defined polynomial rings</short_description>
 
<syntax>
RingQQt(N: <type>INT</type>): <rtn>RING</rtn>
</syntax>
<description>
This function returns a polynomial ring over <tt>QQ</tt> with indeterminates <formula>t[1]...t[N]</formula>.
In particular <tt>RingQQt(1)</tt> is the polynomial ring in which Hilbert polynomials
are defined.
<par/>
NB calling <tt>RingQQt(5)</tt> twice gives the same identical ring,
whereas calling <tt>NewPolyRing(RingQQ(), SymbolRange("t", 5))</tt>
returns each time a new ring (therefore incompatible).
<example>
/**/  QQt := RingQQt(3);  Use QQt;
/**/  (t[1]+1)^3;
t[1]^3 +3*t[1]^2 +3*t[1] +1
/**/  indets(RingQQt(1));
[t]
/**/  indets(RingQQt(5));
[t[1], t[2], t[3], t[4], t[5]]
</example>
</description>
<keys>
  <key>ring of polynomials</key>
</keys>
<seealso>
  <see>TopLevel</see>
  <see>RingQQ</see>
  <see>RingZZ</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingSet</title>
  <short_description>list of the rings of an object</short_description>

<syntax>
RingSet(E: <type>LIST</type>|<type>RINGELEM</type>|<type>IDEAL</type>|<type>MAT</type>|<type>MODULE</type>|<type>MODULEELEM</type>): <rtn>LIST</rtn> of <rtn>RING</rtn> and TYPE
</syntax>
<description>
This function returns the list of the RINGs (or types, if not
dependent from a RING) on which the object E is dependent.
Similar to <ttref>RingOf</ttref>, this function also works on lists
and returns the set of ring environments of all entries.
...needless to say that it may be quite slow on big inputs!

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  L1 := [x, y];
/**/  L2 := [x, y, 0, 5/4];
/**/  Z3 := NewRingFp(3);
/**/  Use S ::= Z3[a,b];
/**/  RingSet(L1);
[RingDistrMPolyClean(QQ, 3)]

/**/  RingSet(L2);
[RingDistrMPolyClean(QQ, 3), INT, RAT]

/**/  RingSet([L2, a+b]);
[RingDistrMPolyClean(QQ, 3), INT, RAT, RingDistrMPolyClean(FFp(3), 2)]
</example>
</description>


<seealso>
  <see>CurrentRing</see>
  <see>RingOf</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RingZZ</title>
  <short_description>the ring of integers</short_description>
 
<syntax>
RingZZ(): <rtn>RING</rtn>
</syntax>
<description>
This function returns the ring of integers.
It is particularly useful when you want to use <tt>ZZ</tt>
(which is a pre-defined top-level variable) inside a function.
<par/>
NB calling <tt>RingZZ</tt> twice gives the same identical ring,
whereas calling <ttref>NewPolyRing</ttref> or
<ttref>NewFractionField</ttref> return each time a new ring.
<example>
/**/  Two := RingElem(RingZZ(), 2);   Two;
2
/**/  type(Two);
RINGELEM;
/**/  RingOf(Two) = RingZZ();
true
/**/  RingOf(Two) = RingQQ();
false
</example>
</description>
<keys>
  <key>ring of integers</key>
</keys>
<seealso>
  <see>TopLevel</see>
  <see>RingQQt</see>
  <see>RingQQ</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RMap [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] define ring homomorphism for function image</short_description>
<syntax>
[OBSOLESCENT] RMap(L: <type>LIST</type>)): <rtn>TAGGED</rtn>("RMap")
</syntax>
<description>
[OBSOLESCENT] related with <ttref>image [OBSOLESCENT]</ttref>.
In CoCoA-5 such homomorphisms are properly implemented as <ttref>PolyAlgebraHom</ttref>.
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RootBound</title>
  <short_description>bound on roots of a polynomial over QQ</short_description>

<syntax>
RootBound(F: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
This function computes a bound on the absolute values of the complex
roots of a univariate polynomial over QQ.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  RootBound(x^2-2);
4
</example>
</description>

<seealso>
  <see>RealRootRefine</see>
  <see>RealRoots</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>round</title>
  <short_description>round to integer</short_description>

<syntax>
round(X: <type>RAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function rounds a rational to the nearest integer; halves are rounded towards zero.
<example>
/**/  round(4.56);
5

/**/  round(-1/2);
0
</example>
</description>

<seealso>
  <see>num</see>
  <see>den</see>
  <see>floor</see>
  <see>ceil</see>
</seealso>
<keys>
  <key>rounding</key>
</keys>
</command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>RowMat</title>
  <short_description>single row matrix</short_description>

<syntax>
RowMat(L: <type>LIST</type>): <rtn>MAT</rtn>
RowMat(R: <type>RING</type>, L: <type>LIST</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix whose only row consists of the
elements of the list L.
<example>
/**/  RowMat([3,4,5]);
matrix([
  [3, 4, 5]
])

/**/  RowMat(QQ,[5,6,7]);
matrix([
  [5, 6, 7]
])
</example>
</description>

<seealso>
  <see>BlockMat</see>
  <see>DiagMat</see>
  <see>ColMat</see>
</seealso>


<keys>
  <key>row matrix</key>
</keys>
</command>

</chapter_letter>
<!-- ===  CHAPTER  =============================================== -->
<chapter_letter>
  <title>S</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>saturate</title>
  <short_description>saturation of ideals</short_description>

<syntax>
saturate(I: <type>IDEAL</type>, J: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the saturation of I with respect to J: the
ideal of polynomials F such that F*G is in I for all G in <formula>J^d</formula>
for some positive integer d.
<par/>
The coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x-z, y-2*z);
/**/  J := ideal(x-2*z, y-z);
/**/  K := intersection(I, J); -- ideal of two points in the
                               -- projective plane
/**/  L := intersection(K, ideal(x,y,z)^3); -- add an irrelevant component
/**/  Hilbert(R/L);
H(0) = 1
H(1) = 3
H(2) = 6
H(t) = 2   for t &gt;= 3

/**/  saturate(L, ideal(x,y,z)) = K; -- saturating gets rid of the
                                     -- irrelevant component
true
</example>
</description>


<seealso>
  <see>colon</see>
  <see>HColon</see>
  <see>HSaturation</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ScalarProduct</title>
  <short_description>scalar product</short_description>

<syntax>
ScalarProduct(L, M): <rtn>OBJECT</rtn>
  where each of L and M is of type <type>MODULEELEM</type> or <type>LIST</type>
</syntax>
<description>
This function returns the sum of the product of the components of L
and M; precisely (len(L)=len(M)):
<par/>
  ScalarProduct(L, M) = sum([ L[I]*M[I] | I In 1..len(L) ]).
<par/>
The function works whenever the product of the components of L and M
are defined (see <ref>Algebraic Operators</ref>).

<example>
/**/  ScalarProduct([1,2,3], [5,0,-1]);
2

  Use R ::= QQ[x,y];
  ScalarProduct([ideal(x,y), ideal(x^2-xy)],[x^2,y]);
ideal(x^3, x^2y, x^2y - xy^2)
-------------------------------
</example>
</description>


<seealso>
  <see>Algebraic Operators</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ScientificStr</title>
  <short_description>convert integer/rational to a floating-point string</short_description>

<syntax>
ScientificStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>): <rtn>STRING</rtn>
ScientificStr(X: <type>INT</type>|<type>RAT</type>|<type>RINGELEM</type>, Prec: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function converts a rational number <tt>X</tt> into a (decimal)
floating-point string.  The optional second argument <tt>Prec</tt> says how many
decimal digits to include in the mantissa; the default value is 5.
Note that an exponent is always included.
<example>
/**/  ScientificStr(2/3);       -- last printed digit is rounded
6.6667*10^(-1)

/**/  ScientificStr(7^510);     -- no arbitrary limit on exponent range
1.0000*10^431

/**/  ScientificStr(1/81, 50);  -- precision of mantissa specified by user
1.2345679012345679012345679012345679012345679012346*10^(-2)

/**/  ScientificStr(1/2);       -- trailing zeroes are not suppressed
5.0000*10^(-1)
</example>
</description>

<seealso>
  <see>DecimalStr</see>
  <see>FloatStr</see>
  <see>FloatApprox</see>
  <see>MantissaAndExponent10</see>
</seealso>
<keys>
  <key>scientific notation</key>
  <key>decimal</key>
  <key>floating point</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>seed</title>
  <short_description>seed for <tt>random</tt></short_description>

<syntax>
Seed(N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function seeds the random number generator, <ttref>random</ttref>.
<par/>
NB: every time you restart CoCoA the sequence of random numbers will
be the same (as happens in many programming languages).  If you want better
randomness, see the example below.
<example>
  Seed(5);
  Rand();
1991603592
-------------------------------
  Rand();
-1650270230
-------------------------------
  Seed(5);  -- with the same seed, "Rand" generates the same sequence
  Rand();
1991603592
-------------------------------
  Rand();
-1650270230
-------------------------------
  -- Better randomness:
  -- the following shows how to make a random seed based on the date.
  D := Date();
  D;
Mon Mar 02 14:43:44 1998
-------------------------------
  Seed(Sum(Ascii(D)));
</example>
</description>


<seealso>
  <see>random</see>
</seealso>

<types>
  <type>miscellaneous</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SeparatorsOfPoints</title>
  <short_description>separators for affine points</short_description>

<syntax>
SeparatorsOfPoints(Points: <type>LIST</type>): <rtn>LIST</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in affine space.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes separators for the points: that is, for each
point a polynomial is determined whose value is 1 at that point and 0
at all the others.  The separators yielded are reduced with respect to
the reduced Groebner basis which would be found by <ttref>IdealOfPoints</ttref>.
<par/>
NOTE:
<par/>
 * the current ring must have at least as many indeterminates as the
   dimension of the space in which the points lie;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * the separators are in the same order as the points (i.e. the first
   separator is the one corresponding the first point, and so on);
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:
<verbatim>
     S := SeparatorsOfPoints(Pts);
     Foreach Element In S Do
       PrintLn Element;
     EndForeach;
</verbatim>
For separators of points in projective space, see
<ttref>SeparatorsOfProjectivePoints</ttref>.

<example>
  Use R ::= QQ[x,y];
  Points := [[1, 2], [3, 4], [5, 6]];
  S := SeparatorsOfPoints(Points);  -- compute the separators
  S;
[1/8y^2 - 5/4y + 3, -1/4y^2 + 2y - 3, 1/8y^2 - 3/4y + 1]
-------------------------------
  [[Eval(F, P) | P In Points] | F In S];  -- verify separators
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
-------------------------------
</example>
</description>


<seealso>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>Interpolate</see>
  <see>SeparatorsOfProjectivePoints</see>
</seealso>

<types>
  <type>points</type>
</types>

<keys>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SeparatorsOfProjectivePoints</title>
  <short_description>separators for projective points</short_description>

<syntax>
SeparatorsOfProjectivePoints(Points: <type>LIST</type>): <rtn>LIST</rtn>

where Points is a list of lists of coefficients representing a set of
<em>distinct</em> points in projective space.
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
This function computes separators for the points: that is, for each
point a homogeneous polynomial is determined whose value is non-zero at
that point and zero at all the others.  (Actually, choosing the values
listed in Points as representatives for the homogeneous coordinates of
the corresponding points in projective space, the non-zero value will
be 1.)  The separators yielded are reduced with respect to the reduced
Groebner basis which would be found by <ttref>IdealOfProjectivePoints</ttref>.
<par/>
NOTE:
<par/>
 * the current ring must have at least one more indeterminate than the
   dimension of the projective space in which the points lie, i.e, at
   least as many indeterminates as the length of an element of
   the input, Points;
<par/>
 * the base field for the space in which the points lie is taken to be
   the coefficient ring, which should be a field;
<par/>
 * in the polynomials returned the first coordinate in the space is
   taken to correspond to the first indeterminate, the second to the
   second, and so on;
<par/>
 * the separators are in the same order as the points (i.e. the first
   separator is the one corresponding the first point, and so on);
<par/>
 * if the number of points is large, say 100 or more, the returned
   value can be very large.  To avoid possible problems when printing
   such values as a single item we recommend printing out the elements
   one at a time as in this example:
<verbatim>
     S := SeparatorsOfProjectivePoints(Pts);
     Foreach Element In S Do
       PrintLn Element;
     EndForeach;
</verbatim>
For separators of points in affine space, see
<ttref>SeparatorsOfPoints</ttref>.

<example>
  Use R ::= QQ[x,y,z];
  Points := [[0,0,1],[1/2,1,1],[0,1,0]];
  S := SeparatorsOfProjectivePoints(Points);
  S;
[-2x + z, 2x, -2x + y]
-------------------------------
  [[Eval(F, P) | P In Points] | F In S];   -- verify separators
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
-------------------------------
</example>
</description>


<seealso>
  <see>GenericPoints</see>
  <see>IdealAndSeparatorsOfPoints</see>
  <see>IdealAndSeparatorsOfProjectivePoints</see>
  <see>IdealOfPoints</see>
  <see>IdealOfProjectivePoints</see>
  <see>Interpolate</see>
  <see>SeparatorsOfPoints</see>
</seealso>

<types>
  <type>points</type>
</types>

<keys>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND-rm Set,Unset ============================================ -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SetRow</title>
  <short_description>set a list as a row into a matrix</short_description>
<syntax>
SetRows(ref M: <type>MAT</type>, i: <type>INT</type>, L: <type>LIST</type>)
</syntax>
<description>
This procedure sets the elements in <tt>L</tt> as entries of the
<tt>i</tt>-th row in the matrix <tt>M</tt>; it returns nothing!
<example>
/**/  M := IdentityMat(QQ, 5);
/**/  SetRow(ref M, 1, [2,3,4,0,0]);
/**/  M;
matrix(QQ,
 [[2, 3, 4, 0, 0],
  [0, 1, 0, 0, 0],
  [0, 0, 1, 0, 0],
  [0, 0, 0, 1, 0],
  [0, 0, 0, 0, 1]])
</example>
</description>
<seealso>
  <see>ref</see>
  <see>GetRow</see>
  <see>SwapRows</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>shape</title>
  <short_description>extended list of types involved in an expression</short_description>

<syntax>
shape(E: <type>LIST</type>): <rtn>LIST</rtn> (of <rtn>TYPE</rtn>)
shape(E: <type>RECORD</type>): <rtn>RECORD</rtn> (of <rtn>TYPE</rtn>)
shape(E:OTHER): <rtn>TYPE</rtn>

where OTHER stands for a type which is not LIST, MAT, or RECORD.
</syntax>
<description>
This function returns the extended list of types involved in the
expression E as outlined below:
<verbatim>
type(E) = LIST
  In this case, Shape(E) is the list whose i-th component is the type
  of  the i-th component of E.

type(E) = MAT
  In this case, Shape(E) is a matrix with (i,j)-th entry equal to the
  type of the (i,j)-th entry of E.

type(E) = RECORD
  In this case, Shape(E) is a record whose fields are the types of the
  fields of E.
</verbatim>
Otherwise, <tt>Shape(E)</tt> is the type of E.

<example>
/**/  Use R ::= QQ[x];
/**/  L := [1,[1,"a"], x^2-x];
/**/  shape(L);
[INT, [INT, STRING], POLY]

/**/  R := record[name := "test", contents := L];
/**/  shape(R);
record[contents := [INT, [INT, STRING], POLY], name := STRING]

/**/  It.name;
STRING
</example>

There are undocumented functions, <tt>IsSubShape</tt> and <tt>IsSubShapeOfSome</tt>,
for determining if the <tt>shape</tt> of a CoCoA expression is a <tt>subshape</tt>
of another.  To see the code for these functions, enter
<verbatim>
  Describe Function(<quotes>$misc.IsSubShape</quotes>);
  Describe Function(<quotes>$misc.IsSubShapeOfSome</quotes>);
</verbatim>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sign</title>
  <short_description>the sign of a number</short_description>

<syntax>
sign(X: <type>INT</type>|<type>RAT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns -1 if X &lt; 0, 0 if X = 0, and 1 if X &gt; 0.
X must be INT or RAT.

<example>
/**/  sign(123);
1

/**/  sign(-5/2);
-1
</example>
</description>


</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SimplestRatBetween</title>
  <short_description>find simplest rational in a closed interval</short_description>

<syntax>
SimplestRatBetween(A: <type>RAT</type>, B: <type>RAT</type>): <rtn>RAT</rtn>
</syntax>
<description>
This function finds the simplest rational in the closed interval with end
points <tt>A</tt> and <tt>B</tt>.

<example>
/**/  SimplestRatBetween(0.123, 0.456);
1/3

/**/  SimplestRatBetween(-3.14159, -2.71828);
-3
</example>
</description>

<seealso>
  <see>CFApprox</see>
  <see>FloatApprox</see>
</seealso>

<keys>
  <key>rational approximation</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>size [OBSOLETE]</title>
  <short_description>[OBSOLETE]</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] see <ttref>len</ttref>.
</description>
<seealso>
  <see>len</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>skip</title>
  <short_description>does nothing</short_description>
<syntax>
skip
</syntax>
<description>
This command does nothing.  I suppose it might be used to make the
structure of a user-defined function more clear.  It is probably at
least as useful as the function <tt>Tao</tt>.

<example>
/**/  skip;
</example>
</description>


<types>
  <type>miscellaneous</type>
  <type>programming</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SmoothFactor</title>
  <short_description>find small prime factors of an integer</short_description>
  
<syntax>
SmoothFactor(N: <type>INT</type>, MaxP: <type>INT</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function finds the small prime factors of an integer.  It simply
tries dividing by all primes up to the given bound <tt>MaxP</tt>.
The result is a list of the prime factors found together with the
unfactored part of <code>N</code>.
Be careful about supplying large values for <tt>MaxP</tt> (e.g. greater than
a million) as the function could take a very long time.
<par/>
From version 5.0.4 the field are called <tt>factors</tt>
and <tt>multiplicities</tt> instead of  <tt>Factors</tt>
and <tt>Exponents</tt> to comply with the naming conventions.

<example>
/**/  SmoothFactor(100,3);
record[factors := [2], multiplicities := [2], RemainingFactor := 25]

/**/  SmoothFactor(123456789,3700);
record[factors := [3, 3607], multiplicities := [2, 1], RemainingFactor := 3803]
</example>
</description>

<seealso>
  <see>IsPrime</see>
  <see>IsProbPrime</see>
</seealso>
<keys>
  <key>factor</key>
  <key>factors</key>
  <key>factorise</key>
  <key>factorisation</key>
  <key>factorize</key>
  <key>factorization</key>
  <key>small prime</key>
  <key>partial factorization</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sort</title>
  <short_description>sort a list</short_description>

<syntax>
sort(V: <type>LIST</type>)

where V is a variable containing a list.
</syntax>
<description>
This function sorts the elements of the list in V with respect
to the default comparisons related to their types; it overwrites V and
returns NULL.
<par/>
For more on the default comparisons, see <ref>Relational Operators</ref>
in the chapter on operators.
For more complicated sorting, see <ttref>SortBy</ttref>, <ttref>SortedBy</ttref>.

<example>
/**/  L := [3,2,1];
/**/  sort(ref L);  -- this returns nothing and modifies L
/**/  L;
[1, 2, 3]

/**/  Use R ::= QQ[x,y,z];
/**/  L := [x,y,z];
/**/  sort(ref L);  -- this returns nothing and modifies L
/**/  L[1];
z

/**/  sorted([y, x, x^2]);   -- this returns the sorted list
[y, x, x^2]
</example>
</description>


<seealso>
  <see>Relational Operators</see>
  <see>sorted</see>
  <see>SortBy</see>
  <see>SortedBy</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SortBy</title>
  <short_description>sort a list</short_description>
<syntax>
SortBy(L: <type>LIST</type>, CmpFn: <type>FUNCTION</type>)
</syntax>
<description>
This function sorts the elements of the list in <code>L</code> with respect
to the comparisons made by <code>CmpFn</code>; it overwrites <code>L</code> and returns <code>NULL</code>.
<par/>
The comparison function <code>CmpFn</code> takes two arguments and returns <code>True</code> if the
first argument is less than the second, otherwise it returns <code>False</code>.
The sorted list is in increasing order.
<par/>
Note that to call <code>SortBy(L,CmpFn)</code> inside a function you
will need to make the name <code>CmpFn</code> accessible using <code>TopLevel CmpFn;</code>
<par/>
Note that if both <code>CmpFn(A, B)</code> and <code>CmpFn(B, A)</code> return
<code>true</code>, then <code>A</code> and <code>B</code> are viewed as being equal.
<example>
/**/  Define ByLength(S, T)    -- define the sorting function
/**/    Return len(S) &gt; len(T);
/**/  EndDefine;

/**/  M := ["bird","mouse","cat"];
/**/  SortBy(ref M, ByLength);
/**/  M;
["mouse", "bird", "cat"]
</example>
</description>
<seealso>
  <see>func</see>
  <see>sort</see>
  <see>sorted</see>
  <see>SortedBy</see>
  <see>TopLevel</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sorted</title>
  <short_description>sort a list</short_description>
<syntax>
sorted(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of the sorted elements of L without
affecting L, itself.
<par/>
For more on the default comparisons, see <ref>Relational Operators</ref>
in the chapter on operators.
For more complicated sorting, see <ttref>SortBy</ttref>, <ttref>SortedBy</ttref>.
<example>
/**/  L := [3,2,1];
/**/  sorted(L);
[1, 2, 3]

/**/  Use R ::= QQ[x,y,z];
/**/  L := [x,y,z];
/**/  sorted(L);
[z, y, x]

/**/  sorted([y, x, z, x^2]);
[z, y, x, x^2]

/**/  sorted([3, 1, 1, 2]);
[1, 1, 2, 3]

/**/  sorted(["b","c","a"]);
["a", "b", "c"]
</example>
</description>
<seealso>
  <see>Relational Operators</see>
  <see>SortBy</see>
  <see>SortedBy</see>
  <see>sort</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SortedBy</title>
  <short_description>sort a list</short_description>
<syntax>
SortedBy(L: <type>LIST</type>, F: <type>FUNCTION</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of the sorted elements of L without
affecting L, itself.  As for <ttref>SortBy</ttref>, the comparison
function F takes two arguments and returns True if the first argument
is less than the second, otherwise it returns False.  The sorted list
is in increasing order.
<par/>
Note that if both F(A, B) and F(B, A) return True, then A and B are
viewed as being equal.
<example>
/**/  Define ByLength(S, T)    -- define the sorting function
/**/    Return len(S) &gt; len(T);
/**/  EndDefine;

/**/  M := ["bird","mouse","cat"];
/**/  SortedBy(M, ByLength);
["mouse", "bird", "cat"]

/**/  M;  -- M is not changed
["bird", "mouse", "cat"]

/**/  sorted(M);  -- the function "Sort" sorts using the default ordering:
                  -- in this case, alphabetical order.
["cat", "bird", "mouse"]

/**/  SortBy(ref M, ByLength);  -- sort M in place, changing M
/**/  M;
["mouse", "bird", "cat"]
</example>
</description>
<seealso>
  <see>func</see>
  <see>sort</see>
  <see>sorted</see>
  <see>SortBy</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>source</title>
  <short_description>read commands from a file or device</short_description>

<syntax>
source S: <type>STRING</type>
</syntax>
<description>
This command executes all CoCoA commands in the file or device named
S.  A typical use of <tt>source</tt> is to collect user-defined functions and
variables in a text file, say, <tt>MyFile.coc</tt> and then execute:
<verbatim>
    source <quotes>MyFile.cocoa5</quotes>;
</verbatim>
or, equivalently, the obsolescent
<verbatim>
    &lt;&lt; <quotes>MyFile.cocoa5</quotes>;
</verbatim>
Functions and variables read in from a file in this way will erase
functions and variables with identical names that may already exist.
This can be avoided by using packages.  Repeatedly used functions can be
read into CoCoA at start-up by using <tt>source</tt> in the
<tt>userinit.coc</tt> file.
</description>


<seealso>
  <see>Introduction to IO</see>
  <see>Introduction to Packages</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SourceRegion</title>
  <short_description>read commands from a region in a file</short_description>

<syntax>
SourceRegion FromLine: <type>INT</type>,FromChar: <type>INT</type> To ToLine: <type>INT</type>,ToChar: <type>INT</type> In S: <type>STRING</type>
</syntax>
<description>
This command executes all CoCoA commands in the specified region of the given file.
It is not intended for manual use, but is used by the CoCoA UI.
<verbatim>
    SourceRegion FromLine,FromChar To ToLine,ToChar In <quotes>MyFile.cocoa5</quotes>;
</verbatim>
It is almost equivalent to copying the region into a temporary file, and then reading
that file with the <tt>source</tt> command.

Line and char indexes start from 1; the region identified starts at the "from"
line/character position and stops immediately before the "to" line/character position.
</description>


<seealso>
  <see>source</see>
</seealso>

<types>
  <type>io</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>spaces</title>
  <short_description>return a string of spaces</short_description>

<syntax>
spaces(N: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns a string consisting of N spaces.

<example>
/**/  L := "a" + Spaces(5) + "b";
/**/  L;
a     b
</example>
</description>


<seealso>
  <see>dashes</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sprint</title>
  <short_description>convert to a string</short_description>

<syntax>
sprint(E: <type>OBJECT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function takes any CoCoA expression and converts its value to a
string.  One use is to check for extremely long output before printing
in a CoCoA window.

<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x,y);
/**/  J := sprint(I);
/**/  I;
ideal(x, y)

/**/  J;        -- The output for I and J looks the same, but ...
ideal(x, y)

/**/  type(I);  -- I is an ideal, and
IDEAL

/**/  type(J);  -- J is just the string "ideal(x, y)".
STRING

/**/  J[1];  -- the 1st character of J
i

/**/  J[2];  -- the 2nd character of J
d

/**/  len(J);  -- J has 11 characters
11
</example>
</description>


<seealso>
  <see>Introduction to IO</see>
  <see>IO.SprintTrunc</see>
  <see>print</see>
  <see>println</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SqFreeFactor</title>
  <short_description>compute a squarefree factorization</short_description>

<syntax>
SqFreeFactor(F: <type>RINGELEM</type>): <rtn>RECORD</rtn>
</syntax>
<description>
Compute a factorization (of a polynomial) into coprime squarefree factors.
The factorization may sometimes be finer than necessary, i.e. two factors
could have the same multiplicity.

<example>
/**/  Use R ::= QQ[x,y];
/**/  f := (x^2-1)^2*(y+2)^3;
/**/  indent(SqFreeFactor(f));
record[
  RemainingFactor := 1,
  factors := [x^2 -1, y +2],
  multiplicities := [2, 3]
]
</example>
</description>

<seealso>
  <see>factor</see>
  <see>ContentFreeFactor</see>
</seealso>
<keys>
  <key>squarefree</key>
  <key>square-free</key>
  <key>factors</key>
  <key>factorise</key>
  <key>factorisation</key>
  <key>factorize</key>
  <key>factorization</key>
</keys>

</command>
<!-- === COMMAND =============================================== -->
 <command>
   <title>StableBBasis5</title>
   <short_description>Stable Border Basis of ideal of points</short_description>
 
 <syntax>
 StableBBasis5(Pts: <type>LIST</type>, Toler: <type>LIST</type>): <rtn>RECORD</rtn>
 StableBBasis5(Pts: <type>LIST</type>, Toler: <type>LIST</type>, Gamma: <type>RAT</type>): <rtn>RECORD</rtn>
 </syntax>
 <description>
***** NOT YET IMPLEMENTED ***** 
See <ttref>TmpNBM</ttref>
<par/>
This function returns a record containing a <em>stable order ideal</em> of
the ideal of points, and a list of <em>almost vanishing</em> polynomials.
If the cardinality of the order ideal is equal to the number of points, it
is in fact a <em>quotient basis</em>, and in this case a <em>stable border
basis</em> founded on it is also returned.  The boolean field <tt>StableBBasisFound</tt>
is set to true if a stable border basis was found, otherwise false.
<par/>
The first argument is a list of points in k-dimensional space, and the
second argument is list of k positive tolerances (one for each dimension).
The function builds the stable order ideal stepwise by testing, from a
numerical point of view, the linear dependence of a set of vectors.
So that the answer can be represented, the current ring must have at
least k indeterminates; the term ordering is ignored as it plays no role
in determining the border basis.
 <par/>
 There is a third, optional argument: it is a real non negative number
 <tt>Gamma</tt> which is used for scaling the threshold on the
 admissible perturbation of the points.
 A value of <tt>Gamma</tt> &lt;&lt; 1 should be used.  
 If no value is specified then by default <tt>Gamma</tt> = 0.1
 <par/>
 For a full description of the algorithms we refer to the paper
 J.Abbott, C.Fassino, L.Torrente
 <em>Stable Border Bases for Ideals of Points</em> (to appear in JSC
 or arXiv:07062316).
 <par/>

<example>
  Pts := [[0.1,-1],[1,1],[2,3]];
  Toler := [0.1,0.1];
  StableBBasis5(Pts, Toler);
record[
  AlmostVanishing := [ (...) ],
  BBasis := [
    -3602879701896397/288230376151711744y^2 + x -
  32425917317067571/72057594037927936y -
  154923827181545063/288230376151711744,
    xy - 140512308373959475/288230376151711744y^2 -
  39631676720860365/72057594037927936y +
  10808639105689191/288230376151711744,
    y^3 - 3y^2 - y + 3,
    xy^2 - 580063632005319885/288230376151711744y^2 -
  32425917317067571/72057594037927936y +
  421536925121878425/288230376151711744],
  SOI := [1, y, y^2],
  StableBBasisFound := True]
-------------------------------
  Toler := [0.6, 0.6]:
  StableBBasis5(Pts, Toler);
record[AlmostVanishing := [.....], SOI := [1, y], StableBBasisFound := False]
-------------------------------
</example>
</description>
 

<seealso>
  <see>IdealOfPoints</see>
  <see>TmpNBM</see>
</seealso>
 
<keys>
   <key>abbott fassino torrente</key>
   <key>cocoalib</key>
   <key>stable border basis</key>
   <key>stable order ideal</key>
   <key>approx</key>
   <key>numerical buchbergermoeller</key>
   <key>approx</key>
</keys>
 </command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>StableIdeal</title>
  <short_description>stable ideal containing L</short_description>
<syntax>
StableIdeal(L: <type>LIST</type> of power-products): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the smallest stable ideal containing the
power-products in <tt>L</tt> (see also <ttref>StronglyStableIdeal</ttref>).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  L := [x*z^4, y^3];
/**/  StableIdeal(L);
ideal(x^2*z^3, x*y*z^3, x*z^4, x^3, x^2*y, x*y^2, y^3)
</example>
</description>
<seealso>
  <see>IsStable</see>
  <see>LexSegmentIdeal</see>
  <see>StronglyStableIdeal</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>StarPrint, StarSprint</title>
  <short_description>print polynomial with *&apos;s for multiplications</short_description>

<syntax>
StarPrint(F: <type>RINGELEM</type>)
StarPrintFold(F: <type>RINGELEM</type>, LineWidth: <type>INT</type>)
StarSprint(F: <type>RINGELEM</type>): <rtn>STRING</rtn>
StarSprintFold(F: <type>RINGELEM</type>, LineWidth: <type>INT</type>): <rtn>STRING</rtn>
</syntax>
<description>
These functions print the polynomial F with asterisks added to denote
multiplications.  They may be useful when transfering polynomials or
rational functions from CoCoA to other mathematical software (e.g. Gap,
Maple, Macaulay, Singular,..).  <tt>StarPrint</tt> inserts newline
characters (only between terms) with the aim of avoiding lines longer
than 70 characters; the second argument to <tt>StarPrintFold</tt> is for
specifying a different width limit; a non positive value is treated as
meaning no limit.  The <tt>StarSprint</tt> functions print the value into
a string.


<example>
  Use R ::= QQ[x,y];
  F := x^3+2xy-y^2;
  StarPrint(F);
1*x^3 +2*x*y -1*y^2
-------------------------------
  StarPrintFold(F,1); -- this will print one term per line
1*x^3
 +2*x*y
 -1*y^2
-------------------------------
  D := OpenOFile("example");
  Print StarSprint(F) On D; -- this will print F into the file "example"
  Close(D);
-------------------------------
</example>
</description>

<seealso>
  <see>LaTeX</see>
</seealso>

<keys>
  <key>multiplication asterisk</key>
  <key>gap, maple, macaulay, singular</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>starting</title>
  <short_description>list functions starting with a given string</short_description>
<syntax>
starting(S: <type>STRING</type>): <rtn>LIST</rtn> of <rtn>RECORD</rtn>
</syntax>
<description>
This function returns a list of all CoCoA functions starting with the
string <tt>S</tt>.  In general, this list will include undocumented
commands.  For these, one may find some information using
<tt>Describe Function(<quotes>Fn_Name</quotes>)</tt> or
<tt>Describe Function(<quotes>$PackageName.Fn_Name</quotes>)</tt>.
<example>
/**/  indent(starting("Su"));
[
  record[IsExported := true, name := "$BackwardCompatible.Subsets"],
  record[IsExported := true, name := "$BackwardCompatible.Subst"],
  record[IsExported := true, name := "$BackwardCompatible.Sum"],
  record[IsExported := true, name := "$BackwardCompatible.Support"]
]
</example>
</description>
<types>
  <type>help</type>
  <type>miscellaneous</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>StdDegLexMat</title>
  <short_description>matrices for std. term-orderings</short_description>
<syntax>
StdDegLexMat(N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix defining a standard term-ordering.
<example>
/**/  StdDegLexMat(3);
matrix(QQ,
 [[1, 1, 1],
  [1, 0, 0],
  [0, 1, 0]])
</example>
</description>
<seealso>
  <see>OrdMat</see>
  <see>Orderings</see>
  <see>StdDegRevLexMat</see>
  <see>LexMat</see>
  <see>RevLexMat</see>
  <see>XelMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>StdDegRevLexMat</title>
  <short_description>matrices for std. term-orderings</short_description>
<syntax>
StdDegRevLexMat(N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix defining a standard term-ordering.
<example>
/**/  StdDegRevLexMat(3);
matrix(QQ,
 [[1, 1, 1],
  [0, 0, -1],
  [0, -1, 0]])
</example>
</description>
<seealso>
  <see>OrdMat</see>
  <see>Orderings</see>
  <see>StdDegLexMat</see>
  <see>LexMat</see>
  <see>RevLexMat</see>
  <see>XelMat</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>StronglyStableIdeal</title>
  <short_description>strongly stable ideal containing L</short_description>

<syntax>
StronglyStableIdeal(L: <type>LIST</type> of power-products): <rtn>IDEAL</rtn>
</syntax>
<description>
This function returns the smallest strongly stable ideal containing the
power-products in L.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  L := [x*y^2*z];
/**/  StableIdeal(L);
ideal(x^4, x^3*y, x^2*y^2, x*y^3, x*y^2*z)

/**/  StronglyStableIdeal(L);
ideal(x^4, x^3*y, x^2*y^2, x*y^3, x^3*z, x^2*y*z, x*y^2*z)
</example>
</description>
<seealso>
  <see>IsStronglyStable</see>
  <see>LexSegmentIdeal</see>
  <see>StableIdeal</see>
</seealso>
<keys>
  <key>borelfixed</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SubalgebraMap [OBSOLETE]</title>
  <short_description>[OBSOLETE] algebra homomorphism representing a subalgebra</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE] See  <ttref>SubalgebraRepr</ttref>.
<!-- <example> -->
<!--   Use QQ[s,t]; -->
<!--   SAM := SubalgebraMap([s^3, s^2t, st^2, t^3]); -->
<!--   Ker(SAM); -->
<!-- SubalgebraRing :: ideal(x[3]^2 - x[2]x[4], x[2]x[3] - x[1]x[4], x[2]^2 - x[1]x[3]) -->
<!--   IsInSubalgebra(s^3, SAM); -->
<!-- True -->
<!--   SubalgebraRepr(s^3, SAM); -->
<!-- SubalgebraRing :: x[1] -->
<!--   IsInSubalgebra(s^5, [s^3, s^2t, st^2, t^3]); -->
<!-- False -->
<!--   SubalgebraRepr(s^5, SAM); -->
<!-- NULL -->
<!-- </example> -->
</description>
<seealso>
  <see>SubalgebraRepr</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SubalgebraRepr</title>
  <short_description>representation of a polynomial as a subalgebra element</short_description>
<syntax>
SubalgebraRepr(F: <type>RINGELEM</type>, L: <type>LIST</type>): <rtn>RECORD</rtn>
SubalgebraRepr(R: <type>RING</type>, F: <type>RINGELEM</type>, L: <type>LIST</type>): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns the representation of a polynomial as a
subalgebra element in terms of the subalgebra generators.
<example>
/**/  Use QQ[s,t];
/**/  L := ***[s^3, s^2t, st^2, t^3]***;
/**/  indent(SubalgebraRepr(s^6*t^6, L));
Record[
  IsInImage := true,
  OnePreImage := x[1]^2*x[4]^2,
  ker := ideal(x[3]^2 -x[2]*x[4], x[2]*x[3] -x[1]*x[4], x[2]^2 -x[1]*x[3])
]
</example>
</description>
<seealso>
  <see>PreImage</see>
  <see>ker</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>submat</title>
  <short_description>submatrix</short_description>

<syntax>
submat(M: <type>MAT</type>, R: <type>LIST</type> of <type>INT</type>, C: <type>LIST</type> of <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the submatrix of M formed by the rows listed
in R and the columns listed in C.  If M is a list, it is interpreted
as a matrix in the natural way.
<example>
/**/  M := mat([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]);
/**/  submat(M,[1,3],3..5);
matrix([
  [3, 4, 5],
  [13, 14, 15]
])

/**/  M := mat([[1,2,3],[4,5,6]]);
/**/  submat(M,[2],[1,3]);
matrix([
  [4, 6]
])
</example>
</description>
<seealso>
  <see>minors</see>
</seealso>
<keys>
  <key>submatrix</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>submodule</title>
  <short_description>submodule generated by list</short_description>
  
<syntax>
submodule(L: <type>LIST</type> of <type>MODULEELEM</type>): <rtn>MODULE</rtn>
submodule(F: <type>MODULE</type>, L: <type>LIST</type> of <type>MODULEELEM</type>): <rtn>MODULE</rtn>
</syntax>
<description>
The first form returns the ideal generated by <tt>L</tt>.
The second is the same as the first but works also if <tt>L = []</tt>.
<par/>
This function is not friendly if you write the input by hand:
we suggest <ttref>SubmoduleCols, SubmoduleRows</ttref> for creating
a module from the rows or columns of a matrix.
<par/>
NOTE: the second argument is a LIST of MODULEELEM, not a LIST of LISTS
of RINGELEM.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  R3 := NewFreeModule(R, 3);
/**/  L := [ModuleElem(R3, [x,y,z]), ModuleElem(R3, [x-1,0,z])];
/**/  M := submodule(R3, L); -- equivalent to
/**/  M := submodule(L);     -- (L not empty)
/**/  gens(M);
[[x, y, z], [x -1, 0, z]]
</example>
</description>

<seealso>
  <see>SubmoduleCols, SubmoduleRows</see>
  <see>GensAsCols, GensAsRows</see>
  <see>gens</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SubmoduleCols, SubmoduleRows</title>
  <short_description>convert a matrix into a module</short_description>

<syntax>
SubmoduleCols(F: <type>MODULE</type>, M: <type>MATRIX</type>): <rtn>MODULE</rtn>
SubmoduleRows(F: <type>MODULE</type>, M: <type>MATRIX</type>): <rtn>MODULE</rtn>
</syntax>
<description>
The first (second) function returns the submodule of F generated by
the module elements described by the columns (rows) in the matrix M
(which might be empty).
<par/>
Dimensions must be compatible.
<example>
/**/  R3 := NewFreeModule(R, 3);
/**/  MGens := matrix(R,[[x,y,z],[x-1,0,z]]);

/**/  M := SubmoduleRows(R3, MGens);
/**/  gens(M);
[[x, y, z], [x -1, 0, z]]

-- /**/  M := SubmoduleCols(R3, MGens); -- !!! ERROR: wrong length !!!

/**/  M := SubmoduleCols(NewFreeModule(R,2), MGens);
/**/  gens(M);
[[x, x -1], [y, 0], [z, z]]
</example>
</description>

<seealso>
  <see>GensAsCols, GensAsRows</see>
  <see>submodule</see>
  <see>ModuleElem</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convertto</key>
  <key>generated</key>
  <key>generators</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>subsets</title>
  <short_description>returns all sublists of a list</short_description>

<syntax>
subsets(S: <type>LIST</type>): <rtn>LIST</rtn>
subsets(S: <type>LIST</type>, N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function computes all sublists (subsets) of a list (set).
If N is specified, it computes all sublists of cardinality N.

<example>
/**/  subsets([1, 4, 7]);
[[ ], [7], [4], [4, 7], [1], [1, 7], [1, 4], [1, 4, 7]]

/**/  subsets([1, 4, 7], 2);
[[1, 4], [1, 7], [4, 7]]

/**/  subsets([2,3,3]);                 -- list with repeated entries
[[ ], [3], [3], [3, 3], [2], [2, 3], [2, 3], [2, 3, 3]]

/**/  subsets(MakeSet([2,3,3]));
[[ ], [3], [2], [2, 3]]
</example>
</description>


<seealso>
  <see>IsSubset</see>
  <see>partitions</see>
  <see>permutations</see>
  <see>MakeSet</see>
  <see>tuples</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>subst</title>
  <short_description>substitute values for indeterminates</short_description>

<syntax>
subst(E: <type>OBJECT</type>, X, F): <rtn>OBJECT</rtn>
subst(E: <type>OBJECT</type>,[[X_1, F_1],...,[X_r, F_r]]): <rtn>OBJECT</rtn>
  where each X or X_i is an indeterminate
  and each F or F_i is a <type>RINGELEM</type>
</syntax>
<description>
The first form of this function substitutes <tt>F_i</tt> for <tt>X_i</tt> in the
expression E.  The second form is a shorthand for the first in the
case of a single indeterminate.  When substituting for the
indeterminates in order, it is easier to use <ttref>eval</ttref>.

<example>
/**/  Use R ::= QQ[x,y,z,t];
/**/  F := x +y +z +t^2;
/**/  subst(F, x, -2);
t^2 +y +z -2

/**/  subst(F, [[x,x^2], [y,y^3], [z,t^5]]);
t^5 +y^3 +x^2 +t^2

/**/  eval(F, [x^2,y^3,t^5]); -- the same thing as above
t^5 +y^3 +x^2 +t^2

/**/  MySubst := [[y,1], [t, 3*z-x]];
/**/  subst(x*y*z*t, MySubst);  -- substitute into the function x*y*z*t
-x^2*z +3*x*z^2
</example>
</description>


<seealso>
  <see>eval</see>
  <see>Evaluation of Polynomials</see>
  <see>PolyAlgebraHom</see>
  <see>QZP</see>
  <see>RingElem</see>
  <see>ZPQ</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sum</title>
  <short_description>the sum of the elements of a list</short_description>

<syntax>
sum(L: <type>LIST</type>): <rtn>OBJECT</rtn>
sum(L: <type>LIST</type>, InitVal: <type>OBJECT</type>): <rtn>OBJECT</rtn>
</syntax>
<description>
This function returns the sum of the objects in the list <tt>L</tt> (together
with <tt>InitVal</tt>, if specified).  When writing a program, if the list <tt>L</tt>
may be empty, you must specify <tt>InitVal</tt>.

<example>
/**/  use R ::= QQ[x,y];
/**/  sum([3, x, y^2]);
y^2 +x +3

/**/  sum(1..40) = binomial(41,2);
true

/**/  sum(["c","oc","oa"]);
cocoa

/**/ sum([]);  -- gives 0 of type INT
0
/**/ sum([], "");  -- gives empty STRING

/**/ sum([], x);  -- gives type RINGELEM
x
</example>
</description>


<seealso>
  <see>Algebraic Operators</see>
  <see>product</see>
</seealso>

<types>
  <type>IDEAL</type>
  <type>INT</type>
  <type>MAT</type>
  <type>RINGELEM</type>
  <type>RAT</type>
  <type>MODULEELEM</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>support</title>
  <short_description>the list of terms of a polynomial or moduleelem</short_description>

<syntax>
support(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
support(F: <type>MODULEELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list of terms of F.  To get a list of
monomials, which includes coefficients, use <ttref>monomials</ttref>.
<example>
/**/  Use R ::= QQ[x,y];
/**/  F := 3*x^2-4*x*y+y^3+3;
/**/  support(F);
[y^3, x^2, x*y, 1]

/**/  monomials(F);
[y^3, 3*x^2, -4*x*y, 3]

// NOT YET IMPLEMENTED for MODULEELEM
</example>
</description>
<seealso>
  <see>coefficients</see>
  <see>monomials</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>swap</title>
  <short_description>swap two values</short_description>
<syntax>
swap(ref A: <type>OBJECT</type>, ref B: <type>OBJECT</type>)
</syntax>
<description>
This procedure swaps two values; it returns nothing!
<example>
/**/  A := 1;
/**/  B := 2;
/**/  swap(ref A, ref B);
/**/  PrintLn [A,B];
[2, 1]
</example>
</description>
<seealso>
  <see>ref</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SwapRows</title>
  <short_description>swap two rows in a matrix</short_description>
<syntax>
SwapRows(ref M: <type>MAT</type>, i: <type>INT</type>, j: <type>INT</type>)
</syntax>
<description>
This procedure swaps the <tt>i</tt>-th and <tt>j</tt>-th rows in the
matrix <tt>M</tt>; it returns nothing!
<example>
/**/  M := IdentityMat(QQ, 5);
/**/  SwapRows(ref M, 2,5);
/**/  M;
matrix(QQ,
 [[1, 0, 0, 0, 0],
  [0, 0, 0, 0, 1],
  [0, 0, 1, 0, 0],
  [0, 0, 0, 1, 0],
  [0, 1, 0, 0, 0]])
</example>
</description>
<seealso>
  <see>ref</see>
  <see>swap</see>
  <see>GetRow</see>
  <see>SetRow</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>sylvester</title>
  <short_description>the Sylvester matrix of two polynomials</short_description>

<syntax>
sylvester(F: <type>RINGELEM</type>, G: <type>RINGELEM</type>, X: <type>RINGELEM</type>): <rtn>MAT</rtn>
</syntax>
<description>
(sorry Sylvester for the lower-case: here we follow the naming
convention <em>single name goes lower-case</em>)
<par/>
This function returns the Sylvester matrix of the polynomials F and G
with respect to the indeterminate X.  This is the matrix used to
calculate the resultant.

<example>
/**/  Use R ::= QQ[p,q,x];
/**/  F := x^3+p*x-q;  G := deriv(F, x);
/**/  sylvester(F, G, x);
matrix([
  [1, 0, p, -q, 0],
  [0, 1, 0, p, -q],
  [3, 0, p, 0, 0],
  [0, 3, 0, p, 0],
  [0, 0, 3, 0, p]
])

/**/  det(sylvester(F, G, x)) = resultant(F, G, x);
true
</example>
</description>


<seealso>
  <see>resultant</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SymbolRange</title>
  <short_description>range of symbols for the indeterminates of a PolyRing</short_description>

<syntax>
SymbolRange(H: <type>STRING</type>, LO: <type>INT</type>, HI: <type>INT</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
</syntax>
<description>
This function returns the list of the symbols with a given head and a
range of indices.
A symbol is a record with head (as <ttref>IndetName</ttref>) and indices
(as <ttref>IndetSubscripts</ttref>)

<example>
/**/  indent(SymbolRange("x", 3, 5));
[
  record[head := "x", indices := [3]],
  record[head := "x", indices := [4]],
  record[head := "x", indices := [5]]
]
/**/  P := NewPolyRing(QQ, SymbolRange("x", 0,2));
/**/  indets(P);
[x[0], x[1], x[2]]
</example>
</description>


<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>NumIndets</see>
  <see>SymbolRange</see>
</seealso>
<keys>
  <key>variable</key>
  <key>indexed</key>
  <key>indices</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>syz</title>
  <short_description>syzygy modules</short_description>
    
<syntax>
Syz(L: <type>LIST</type> of <type>RINGELEM</type>): <rtn>MODULE</rtn>
Syz(M: <type>IDEAL</type>|<type>MODULE</type>, Index: <type>INT</type>): <rtn>MODULE</rtn>
</syntax>
<description>
In the first two forms this function computes the syzygy module of a list
of polynomials or module elements.
<tt>SyzOfGens(I)</tt> is the same as <tt>Syz(gens(I))</tt>.
<par/>
In the last form this function returns the specified syzygy module of
the minimal free resolution of M which must be homogeneous.  As a side
effect, it computes the Groebner basis of M.   (***** NOT YET IMPLEMENTED *****)
<par/>
The coefficient ring must be a field.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  indent(Syz([x^2-y-1, y^3-z, x^2-y, y^3-z]));
SubmoduleRows(F, matrix(
  [y^3 -z, 0, 0, -x^2 +y +1],
  [0, 1, 0, -1],
  [x^2 -y, 0, -x^2 +y +1, 0],
  [0, 0, y^3 -z, -x^2 +y]
))
-------------------------------
/**/  I := ideal(x, x, y);
/**/  syz(gens(I));
submodule(FreeModule(..), [[1, -1, 0], [0, y, -x]])
/**/  SyzOfGens(I);
submodule(FreeModule(..), [[1, -1, 0], [0, y, -x]])

  Syz(I, 1);      -- NOT YET IMPLEMENTED
Module([[x, -y]])
-------------------------------
  I := ideal(x^2-yz, xy-z^2, xyz);    -- NOT YET IMPLEMENTED
  Syz(I,0);
Module([x^2 - yz], [xy - z^2], [xyz])
-------------------------------
  Syz(I,1);    -- NOT YET IMPLEMENTED
  Module([-x^2 + yz, xy - z^2, 0], [xz^2, -yz^2, -y^2 + xz], [z^3, 0,
-xy + z^2], [0, z^3, -x^2 + yz])
-------------------------------
  Syz(I,2);
Module([0, z, -x, y], [-z^2, -x, y, -z])
-------------------------------
  Syz(I,3);
Module([[0]])
-------------------------------
  Res(I);
0 --> R(-6)^2 --> R(-4)(+)R(-5)^3 --> R(-2)^2(+)R(-3)
-------------------------------
</example>
</description>

<seealso>
  <see>res</see>
  <see>SyzOfGens</see>
</seealso>

<types>
  <type>groebner</type>
</types>

<keys>
  <key>syzygies</key>
  <key>syzygy</key>
</keys>
</command>
<!-- ===  COMMAND-rm SyzMinGens ========================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>SyzOfGens</title>
  <short_description>syzygy module for a given set of generators</short_description>

<syntax>
SyzOfGens(M: <type>IDEAL</type>|<type>MODULE</type>): <rtn>MODULE</rtn>
</syntax>
<description>
If M is an ideal or submodule, this function calculates the syzygy
module for the given set of generators of M. 
<par/>
If M is a quotient of a ring by an ideal I or a quotient of a free
module by a submodule N, then this function calculates the syzygy
module for the given set of generators of I or N, respectively.
<par/>
<tt>SyzOfGens(I)</tt> is the same as <tt>Syz(gens(I))</tt>.
<par/>
The coefficient ring must be a field.

<example>
/**/  Use R ::= QQ[x,y,z];
/**/  I := ideal(x, y, x+y);
/**/  indent(SyzOfGens(I));
SubmoduleRows(F, matrix([
  [1, 1, -1],
  [0, x +y, -y]
]))

/**/  R3 := NewFreeModule(R, 3);
/**/  MGens := matrix(R,[[x,y,z], [x-y,0,z], [y^2,y^2,0]]);
/**/  indent(SyzOfGens(SubmoduleRows(R3, MGens)));
SubmoduleRows(F, matrix([
  [1, -1, -1]
]))
</example>
</description>

<seealso>
  <see>syz</see>
</seealso>

<types>
  <type>groebner</type>
</types>

</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>T</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>tag</title>
  <short_description>returns the tag string of an object</short_description>

<syntax>
tag(E: <type>OBJECT</type>): <rtn>STRING</rtn>
</syntax>
<description>
If E is a tagged object, this function returns the tag of E;
otherwise, it returns the empty string.

<example>
/**/  L := tagged(3,"MyTag");
/**/  type(L);
TAGGED("$TopLevel.MyTag")

/**/  tag(L);
MyTag
</example>
</description>


<seealso>
  <see>Printing a Tagged Object</see>
  <see>tagged</see>
  <see>untagged</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
  <type>tags</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>tagged</title>
  <short_description>tag an object for pretty printing</short_description>

<syntax>
tagged(E: <type>OBJECT</type>, S: <type>STRING</type>): TAGGED(S)
</syntax>
<description>
This first function returns the object E, tagged with the string S.
Tagging is used for pretty printing of objects.  See the reference
listed below.

<example>
/**/  L := [1,2,3];
/**/  M := tagged(L,"MyTag");
/**/  type(L);
LIST

/**/  type(M);
TAGGED("$TopLevel.MyTag")

/**/  type(untagged(M));
LIST
</example>
</description>


<seealso>
  <see>Printing a Tagged Object</see>
  <see>tag</see>
  <see>untagged</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
  <type>tags</type>
</types>

<keys>
  <key>tag an object</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>tail</title>
  <short_description>remove the first element of a list</short_description>

<syntax>
tail(L: <type>LIST</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list obtained from L by removing its first
element.  It cannot be applied to the empty list.

<example>
/**/  tail([1,2,3]);
[2, 3]
</example>
</description>


<seealso>
  <see>first</see>
  <see>last</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TensorMat</title>
  <short_description>returns the tensor product of two matrices</short_description>

<syntax>
TensorMat(M: <type>MATRIX</type>, N: <type>MATRIX</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the tensor product of two matrices.

<example>
/**/  Use R ::= QQ[x,y,z,w];
/**/  TensorMat(mat(R, [[1,-1],[2,-2],[3,-3]]), mat(R, [[x,y],[z,w]]));
matrix([
  [x, y, -x, -y],
  [z, w, -z, -w],
  [2*x, 2*y, -2*x, -2*y],
  [2*z, 2*w, -2*z, -2*w],
  [3*x, 3*y, -3*x, -3*y],
  [3*z, 3*w, -3*z, -3*w]
])
</example>
</description>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TgCone</title>
  <short_description>tangent cone</short_description>

<syntax>
TgCone(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
The <em>initial form</em> of a polynomial F is the homogeneous
component of F of the lowest degree (in contrast with the <em>leading
form</em>, see <ttref>LF</ttref>, <ttref>DF</ttref>).
The <em>initial ideal</em> of the ideal <tt>I</tt> is the ideal
generated by the initial forms of all polynomials in <tt>I</tt>.
It is also called <em>tengent cone</em> (which strictly is the variety
defined by the initial ideal).
<par/>
The implementation is based on Lazard's method (see Kreuzer-Robbiano,
Commutative Computer Algebra II, pg.463).
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  TgCone(ideal(x^3-y));
ideal(-y)
/**/  TgCone(ideal(x^3+x^2-y^2));
ideal(x^2 -y^2)

/**/  I := ideal(x^3-y*z, y^2-x*z, z^2-x^2*y);
/**/  TgCone(I); -- same as InitialIdeal(I, [x,y,z]);
ideal(y^2 -x*z, z^2, -y*z)
</example>
</description>
<keys>
  <key>tangentcone</key>
  <key>tangent cone</key>
</keys>

<seealso>
  <see>InitialIdeal</see>
  <see>PrimaryPoincare</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TimeFrom</title>
  <short_description>time elapsed since a given moment</short_description>

<syntax>
TimeFrom(StartPoint: <type>RAT</type>): <rtn>STRING</rtn>
</syntax>
<description>
This function returns a string indicating the number of CPU seconds consumed
since <tt>StartPoint</tt>; the value in <tt>StartPoint</tt> should be the value produced
by the function <ttref>CpuTime</ttref> at the point where timing should commence.
<example>
/**/  t0 := CpuTime();
/**/  N := factorial(10000000);
/**/  PrintLn "Time to compute N: ",TimeFrom(t0);
Time to compute N: 7.538
</example>
</description>

<keys>
  <key>timer</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TimeOfDay</title>
  <short_description>the current time</short_description>

<syntax>
TimeOfDay(): <rtn>INT</rtn>
</syntax>
<description>
This function returns the current time as an INT in the form HHMMSS.
<par/>
Note that from version 5.0.4 this information is no longer given by
the function <ttref>date</ttref>.

<example>
/**/  date();       -- 2013-05-30
20130530
/**/  TimeOfDay();  -- 09:08:13
90813
</example>
</description>

<seealso>
  <see>date</see>
</seealso>

<types>
  <type>miscellaneous</type>
</types>

</command>
<!-- === COMMAND =============================================== -->
 <command>
   <title>TmpNBM</title>
   <short_description>Numerical Border Basis of ideal of points</short_description>
 
 <syntax>
 TmpNBM(P: <type>RING</type>, Pts: <type>MAT</type>, Toler: <type>MAT</type>): <rtn>RECORD</rtn>[QuotientBasis: <type>LIST</type>, BBasis: <type>LIST</type>, AlmostVanishing: <type>LIST</type>, StableBBasisFound: <type>BOOL</type>]
</syntax>
<description>
Thanks to John Abbott and Maria-Laura Torrente.
<par/>
This function checks that the current ring is suitable: see below for details.
<par/>
This function returns a record containing a factor-closed set of power-products
<tt>QuotientBasis</tt> and a list of <em>almost vanishing</em> polynomials.
If the cardinality of the <tt>QuotientBasis</tt> is equal to the
number of points, it is in fact a <em>quotient basis</em> of the ideal
of points, and in this case a <em>border basis</em> founded on it is also returned.
<par/>
The first argument is a list of points in k-dimensional space, and the
second argument is list of k positive tolerances (one for each dimension).
So that the answer can be represented, the current ring must have at
least k indeterminates; the term ordering is ignored as it plays no role
in determining the border basis.
 <par/>
 For a full description of the algorithms we refer to the paper
 C.Fassino
 <em>Almost Vanishing Polynomials for Sets of Limited Precision Points</em>
 (arXiv:0807.3412).
 <par/>

<example>
/**/ P ::= QQ[x,y];
/**/ Eps := [0.1, 0.1];
/**/ Points := [[10, 0], [-10, 0], [0, 10], [0, -10], [7, 7], [-7, -7]];
/**/ indent(TmpNBM(P, mat(Points), RowMat(Eps)));
record[
  AlmostVanishing := [x^2 +(2/49)*x*y +y^2 -100,
                      x*y^2 +(49/51)*y^3 +(-4900/51)*y, y^4 +51*x*y -100*y^2],
  BBasis := [x^2 +(2/49)*x*y +y^2 -100, x*y^2 +(49/51)*y^3 +(-4900/51)*y,
             x^2*y +(49/51)*y^3 +(-4900/51)*y, y^4 +51*x*y -100*y^2, x*y^3 -49*x*y],
  QuotientBasis := [1, y, x, y^2, x*y, y^3],
  StableBBasisFound := true
]
</example>
</description>
 

<seealso>
  <see>IdealOfPoints</see>
  <see>StableBBasis5</see>
</seealso>
 
<keys>
   <key>abbott fassino torrente</key>
   <key>cocoalib</key>
   <key>stable border basis</key>
   <key>bbasis</key>
   <key>stable order ideal</key>
   <key>approx</key>
   <key>numerical buchbergermoeller</key>
   <key>approx</key>
   <key>stablebbasisnbm5</key>
   <key>author: john abbott</key>
   <key>author: maria-laura torrente</key>
</keys>
 </command>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TopLevel</title>
  <short_description>make a top level variable accessible</short_description>
<syntax>
TopLevel X;
  where <tt>X</tt> is the name of a top level variable or function.
</syntax>
<description>
This command makes a top-level variable accessible from inside a function.
It is useful for making <tt>QQ</tt> and <tt>ZZ</tt> visible, and also if
a top-level function is to be passed as a parameter (<i>e.g.</i> to the
function <ttref>SortBy</ttref>).
<par/>
The command may be used with any top-level variable, but it is poor style
to use it for purposes other than those mentioned above.
<example>
/**/  Define CompareLen(X,Y) Return len(X) &lt; len(Y); EndDefine;

/**/  Define LongestName(ListOfNameAndValue)
/**/    TopLevel CompareLen;  --> to pass it as paremeter to SortBy
/**/    names := [entry[1] | entry in ListOfNameAndValue];
/**/    SortBy(ref names, CompareLen);
/**/    Return last(names);
/**/  EndDefine;

/**/  L := [["ABC",1],["XYZT",2]];
/**/  LongestName(L);
XYZT
</example>
</description>
<seealso>
  <see>func</see>
  <see>ImportByRef, ImportByValue</see>
</seealso>
<types>
  <type>FUNCTION</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>TopLevelFunctions</title>
  <short_description>returns the functions available at top-level</short_description>
<syntax>
TopLevelFunctions(): <rtn>LIST</rtn> of <rtn>FUNCTION</rtn>
</syntax>
<description>
This function returns the list of all functions available at top-level
<example>
/**/  indent(TopLevelFunctions());
[
  record[IsExported := true, Name := "$BackwardCompatible.Abs"],
  record[IsExported := true, Name := "$BackwardCompatible.Append"],
  record[IsExported := true, Name := "$BackwardCompatible.Ascii"],
  ...
</example>
</description>
<keys>
  <key>all functions</key>
  <key>all commands</key>
  <key>allfunctions</key>
  <key>allcommands</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>toric</title>
  <short_description>saturate toric ideals</short_description>
  
<syntax>
toric(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
toric(I: <type>IDEAL</type>, L: <type>LIST</type> of INDETS): <rtn>IDEAL</rtn>
toric(M: <type>MAT</type>|<type>LIST</type> of LIST): <rtn>IDEAL</rtn>
</syntax>
<description>
These functions return the saturation of an ideal, I, generated by
binomials.  In the first two cases, I is the ideal generated by the
binomials in L.  To describe the ideal in the last case, let K be the
integral elements in the kernel of M.  For each k in K, we can write k
= k(+) - k(-) where the i-th component of k(+) is the i-th component
of k, if positive, otherwise zero.  Then I is the ideal generated by
the binomials <tt>x^k(+) - x^k(-)</tt> as k ranges over K.
<par/>
NOTE: successive calls to this last form of the function may produce
different generators for the saturation.
<par/>
The first and third functions return the saturation of I.  For the
second function, if the saturation of I with respect to the variables
in X happens to equal the saturation of I, then the saturation of I is
returned.  Otherwise, an ideal <em>containing</em> the saturation with
respect to the given variables is returned.  The point is that if one
knows, a priori, that the saturation of I can be obtained by
saturating with respect to a subset of the variables, the second
function may be used to save time.
<par/>
For more details, see the article: A.M. Bigatti, R. La Scala,
L. Robbiano, <em>Computing Toric Ideals,</em> Preprint (1998).  The article
describes three different algorithms; the one implemented in CoCoA is
<em>EATI</em>. The first two examples below are motivated by B. Sturmfels,
<em>Groebner Bases and Convex Polytopes,</em> Chapter 6, p. 51.  They count
the number of homogeneous primitive partition identities of degrees 8
and 9.
<example>
/**/  Use QQ[x[1..8],y[1..8]];
/**/  HPPI8 := [x[1]^I*x[I+2]*y[2]^(I+1) -y[1]^I*y[I+2]*x[2]^(I+1) | I In 1..6];
/**/  BL := toric(ideal(HPPI8), [x[1],y[2]]);
/**/  len(gens(BL));
340

/**/  Use QQ[x[1..9],y[1..9]];
/**/  HPPI9 := [x[1]^I*x[I+2]*y[2]^(I+1) -y[1]^I*y[I+2]*x[2]^(I+1) | I In 1..7];
/**/  BL := toric(ideal(HPPI9), [x[1],y[2]]);
/**/  len(gens(BL));
798

/**/  Use R ::= QQ[x,y,z,w];
/**/  toric(ideal(x*z-y^2, x*w-y*z));
ideal(-y^2 +x*z, -y*z +x*w, z^2 -y*w)

/**/  toric(ideal(x*z-y^2, x*w-y*z), [y]);
ideal(-y^2 +x*z, -y*z +x*w, z^2 -y*w)

/**/  Use R ::= QQ[x,y,z];
/**/  toric([[1,3,2],[3,4,8]]);
ideal(-x^16 +y^2*z^5)

/**/  toric(mat([[1,3,2],[3,4,8]]));
ideal(-x^16 +y^2*z^5)
</example>
</description>


<seealso>
</seealso>
<keys>
  <key>bigatti lascala robbiano</key>
  <key>author: anna maria bigatti</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<!-- <command> -->
<!--   <title>Toric.CheckInput</title> -->
<!--   <short_description>check input to <tt>Toric</tt></short_description> -->

<!--     <description> -->
<!-- This function checks if E or (E, X) is suitable input for <ttref>Toric</ttref>. -->
<!-- Thus, E should be either a list of homogeneous binomials (without -->
<!-- coefficients) or a matrix of non-negative integers.  In the former -->
<!-- case, X must be a list of indeterminates (in the latter, X would be -->
<!-- ignored by <ttref>Toric</ttref> anyway). -->

<!-- <example> -->
<!--   Use R ::= QQ[x,y,z]; -->
<!--   Toric.CheckInput([[1,2,3,4],[4,5,6,7]]); -->
<!-- True -->
<!--   Toric.CheckInput([[-1,2],[3,4]]); -->
<!-- ERROR: entries must be non-negative integers -->
<!-- CONTEXT: Return(Error(Toric_IntMatrix)) -->
<!--   Toric.CheckInput([xy-z^2,x^3-y^2z]); -->
<!-- True -->
<!--   Toric.CheckInput([3xy-z^2,x^3-y^2z]); // the binomials should not -->
<!--                                         // have coefficients -->
<!-- ERROR: generators must be of type: power-product - power-product -->
<!-- CONTEXT: Return(Error(Toric_PP)) -->
<!--   Toric.CheckInput([xy-z^2,x^3-y^2z],[x]); -->
<!-- True -->
<!-- </example> -->
<!-- </description> -->

<!-- <syntax> -->
<!-- Toric.CheckInput(E:OBJECT): <rtn>BOOL</rtn> -->
<!-- Toric.CheckInput(E:OBJECT, X: <type>LIST</type>): <rtn>BOOL</rtn> -->
<!-- </syntax> -->

<!--<seealso> -->
<!--  <see>Toric</see> -->
<!--</seealso> -->

<!-- <types> -->
<!--   <type>ideal</type> -->
<!--   <type>MAT</type> -->
<!--   <type>LIST</type> -->
<!--   <type>toric</type> -->
<!-- </types> -->

<!--<keys> -->
<!--   <key>author: anna maria bigatti</key> -->
<!--</keys> -->
<!--   </command> -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>transposed</title>
  <short_description>the transposition of a matrix</short_description>

<syntax>
transposed(M: <type>MAT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the transpose of the matrix M.

<example>
/**/  M := mat([[1,2,3],[4,5,6]]);
/**/  M;
matrix([
  [1, 2, 3],
  [4, 5, 6]
])

/**/  transposed(M);
matrix([
  [1, 4],
  [2, 5],
  [3, 6]
])
</example>
</description>


</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>try</title>
  <short_description>try and catch an error</short_description>
<syntax>
Try C1 UponError E Do C2 EndTry
  where C1, C2 are sequences of commands and E is a variable identifier.
</syntax>
<description>
Usually, when an error occurs during the execution of a command, the
error is automatically propagated out of the nesting of the
evaluation.  This can be prevented with the use of <tt>Try..UponError</tt>.
<par/>
If an error occurs during the execution of the commands C1, then it is
captured by the command <tt>UponError</tt> and assigned to the
variable E, and the commands C2 are executed; the string inside E may be
retrieved using <ttref>GetErrMesg</ttref>.  If no error occurs then
the variable E and the commands C2 are ignored.
<example>
-- /**/  deg(zero(R));  --> !!! ERROR !!!
-- ERROR: Non-zero RingElem required
--  deg(zero(R));
--  ^^^^^^^^^^^^

/**/  Define MyDeg(F)
/**/    Try
/**/      D := Deg(F);
/**/      Return D;
/**/    UponError E Do
/**/      MyDegError := GetErrMesg(E);
/**/      If "Non-zero RingElem required" IsIn MyDegError Then
/**/        Return -123456;
/**/      Else
/**/        error(MyDegError);
/**/      EndIf; 
/**/    EndTry;
/**/  EndDefine;

/**/  MyDeg(x);
1
/**/  MyDeg(zero(R));
-123456
-- /**/  MyDeg("a"); --> !!! ERROR !!!
ERROR: Expecting type RINGELEM, but found type STRING
        error(MyDegError);
        ^^^^^^^^^^^^^^^^^
</example>
</description>
<keys>
  <key>catch</key>
  <key>uponerror</key>
</keys>
<seealso>
  <see>error</see>
  <see>GetErrMesg</see>
</seealso>
<types>
  <type>ERROR</type>
</types>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>tuples</title>
  <short_description>N-tuples</short_description>

<syntax>
tuples(S: <type>LIST</type>, N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function computes all N-tuples with entries in S.
It is equivalent to <tt>S &gt;&lt; S &gt;&lt; ... &gt;&lt; S</tt>  [N times].

<example>
/**/  tuples([1, 4, 7], 2);
[[1, 1], [1, 4], [1, 7], [4, 1], [4, 4], [4, 7], [7, 1], [7, 4], [7, 7]]
</example>
</description>


<seealso>
  <see>CartesianProduct, CartesianProductList</see>
  <see>permutations</see>
  <see>subsets</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>type</title>
  <short_description>the data type of an expression</short_description>
<syntax>
type(E: <type>OBJECT</type>): <rtn>TYPE</rtn>
</syntax>
<description>
This function returns the data type of E.
<example>
/**/ L := [1,"a",2,"b",3,"c"];
/**/ [ X In L | type(X)=INT ];
[1, 2, 3]

/**/  type(type(INT));  -- Type returns a value of type TYPE
TYPE

/**/  CurrentTypes();
[BOOL, ERROR, FUNCTION, ...]
</example>
</description>
<seealso>
  <see>CurrentTypes</see>
</seealso>
</command>
</chapter_letter>
<!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>U</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>UnivariateIndetIndex</title>
  <short_description>the index of the indeterminate of a univariate polynomial</short_description>

<syntax>
UnivariateIndetIndex(F: <type>RINGELEM</type>): <rtn>INT</rtn>
</syntax>
<description>
This function returns 0 if the polynomial F is not univariate
otherwise it returns the indeterminate index of F.
<par/>
NB: If F is a constant, it returns 1.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  UnivariateIndetIndex(3*x^4-2*x-1);
1

/**/  UnivariateIndetIndex(x-y-1);
0

/**/  UnivariateIndetIndex(one(R));
1
</example>

</description>


<seealso>
  <see>indet</see>
  <see>IndetSubscripts</see>
  <see>IndetIndex</see>
  <see>IndetName</see>
  <see>indets</see>
  <see>NumIndets</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>unprotect</title>
  <short_description>remove protection from a variable</short_description>

<syntax>
unprotect X;
</syntax>
<description>
This command undoes the effect of the <ttref>protect</ttref> command; once a
variable has been unprotected, it may be assigned to freely.
<example>
/**/ X := 1;
/**/ protect X;    --> cannot assign to X henceforth
/**/ 
/**/ unprotect X;  --> remove protection, X may be assigned to now
/**/ X := 2;
</example>
</description>

<seealso>
  <see>protect</see>
</seealso>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>Unset [OBSOLETE]</title>
  <short_description>[OBSOLETE] set and unset panel options</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
</description>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>untagged</title>
  <short_description>untag an object</short_description>

<syntax>
untagged(E:TAGGED_OBJECT):UNTAGGED_OBJECT
</syntax>
<description>
This function strips an object E of its tag, if any.
<tt>@E</tt> is equivalent to <tt>untagged(E)</tt>.
<par/>
Tags are used for pretty printing of objects.  See the reference
listed below.

<example>
/**/  L := [1,2,3];
/**/  M := tagged(L,"MyTag");
/**/  type(L);
LIST

/**/  type(M);
TAGGED("MyTag")

/**/  type(untagged(M));
LIST
</example>
</description>


<seealso>
  <see>Printing a Tagged Object</see>
  <see>tag</see>
  <see>tagged</see>
</seealso>

<types>
  <type>io</type>
  <type>printing</type>
  <type>tags</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>use</title>
  <short_description>command for making a ring active</short_description>
<syntax>
use R
use RingDefn
use R ::= RingDefn

where R is a RING, and RingDefn is a ring definition.
</syntax>
<description>
This command works only at top-level; it makes a ring active,
<i>i.e.</i> it makes that ring the <em>current ring</em>.
The command will also let you create a new ring, and make it active
immediately <tt>Use NewR ::= RingDefn;</tt> where <tt>RingDefn</tt> is
a ring definition; this is a shorthand for
<tt>NewR ::= RingDefn;  Use NewR;</tt>
<par/>
This command cannot be called inside a function, and it is never
necessary (if you write clean programs ;-)
In CoCoA-5 you can define new rings, return rings, assign rings and
pass rings as arguments (this was not possible in CoCoA-4).
<example>
/**/  use S ::= QQ[x,y,z];
/**/  Print CurrentRing;
RingDistrMPolyClean(QQ, 3)
/**/  indets(CurrentRing);
[x, y, z]

/**/  use QQ[u];  -- can be used w/out a ring identifier
/**/  indets(CurrentRing);
[u]

/**/  define SumInAnotherRing(N)
/**/    K := NewRingTwinFloat(128); -- 128 bits of precision
/**/    P ::= K[x[1..N]], Lex;
/**/    return sum(indets(P));
/**/  enddefine;

/**/  SumInAnotherRing(4);
x[1] +x[2] +x[3] +x[4]
/**/  CoeffRing(RingOf(It));
RingTwinFloat(AccuracyBits=128, BufferBits=128, NoiseBits=32)
</example>
</description>
<seealso>
  <see>Accessing Other Rings</see>
  <see>CurrentRing</see>
  <see>RingOf</see>
  <see>ReadExpr</see>
</seealso>
</command>
<!-- ===  COMMAND-rm Using ============================================= -->

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>V</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>valuation</title>
  <short_description>p-adic valuation</short_description>
<syntax>
valuation(p: <type>INT</type>, N: <type>INT</type>): <rtn>INT</rtn>
</syntax>
<description>
This function determines the p-adic valuation of a non-zero integer:
the largest integer <code>k</code> such that <code>power(p,k)</code> divides <code>N</code>.
The first argument is the prime <code>p</code>.
<example>
/**/ valuation(5,10);
1
</example>
</description>
<seealso>
  <see>IsDivisible</see>
</seealso>
<keys>
  <key>p-adic</key>
  <key>divisible</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>VersionInfo</title>
  <short_description>version and info about CoCoA</short_description>
<syntax>
VersionInfo(): <rtn>RECORD</rtn>
</syntax>
<description>
This function returns a record with various information about CoCoA 
and CoCoALib (the mathematical core of CoCoA)
<example>
/**/ indent(VersionInfo());
record[
  CoCoALibVersion := "0.99533",
  CoCoAVersion := "5.1.0",
  CompilationDate := "May 14 2014 15:48:58",
  ...
</example>
</description>
<seealso>
  <see>CoCoALib</see>
</seealso>
<keys>
  <key>versioninfos</key>
  <key>cocoainfos</key>
</keys>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>W</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>wdeg</title>
  <short_description>multi-degree of an polynomial</short_description>
<syntax>
wdeg(F: <type>RINGELEM</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the multi-weighted degree of F, as determined by the
matrix weights of the polynomial ring of F.  The function <ttref>deg</ttref>
returns the standard degree.
<par/>
NB: In CoCoA-4 <ttref>deg</ttref> gave the weight
given by only the first row of the weights matrix.
<example>
/**/  M := matrix([[2,3,4], [1,0,2], [1,0,0]]);
/**/  P := NewPolyRing(QQ, ["x","y","z"], M, 1);  -- GradingDim=1
/**/  Use P;
/**/  wdeg(x*y^2+y);
[8]
/**/  P := NewPolyRing(QQ, ["x","y","z"], M, 2);  -- GradingDim=2
/**/  Use P;
/**/  wdeg(x*y^2+y);
[8, 1]
/**/  deg(x*y^2+y);
3

/**/  P4 := NewFreeModule(P,4); -- the default module ordering is TOPos
/**/  wdeg(ModuleElem(P4, [0, x, y^2, x^2]));
[6, 0]

/**/  LT(ModuleElem(P4, [0, x, y^2, x^2]));
[0, 0, y^2, 0]
</example>
</description>
<seealso>
  <see>deg</see>
  <see>LF</see>
</seealso>
</command>
<!-- ===  COMMAND-rm WeightsList  ===================================== -->
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>WeightsMatrix [OBSOLESCENT]</title>
  <short_description>[OBSOLESCENT] matrix of generalized weights for indeterminates</short_description>
<syntax>
WeightsMatrix(R: <type>RING</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function is now called <ttref>GradingMat</ttref>.
</description>
<seealso>
  <see>deg</see>
  <see>wdeg</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>while</title>
  <short_description>loop command</short_description>
    
<syntax>
While B Do C EndWhile

where B is a boolean expression and C is a sequence of commands.
</syntax>
<description>
The command sequence C is repeated until B evaluates to False.

<example>
/**/  N := 0;
/**/  while N &lt;= 5 do
/**/    PrintLn 2, "^", N, " = ", 2^N;
/**/    N := N+1;
/**/  EndWhile;
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
</example>
</description>

<seealso>
  <see>for</see>
  <see>foreach</see>
  <see>repeat</see>
</seealso>

<types>
  <type>command</type>
  <type>programming</type>
  <type>loops</type>
</types>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>WithoutNth</title>
  <short_description>removes the N-th component from a list</short_description>

<syntax>
WithoutNth(L: <type>LIST</type>, N: <type>INT</type>): <rtn>LIST</rtn>
</syntax>
<description>
This function returns the list obtained by removing the <tt>N</tt>-th component
of the list <tt>L</tt>.  The list <tt>L</tt> itself is not changed; compare with
<ttref>remove</ttref>.

<example>
/**/  L := [1,2,3,4,5];
/**/  WithoutNth(L,3);
[1, 2, 4, 5]
</example>
</description>

<seealso>
  <see>remove</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>WLog [OBSOLETE]</title>
  <short_description>[OBSOLETE]weighted list of exponents</short_description>
<syntax>
[OBSOLETE]
</syntax>
<description>
[OBSOLETE]
This function returns the weighted list of exponents of the leading
term of F, as determined by the first row of the weights matrix.
</description>
<seealso>
  <see>log</see>
</seealso>
</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>X</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>XelMat</title>
  <short_description>matrices for std. term-orderings</short_description>

<syntax>
XelMat(N: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function return the matrix defining a standard term-ordering.

<example>
/**/  XelMat(3);
matrix([
  [0, 0, 1],
  [0, 1, 0],
  [1, 0, 0]
])
</example>
</description>


<seealso>
  <see>OrdMat</see>
  <see>Orderings</see>
  <see>StdDegRevLexMat</see>
  <see>StdDegLexMat</see>
  <see>LexMat</see>
  <see>RevLexMat</see>
</seealso>

</command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <title>Z</title>

<!-- ===  COMMAND  =============================================== -->
<command>
  <title>zero</title>
  <short_description>zero of a ring</short_description>

<syntax>
zero(R: <type>RING</type>): <rtn>RINGELEM</rtn>
</syntax>
<description>
This function return the additive identity of a ring.
For when you want to force the integer <tt>0</tt> to be a
<tt>RINGELEM</tt>.
<example>
/**/ P ::= ZZ/(101)[x,y,z];

/**/ N := 0;  Print N, " of type ",  type(N);
0 of type INT
/**/ N := zero(P);  Print N, " of type ",  type(N);
0 of type RINGELEM
/**/ N := 300*0;  Print N, " of type ",  type(N);
0 of type INT
/**/ N := 300*zero(P);  Print N, " of type ",  type(N);
0 of type RINGELEM

/**/  F := NewFreeModule(P, 3);
/**/  zero(F);
[0, 0, 0]
</example>
</description>


<seealso>
  <see>one</see>
  <see>IsZero</see>
</seealso>
<keys>
  <key>cast</key>
  <key>convertto</key>
</keys>

</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ZeroMat</title>
  <short_description>matrix filled with 0</short_description>
  
<syntax>
ZeroMat(R: <type>RING</type>, NumRows: <type>INT</type>, NumCols: <type>INT</type>): <rtn>MAT</rtn>
</syntax>
<description>
This function returns the <tt>NumRows x NumCols</tt> zero matrix
with entries in <tt>R</tt>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  ZeroMat(QQ, 1, 3); --> same as NewMatFilled(1,3, 0)
matrix(QQ,
 [[0, 0, 0]])
/**/  ZeroMat(R, 1, 3); --> same as NewMatFilled(1,3, zero(R))
matrix( /*RingDistrMPolyClean(QQ, 3)*/
 [[0, 0, 0]])
</example>
</description>
<seealso>
  <see>matrix</see>
  <see>IdentityMat</see>
  <see>NewMatFilled</see>
</seealso>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ZPQ</title>
  <short_description>change field for polynomials and ideals</short_description>

<syntax>
ZPQ(F: <type>RINGELEM</type>): <rtn>RINGELEM</rtn>
ZPQ(F: <type>LIST</type> of <type>RINGELEM</type>): <rtn>LIST</rtn> of <rtn>RINGELEM</rtn>
ZPQ(I: <type>IDEAL</type>): <rtn>IDEAL</rtn>
</syntax>
<description>
***** NOT YET IMPLEMENTED *****
<par/>
The function <tt>ZPQ</tt> maps a polynomial with finite field coefficients
into one with rational (actually, integer) coefficients.  It is not
uniquely defined mathematically, and currently for each coefficient
the least non-negative equivalent integer is chosen.
Users should not rely on this choice, though any change will be
documented.
<par/>
See <ttref>QZP</ttref> for more details.

<example>
  Use R ::= QQ[x,y,z];
  F := 1/2*x^3 + 34/567*x*y*z - 890; -- a poly with rational coefficients
  Use S ::= ZZ/(101)[x,y,z];
  QZP(F);                            -- compute its image with coeffs in ZZ/(101)
-50x^3 - 19xyz + 19
-------------------------------
  G := It;
  Use R;
  ZPQ(G);     -- now map that result back to QQ[x,y,z] it is NOT the same as F...
51x^3 + 82xyz + 19
-------------------------------
</example>
</description>


<seealso>
  <see>BringIn</see>
</seealso>

<keys>
  <key>change ring</key>
  <key>author: john abbott</key>
</keys>
</command>
<!-- ===  COMMAND  =============================================== -->
<command>
  <title>ZZ</title>
  <short_description>the ring of integers</short_description>

<syntax>
ZZ
</syntax>
<description>
This system variable is constant; its value is the ring of integers.
Its name is protected so that it cannot be re-assigned to any other value.

<example>
/**/ P ::= ZZ/(101)[x,y,z];

/**/ Use ZZ;

/**/ type(5);
INT
/**/ type(RingElem(ZZ, 5));
RINGELEM
</example>
</description>


<seealso>
  <see>QQ</see>
</seealso>
<keys>
</keys>

</command>



 </chapter_letter>

</cocoa_commands>



<!-- *************************** -->
<!-- LIST OF PARTS OF THE MANUAL -->
<!-- *************************** -->
<manual_parts>
<!--   <part> -->
<!--   <title></title> -->
<!-- ===  CHAPTER  =============================================== -->
<!--     <chapter> -->
<!--   <title>Preamble</title> -->
<!--     </chapter> -->
<!--   </part> -->

<part>
  <title>The CoCoA Programming Language</title>
<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Introduction to CoCoA Programming</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>An Overview of CoCoA Programming</title>
  <type>1</type>

<description>
The CoCoA system includes a full-fledged high level programming
language, CoCoALanguage, complete with loops, branching, scoping of
variables, and input/output control.  The language is used whenever
one issues commands during a CoCoA session.  A sequence of commands
may be stored in a text file and then read into a CoCoA session using
the <ttref>source</ttref> command.
<par/>
The most important construct in CoCoA programming is the user-defined
function, created with <ttref>define</ttref>.
A user-defined function can take any number of arguments, of any
types, perform CoCoA commands, and return values.
Collections of these functions can be stored in text files,
as mentioned in the preceding paragraph, or formed into CoCoA
<em>packages</em>, to be made available for general use.
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Language Elements</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Character Set and Special Symbols</title>
  <type>1</type>

<description>
The CoCoA character set consists of the 26 lower case letters, the 26
upper case letters, the 10 digits and the special characters listed in
the table below.  Note that the special character <tt>|</tt> looks a bit
different on some keyboards (its ASCII code is 124).

<verbatim>
    ------------------------------------------------------
   |    blank     _  underscore     (  left parenthesis   |
   | +  plus      =  equal          )  right parenthesis  |
   | -  minus     &lt;  less than      [  left bracket       |
   | *  asterisk  &lt;  greater than   [  right bracket      |
   | /  slash     |  vertical bar   &apos;  single quote       |
   | :  colon     .  period         <quotes>  </quotes>  double quote    |
   | ^  caret     ;  semicolon                            |
   | ,  comma     %  percent                              |
    ------------------------------------------------------
                  Special Characters
</verbatim>
The character-groups listed in the table below are special symbols in CoCoA
<verbatim>
    -------------------------------------------------------------
   | :=   assign                      ..   range                 |
   | &lt;&lt;   input from                  //   start line comment    |
   | &lt;&gt;   not equal                   --   start line comment    |
   | &gt;&lt;   Cartesian product           ::=  ring definition       |
   | &lt;=   less than or equal to       /*   start embedded comment|
   | &gt;=   greater than or equal to    */   end embedded comment  |
    -------------------------------------------------------------
                     Special Character-groups
</verbatim>
</description>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Identifiers</title>
  <type>1</type>

<description>
There are two types of identifiers or names.
<par/>
  * Identifiers of ring indeterminates (see <ttref>NewPolyRing</ttref>)
<par/>
  * Predefined or user-defined names (functions and CoCoALanguage variables).
</description>
<seealso>
  <see>Indeterminates</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Reserved Names</title>
  <type>1</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
The names in the following tables are reserved and cannot be used
otherwise.  The names in the first table are case insensitive
(e.g. CLEAR, Clear and ClEaR are all reserved).  The names in the
second table are case sensitive.

<par/>...work in progress...

<verbatim>
     ----------------------------------------------------
    | Alias      And      Block       Ciao      Define   |
    | Describe   Do       Elif        Else      End      |
    | EndBlock   EndTry               EndDefine EndFor   |
    | EndForeach EndIf    EndPackage  EndRepeat EndUsing |
    | EndWhile   Eof      False       For       Foreach  |
    | Global     Help     If          In        IsIn     |
    | NewLine    Not      On          Or        Package  |
    | Print      PrintLn  Quit        Repeat    Record   |
    | Return     Set      Skip        Source    Step     |
    | Then       Time     To          True      Unset    |
    | Until      Use      Using       Var       While    |
    | QQ         ZZ                                      |
     ----------------------------------------------------
           Case insensitive reserved names

     -------------------------------------------------
    | BOOL      DegLex  DegRevLex  DEVICE  ERROR      |
    | FUNCTION  IDEAL   INT        LIST    Lex        |
    | MAT       MODULE  NULL       Null    PANEL      |
    | POLY      PosTo   RAT        RATFUN  RING       |
    | STRING    TAGGED  ToPos      TYPE    MODULEELEM |
    | Xel       ZMOD                                  |
     -------------------------------------------------
            Case sensitive reserved names
</verbatim>
	</description>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Comments</title>
  <type>1</type>
<description>
End-of-line comments in CoCoA start with either <tt>--</tt> or
<tt>//</tt>; all text up to the end of the line is considered comment.
CoCoA also allows embedded comments; these begin with the symbol
<tt>/*</tt> and end with the symbol <tt>*/</tt>.  CoCoA ignores the
contents of a comment, and treats it as if it were just a space.
<example>
/**/  // This is an end-of-line comment
/**/  Print 1+1; -- a command followed by an end-of-comment
2
/**/  A := [1 /*x-coord*/, 2 /*y-coord*/ ]; --> embedded comments
</example>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
    <chapter>
  <title>Operators</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>CoCoA Operators</title>
  <type>1</type>
<description>
In CoCoA there are 5 main types of operators: algebraic
operators, relational operators, boolean operators, selection
operators, and the range operator.
There is also an n-ary operator <tt>&gt;&lt;</tt> for forming
Cartesian products of lists and an operator <tt>::=</tt> used in
defining rings.
<par/>
The meaning of an operator depends on the types of its operands; the <tt>+</tt>
in the expression <tt>A + B</tt> represents the sum of polynomials, or of
ideals, or of matrices, etc. according to the type of A and B.
<par/>
The CoCoA operators are, from the highest to the lowest priority:
<verbatim>
    []  .   (selection operators)
    ^  %
    +  -    (as unary operators)
    *  :  /
    +  -    (as binary operators)
    ..
    =  &lt;&gt;  &lt;  &lt;=  &gt;  &gt;=
    IsIn
    And
    Or
</verbatim>
Operations with equal priority are performed from left to right.
When in doubt, parentheses may be used to enforce a particular order of
evaluation.
</description>
<seealso>
  <see>operators, shortcuts</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Algebraic Operators</title>
  <type>1</type>
<description>
The algebraic operators are:
<verbatim>
      +  -  *  /  :  ^
</verbatim>
The following table shows which operations the system can perform
between two objects of the same or of different types; the first
column lists the type of the first operand and the first row lists the
type of the second operand. So, for example, the symbol <tt>:</tt> in the box
on the seventh row and fourth column means that it is possible to
divide an ideal by a polynomial.

<verbatim>
          INT    RAT  RINGELEM  MODULEELEM IDEAL MODULE MAT LIST
INT       +-*/^  +-*/   +-*/      *         *     *      *   *
RAT       +-*/^  +-*/   +-*/      *         *     *      *   *
RINGELEM  +-*/^  +-*/   +-*/      *         *     *      *   *
MODULEELEM *     *      *         +-
IDEAL     *^     *      *                   +*:   *
MODULE    *      *      *                   *     +:
MAT       *^     *      *                                +-*
LIST      *      *      *                                    +-

                           Algebraic operators
</verbatim>

Remarks:
<par/>
  * Let F and G be two polynomials. If F is a multiple of G, then
    F/G is the polynomial obtained from the division of F by G,
    otherwise F/G is a rational function (common factors are
    simplified). The functions <ttref>div</ttref> and <ttref>mod</ttref> can be used to get the
    quotient and the remainder of a polynomial division.
<par/>
  * Let <formula>L_1</formula> and <formula>L_2</formula> be two lists of the same length. Then <formula>L_1 + L_2</formula> is
    the list obtained by adding <formula>L_1</formula> to <formula>L_2</formula> componentwise.
<par/>
  * If I and J are both ideals or both modules, then <formula>I : J</formula> is the
    ideal consisting of all polynomials f such that fg is in I for all
    g in J.
</description>

      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Relational Operators</title>
  <type>1</type>
  <description>
</description>
<seealso>
  <see>Equality Test</see>
  <see>Comparison Operators</see>
  <see>IsIn</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Selection Operators</title>
  <type>1</type>

<description>
The selection operators are
<verbatim>
      []    .
</verbatim>
Let N be of type INT and let L be of type STRING, MODULEELEM, LIST, or
MAT.  Then the meaning of L[N] depends on the type of L as explained
in the following table:

<verbatim>
    ------------------------------------------------------------
   |  Type of L    Meaning of L[N]                              |
    ------------------------------------------------------------
   | STRING       string consisting of the N-th character of L. |
   | MODULEELEM   N-th component of L                           |
   | LIST         N-th element of L                             |
   | MAT          N-th element of L                             |
    ------------------------------------------------------------
                   Selection Operator
</verbatim>
If N is an identifier and L is of type RECORD, then <tt>L.N</tt> indicates the
object contained in the field N of the record L (see <ref>record</ref>).
	</description>
<seealso>
  <see>record</see>
  <see>List Constructors</see>
</seealso>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Range Operator</title>
  <type>1</type>
<description>
If M and N are of type INT, then the expression:  <tt>M .. N</tt> returns
<par/>
      * the list <tt>[M, M+1, ... , N]</tt> if <formula>M <less_eq/> N;</formula>
<par/>
      * the empty list, <tt>[]</tt>, otherwise.
<par/>
NOTE: Large values for M and N are not permitted; typically
      they should lie in the range about <formula>-10^9</formula> to <formula>+10^9</formula>.
<par/>
NOTE: see example for how to select a sub-range of a list
<par/>
If x and y are indeterminates in a ring, then <tt>x .. y</tt>
gives the indeterminates between x and y in the order they appear
in the definition of the ring.
<example>
/**/  1..10;
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

/**/  Use R ::= QQ[x,y,z,a,b,c,d];
/**/  z..c;
[z, a, b, c]

/**/ L := [11, 22, 33, 44, 55];
/**/ PartOfL := L[2]..L[4];  --> probably *NOT* what you want!
/**/ PartOfL := [ L[k] | k in 2..4 ]; --> OK, this is RIGHT!
</example>
</description>
<seealso>
  <see>CoCoA Operators</see>
  <see>List Constructors</see>
  <see>LIST</see>
</seealso>
<type>LIST</type>
<keys>
  <key>list constructor</key>
  <key>dot dot</key>
  <key>dotdot</key>
  <key>..</key>
</keys>
</section>
</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Evaluation and Assignment</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Evaluation</title>
  <type>1</type>

<description>
An expression is by itself a valid command. The effect of this
command is that the expression is evaluated in the current ring and
its value is displayed.
<par/>
The evaluation of an expression in CoCoA is normally performed in a
full recursive evaluation mode.
Usually the result is the fully evaluated expression.
<par/>
The result of the evaluation is automatically stored in the variable
<ttref>It</ttref>.
<example>
/**/  2 + 2;
4
/**/  It + 3;
7
/**/  It;
7
/**/  X := 5;
/**/  It;
7
</example>
The command <tt>X := 5</tt> is an assignment, not an evaluation; so it does
not change the value of the variable <ttref>It</ttref>.
<par/>
If an error occurs during the evaluation of an expression, then the
evaluation is interrupted and the user is notified about the error.
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Assignment</title>
  <type>1</type>
<description>
An assignment command has the form
<verbatim>
  L := E
</verbatim>
where L is a variable and E is an expression.
The assignment command binds the result of the evaluation of the
expression E to L in the working memory.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  I := ideal(x,y);

/**/  M := 5;  N := 8;
/**/  T := M+N;
/**/  T;
13
/**/  T := T+1;  -- note that T occurs on the right, also
/**/  T;
14

/**/  L := [1,2,3];
/**/  L[2] := L[3];
/**/  L;
[1, 3, 3]

/**/  P := record[F := x*z];
/**/  P.Degree := Deg(P.F);
/**/  P;
record[Degree := 2, F := x*z]
</example>
</description>
</section>
</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Flow Control: Conditional Statements and Loops</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for Branching</title>
  <type>1</type>
<description>
The following are the CoCoA commands for constructing conditional
statements:
<commands_and_functions_for type="branching"></commands_and_functions_for>
</description>

</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for Loops</title>
  <type>1</type>
<description>
The following are the commands and functions for loops:
<commands_and_functions_for type="loops"></commands_and_functions_for>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Input/Output</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to IO</title>
  <type>1</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
Input and output is implemented in CoCoA through the use of
<em>devices</em>.  At present, the official devices are: (1) standard IO (the
CoCoA window), (2) text files, and (3) strings.  What this means is that
it is possible to read from or write to any of these places.  The
cases are discussed separately, below.  Text files may be read
verbatim or---with the <ttref>source</ttref> command---be executed as CoCoA
commands.
</description>

<keys>
  <key>devices</key>
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Standard IO</title>
  <type>2</type>

  <description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
Standard IO is what takes places normally when one interacts with
CoCoA.
CoCoA accepts and interprets strings typed in by the user and prints
out expressions.  If E is a CoCoA object, then the command
<verbatim>
    E;
</verbatim>
causes the value of E to be printed to the CoCoA window.  One may also
use the functions <ttref>print</ttref> and <ttref>println</ttref> for more control over the
format of the output.
<par/>
The official devices that are being used here are <tt>DEV.STDIN</tt> and
<tt>DEV.OUT</tt>. So for instance, the commands <ttref>Get</ttref> and <ttref>print on</ttref> can be
used with the standard devices although they are really meant to be
used with the other devices.  <tt>Print E On DEV.OUT</tt> is synonymous with
<tt>Print E</tt>.  Also, one may use <tt>Get(DEV.STDIN,10)</tt>, for example, to get
the next 10 characters typed in the CoCoA window.  Thus, clever use of
<ttref>Get</ttref> will allow your user-defined functions to prompt the user for
input, but normal practice is to pass variables to a function as
arguments to that function.
</description>

      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>File IO</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
To print CoCoA output to a file, one first opens the file
with <ttref>OpenOFile</ttref> then prints to the file using <ttref>print on</ttref>.
<par/>
To receive verbatim input from a file, one first opens the file with
<ttref>OpenIFile</ttref>, then gets characters from the file with <ttref>Get</ttref>.  Actually,
<ttref>Get</ttref> gets a list of ASCII codes for the characters in the file.
These can be converted to real characters using the function <ttref>ascii</ttref>.

<example>
  D := OpenOFile("my-file"); -- open text file with name "my-file",
                             -- creating it if necessary
  Print "hello world" On D; -- append "hello world" to my-file
  Close(D); -- close the file
  D := OpenIFile("my-file"); -- open "my-file"
  Get(D,10);  -- get the first ten characters, in ASCII code
[104, 101, 108, 108, 111, 32, 119, 111, 114, 108]
-------------------------------
  ascii(It); -- convert the ASCII code
hello worl
-------------------------------
  Close(D);
</example>

To read and execute a sequence of CoCoA commands from a text file, one
uses the <ttref>source</ttref> command.  For instance, if the
file <tt>MyFile.coc</tt> contains a list of CoCoA commands, then
<verbatim>
  Source <quotes>MyFile.cocoa</quotes>;
</verbatim>
reads and executes the commands.
</description>

<seealso>
  <see>ascii</see>
  <see>close</see>
  <see>Get</see>
  <see>OpenIFile</see>
  <see>OpenOFile</see>
  <see>OpenLog</see>
  <see>CloseLog</see>
  <see>print on</see>
  <see>source</see>
</seealso>

      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>String IO</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
To print CoCoA output to a string, on may use <ttref>OpenOString</ttref> to
<em>open</em> the string, then <ttref>print on</ttref> to write to it.  To read from a
string, one may open the string for input with <ttref>OpenIString</ttref> then get
characters from it with <ttref>Get</ttref>.

<example>
  S := "hello world";
  D := OpenIString("", S);  -- open the string S for input to CoCoA
                -- the first argument is just a name for the device
  L := Get(D,7);  -- read 7 characters from the string
  L;  -- ASCII code
[104, 101, 108, 108, 111, 32, 119]
-------------------------------
  ascii(L); -- convert ASCII code to characters
hello w
-------------------------------
  Close(D);  -- close device D
  D := OpenOString("");  -- open a string for output from CoCoA
  L := [1,2,3]; -- a list
  Print L On D;  -- print to D
  D;
record[Name := "", Type := "OString", Protocol := "CoCoALanguage"]
-------------------------------
  S := Cast(D, STRING);  -- S is the string output printed on D
  S; -- a string
  [1, 2, 3]
  Print " more characters" On D;  -- append to the existing output string
  Cast(D, STRING);
[1, 2, 3] more characters
-------------------------------
</example>
There are usually more direct ways to collect results in strings.  For
instance, if the output of a CoCoA command is not already of type
STRING, one may convert it to a string using <ttref>sprint</ttref>.
</description>

      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for IO</title>
  <type>1</type>
  
  <description>
The following are commands and functions for input/output:
<commands_and_functions_for type="io"></commands_and_functions_for>
</description>
  
</section>

</chapter>


<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>CoCoA Packages</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to Packages</title>
  <type>1</type>
<description>
User-defined functions may be saved in separate files and read into a
CoCoA session using the <ttref>source</ttref> command.
If one sources several such files or, especially, if a file is to be
made available for general use, a possible problem arises from
conflicting function names.
If two functions with the same name are read into a CoCoA session, only
the one last read survives.
To avoid this, functions may be collected in <em>packages</em>.
<par/>
A CoCoA package is essentially a list of functions labeled with prefix.
<par/>
Writing a package in CoCoA-5 is slightly different from how it was
done in CoCoA-4 it is easier!).
</description>
<seealso>
  <see>define</see>
  <see>source</see>
</seealso>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>First Example of a Package</title>
  <type>1</type>
<description>
The following is an example of a package.  It could be typed into a
window as-is during a CoCoA session, but we will assume that it is
stored in a file in the CoCoA directory under the name <tt>one.cpkg5</tt>.
<example>
package $contrib/toypackage

export ToyTest;

define IsNumberOne(n)
  if n = 1 then return true; else return false; endif;
enddefine;

define ToyTest(n)
  if IsNumberOne(n) then
    print "The number 1";
  else
    print "Not the number 1";
  endif;
enddefine;

endpackage; -- of toypackage
</example>

Below is output from a CoCoA session in which this package was used:

<example>
-- read in the package:
Source "one.cpkg";
/* */ ToyTest(4);  -- was exported
Not the number 1
/* */ IsNumberOne(4);  -- wasn't exported
ERROR: Cannot find a variable named "IsNumberOne" in scope
IsNumberOne(4);
^^^^^^^^^^^

/* */ $contrib/toypackage.IsNumberOne(4);
false
</example>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Package Essentials</title>
  <type>1</type>
<description>
A package begins with
<verbatim>
  Package $PackageName
</verbatim>
and ends with
<verbatim>
  EndPackage;
</verbatim>
PackageName is a string that will be used to identify the package.
The dollar sign is required.  There are no restrictions on the string
PackageName, but keep in mind that it serves to distinguish functions
in the package from those in all other CoCoA packages.  A name of the
form <tt>contrib/subject</tt> is typical.
<par/>
All packages in the CoCoA directory <tt>packages</tt> are
automatically loaded when starting CoCoA.
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Global Aliases</title>
  <type>1</type>
<description>
A global alias for a package is formed by using the command <ttref>alias</ttref>
during a CoCoA session.
Note: global aliases cannot be used in function definitions.
This is to force independence of context.
Inside a function, one must use the complete package name.
</description>
<seealso>
  <see>alias</see>
  <see>aliases</see>
</seealso>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Sharing Your Package</title>
  <type>1</type>
<description>
If you create a package that others might find useful, please contact
the CoCoA team by email at <tt>cocoa at dima.unige.it</tt>.
<par/>
Include comments in the package that:
<par/>
  * explain the use of the package
<par/>
  * give the syntax, description, examples for exported functions.
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for Packages</title>
  <type>1</type>
<description>
The following are commands and functions for packages:
<commands_and_functions_for type="packages"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Supported Packages</title>
  <type>1</type>
<description>
Several packages are supported by the CoCoA team.  These packages
contain functions that are not built into CoCoA because they are of a
more specialized or experimental nature.
<par/>
Some functions which used to be defined in supported packages are now
official functions in CoCoA-5.
</description>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Galois Package</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : galois.cpkg
DESCRIPTION : CoCoA package for computing in a cyclic algebraic
              extension
AUTHOR      : A. Bigatti, D.La Macchia, F.Rossi

-- Enter
       $contrib/galois.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>algebraic extension</key>
  <key>cyclic extension</key>
  <key>galois group</key>
	<key>author: anna maria bigatti</key>
	<key>author: la macchia</key>
	<key>author: rossi</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Integer Programming</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : intprog.cpkg
DESCRIPTION : CoCoA package for applying toric ideals to integer
              programming
AUTHOR      : A. Bigatti

-- Enter
       $contrib/intprog.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>intprog</key>
  <key>test set</key>
  <key>testset</key>
  <key>author: anna maria bigatti</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Algebra of Invariants</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : invariants.cpkg
DESCRIPTION : CoCoA package for computing homogeneous generators of an
              algebra of invariants, and for testing invariance of a polynomial
AUTHOR      : A. Del Padrone

-- Enter
       $contrib/invariants.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>invariance</key>
	<key>author: del padrone</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Special Varieties</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : specvar.cpkg
DESCRIPTION : CoCoA package for computing the Hilbert-Poincare
              series of special varieties (Segre, Veronese, Rees).
AUTHORS     : A. Bigatti, L. Robbiano

-- Enter
       $contrib/specvar.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>rees</key>
  <key>segre</key>
  <key>veronese</key>
	<key>author: anna maria bigatti</key>
	<key>author: robbiano</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Statistics</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : stat.cpkg
DESCRIPTION : package for design of experiments in statistics
AUTHOR      : M. Caboara

-- Enter
       $contrib/stat.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>design of experiments</key>
	<key>author: caboara</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Geometrical Theorem-Proving</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : thmproving.cpkg
DESCRIPTION : CoCoA package for geometrical theorem-proving in euclidean space
AUTHOR      : L. Bazzotti, G. Dalzotto

-- Enter
       $contrib/thmproving.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>thmproving</key>
  <key>hypothesis</key>
  <key>thesis</key>
	<key>author: bazzotti</key>
	<key>author: dalzotto</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Typevectors</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : typevectors.cpkg
DESCRIPTION : CoCoA package for computing type-vectors associated to
              Hilbert functions of ideals of points
AUTHOR      : E.Carlini, M.Stewart

-- Enter
       $contrib/typevectors.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>type-vectors</key>
  <key>type vectors</key>
  <key>hilbert functions of points</key>
	<key>author: carlini</key>
	<key>author: stewart</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Conductor</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : conductor.cpkg
DESCRIPTION : CoCoA package for computing conductor sequence of points
AUTHOR      : L.Bazzotti

-- Enter
       $contrib/conductor.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>author: bazzotti</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Matrix Normal Form</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : matrixnormalform.cpkg
DESCRIPTION : CoCoA package for computing normal forms of a matrix,
              Smith Normal Form (PID)
AUTHOR      : A.Bigatti, S.DeFrancisci

-- Enter
       $contrib/matrixnormalform.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>matrixnormalform</key>
  <key>smith normal form</key>
  <key>principal ideal domain, PID</key>
  <key>author: anna maria bigatti</key>
  <key>author: de francisci</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>CantStop</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : CantStop.cpkg
DESCRIPTION : CoCoA package for playing  Can't Stop  and studying strategies
AUTHOR      : A.Bigatti

-- Enter
       $contrib/CantStop.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>game</key>
  <key>play</key>
  <key>author: anna maria bigatti</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Control</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
<verbatim>
TITLE       : control.cpkg
DESCRIPTION : CoCoA package for Geometric Control Theory
AUTHOR      : M. Anderlucci and M. Caboara

-- Enter
       $contrib/control.Man();
   to get a complete description of the package including a suggested alias.
</verbatim>
</description>

<keys>
  <key>control theory</key>
	<key>geometric theory of control</key>
  <key>author: anderlucci</key>
	<key>author: caboara</key>
</keys>
      </section>

    </chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Linked libraries</title>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>CoCoALib</title>
  <type>2</type>
<description>
CoCoALib <tt>http://cocoa.dima.unige.it/cocoalib</tt>.
<par/>
CoCoALib is the mathematical core of CoCoA-5.
It may be used directly as a C++ library.
</description>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>GMP</title>
  <type>2</type>
<description>
GMP - The GNU Multiple Precision Arithmetic Library
<tt>https://gmplib.org</tt>
<par/>
All arbitrary precision integer/rational/floating-point datatypes and
operations are based on GMP.
</description>
<keys>
  <key>external library</key> 
  <key>ExternalLib</key> 
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>GSL</title>
  <type>2</type>
<description>
GSL - GNU Scientific Library
<tt>http://www.gnu.org/software/gsl/</tt>
<par/>
Some functions from GSL have been ported to CoCoA-5.
There is no manual yet because it's work in progress.
</description>
<keys>
  <key>external library</key> 
  <key>ExternalLib</key> 
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Frobby</title>
  <type>2</type>
<description>
Frobby - Computations With Monomial Ideals
<tt>http://www.broune.com/frobby</tt>
<par/>
All functions starting with <tt>Frb</tt> are implemented in Frobby.
</description>
<keys>
  <key>external library</key> 
  <key>ExternalLib</key> 
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Normaliz</title>
  <type>2</type>
<description>
Normaliz
<tt>http://www.home.uni-osnabrueck.de/wbruns/normaliz</tt>
<par/>
All functions starting with <tt>Nmz</tt> are implemented in Normaliz.
</description>
<keys>
  <key>external library</key> 
  <key>ExternalLib</key> 
</keys>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Migrating from CoCoA-4 and keeping up-to-date</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Changes in the CoCoA language</title>
  <type>1</type>
<description>
CoCoA-5 is largely, but not completely, backward-compatible with CoCoA-4.
Some commands/functions have changed name; others have been removed or
replaced.  Here we give a little guidance to help update your CoCoA-4
programs to CoCoA-5/
<par/>
The operator <tt>Not</tt> has been replaced by the function <tt>not(...)</tt>.
<example>
/*C4*/ If Not X IsIn L Then ... EndIf;
/*C5*/ If not(X IsIn L) Then ... EndIf;
</example>
Several functions modify one of their arguments (<i>e.g.</i> <ttref>append</ttref>,
<ttref>sort</ttref>); CoCoA-5 wants these arguments to be identified with the new
keyword <ttref>ref</ttref>, and will issue a warning if you don't do this
(just to make sure you know that <tt>L</tt> will be modified).
<example>
/*C4*/ L := [1,2,3];  Append(L, 4);
/*C5*/ L := [1,2,3];  append(ref L, 4);
</example>
Implicit multiplication has gone: either write <tt>x*y</tt> instead of <tt>xy</tt>
for every product, or use <ttref>CoCoA-4 mode</ttref>.
<example>
/*C4*/ F := 3xyzt;
/*C5*/ F := 3*x*y*z*t;  OR  F := ***3xyzt***;
</example>
Many CoCoA-4 functions would employ the <tt>CurrentRing</tt> implicitly (<i>e.g.</i>
<tt>NumIndets()</tt>, <tt>CoeffRing()</tt>).  They now require an explicit argument;
you can pass <tt>CurrentRing</tt> as the argument, but inside a function you must
make that system variable visible via the command <ttref>TopLevel</ttref>.
<example>
/*C4*/ Define LastIndet() Return Last(Indets()); EndDefine;
/*C5*/ Define LastIndet()
         TopLevel CurrentRing;
         Return last(indets(CurrentRing));
       EndDefine;
</example>
However, we encourage you to consider modifying your function so that
it does not depend on <tt>CurrentRing</tt>; <i>e.g.</i> you can find
out to which ring a value belongs by calling the function <ttref>RingOf</ttref>.
<example>
/*C5*/ I := ideal(x,y^2);  NumIndets(RingOf(I));
</example>
The function <ttref>LinKer</ttref> has been replaced by <ttref>LinKerBasis</ttref>,
and there is a new function called <ttref>LinKer</ttref> which produces a matrix.
<par/>
More generally, see also the CoCoA-4 "translation table" in the
CoCoAManual directory or at
<verbatim>
  http://cocoa.dima.unige.it/cocoalib/doc/CoCoATranslationTable.html
</verbatim>
</description>
<keys>
  <key>translate</key>
  <key>translation</key>
  <key>cocoa4</key>
</keys>
<seealso>
  <see>CoCoA-4 mode</see>
  <see>TopLevel</see>
  <see>CurrentRing</see>
  <see>RingOf</see>
</seealso>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Recent changes in the CoCoA-5 language</title>
  <type>1</type>
<description>
There are a few changes in the language even from the first versions
of CoCoA-5.
<par/>
The operator <tt>Not</tt> has been replaced by the function <tt>not(...)</tt>.
<example>
/*5.0.9*/ If Not X IsIn L Then ... EndIf;
/*5.1.0*/ If not(X IsIn L) Then ... EndIf;
</example>
The anonymous function called <tt>lambda</tt> is now called <ttref>func</ttref>.
<example>
/*5.0.9*/  square := Lambda(x) Return x^2; EndLambda;
/*5.1.0*/  square := Func(x) Return x^2; EndFunc;
</example>
</description>
<keys>
  <key>translate</key>
  <key>translation</key>
  <key>cocoa5</key>
</keys>
<seealso>
  <see>not</see>
  <see>func</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Obsolete and obsolescent functions</title>
  <type>1</type>
<description>
As the language evolves some functions might become obsolete, maybe
just more sensibly renamed.  This is the list of such functions: see
in the manual for reasons/updates.
<obsolete_functions></obsolete_functions>

Some functions are obsolescent, that means that they are still usable
but will be deleted in some future version of CoCoA (leaving some time
to adapt to the replacing function).
<obsolescent_functions></obsolescent_functions>
</description>
</section>
</chapter>

</part>
<!-- ===  PART  =============================================== -->
<!-- ===  PART  =============================================== -->
<!-- ===  PART  =============================================== -->
<part>
  <title>CoCoA datatypes</title>
<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>BOOL</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to BOOL</title>
  <type>1</type>
  
<description>
The two BOOL constants are <tt>true</tt> and <tt>false</tt>.
(can also be written 
<tt>TRUE</tt>, <tt>FALSE</tt> and <tt>True</tt>, <tt>False</tt>)
They are mainly used with the commands <ttref>if</ttref>
and <ttref>while</ttref>, etc., inside CoCoA programs.
<par/>
The relational operators
<verbatim>
    =  &lt;&gt;  &lt;  &lt;=  &gt;  &gt;=
</verbatim>
return boolean constants (see <ref>Relational Operators</ref>).
<par/>
The boolean operators are <ttref>and</ttref>, <ttref>or</ttref>, <ttref>IsIn</ttref>.
From version CoCoA-5.0.9 <ttref>not</ttref> is a function (instead of
an operator).
</description>
<keys>
  <key>true</key>
  <key>false</key>
  <key>bool</key>
  <key>boolean expressions</key>
</keys>
<seealso>
  <see>Relational Operators</see>
  <see>Commands and Functions for BOOL</see>
  <see>Commands and Functions returning BOOL</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for BOOL</title>
  <type>1</type>
<description>
<commands_and_functions_for type="BOOL"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning BOOL</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="BOOL"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>INT</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to INT</title>
  <type>1</type>
  <description>
There are two types of numbers recognized by CoCoA: integers (type
<tt>INT</tt>), rationals (type <tt>RAT</tt>).
(CoCoA-4 also had <tt>ZMOD</tt>, but CoCoA-5 can deal with more rings:
see <ttref>NewRingFp</ttref>).
Numbers in CoCoA are handled with arbitrary precision.  This means that the
sizes of numbers are only limited by the amount of available memory.
The basic numeric operations---addition (<tt>+</tt>), subtraction (<tt>-</tt>),
multiplication (<tt>*</tt>), division (<tt>/</tt>), exponentiation (<tt>^</tt>),
and negation (<tt>-</tt>)---behave as one would expect.
Be careful, two adjacent minus signs, <tt>--</tt>, start a comment in CoCoA.
<example>
/**/  N := 3;
/**/  -N;
-3
--N;  &lt;-- THIS IS A COMMENT  (not C++ decrement)
</example>
</description>
<keys>
  <key>int</key>
</keys>
<seealso>
  <see>Commands and Functions for INT</see>
  <see>Commands and Functions returning INT</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for INT</title>
  <type>1</type>
<description>
<commands_and_functions_for type="INT"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning INT</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="INT"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>RAT</title>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to RAT</title>
  <type>2</type>
<description>
Rational numbers can be entered as fractions or as terminating decimals.
CoCoA always converts a rational number into a fraction in lowest terms.
<example>
/**/  3.8;
19/5
/**/  N := 4/8;  N;
1/2
/**/  type(N);
RAT
</example>
</description>
<keys>
  <key>rat</key>
</keys>
<seealso>
  <see>Commands and Functions for RAT</see>
  <see>Commands and Functions returning RAT</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for RAT</title>
  <type>1</type>
<description>
<commands_and_functions_for type="RAT"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning RAT</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="RAT"></commands_and_functions_rtn>
</description>
</section>

</chapter>
<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>STRING</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>String Literals</title>
  <type>1</type>
  
<description>
A string literal consists of a sequence of characters between double
quotes (<quotes>...</quotes>).
<example>
/**/ PrintLn "The primes up to 10 are ", [n in 1..10 | IsPrime(n)];
The primes up to 10 are [2, 3, 5, 7]

/**/ Print "The quick brown fox", "jumped over the lazy dog.";
The quick brown foxjumped over the lazy dog
</example>

To put special characters in CoCoA string literals use the appropriate
<em>escape sequence</em>.  Here is a summary:
  <tt>\"</tt>  produces a double-quote character;
  <tt>\n</tt>  produces a newline character;
  <tt>\\</tt>  produces a backslash character;
  <tt>\t</tt>  produces a TAB character;
  <tt>\r</tt>  produces a carriage-return character.
<example>
/**/ Print "line 1\nline 2";
line 1
line 2
/**/  Print "A string containing \"quote marks\".";
A string containing "quote marks".
</example>

WARNING: CoCoA still accepts an <em>obsolescent</em> syntax for string
literals (between single-quotes); do not use this!
</description>
<seealso>
  <see>String Operations</see>
  <see>sprint</see>
  <see>Commands and Functions for STRING</see>
  <see>Commands and Functions returning STRING</see>
</seealso>
<keys>
  <key>string</key>
  <key>strings</key>
  <key>characters</key>
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>String Operations</title>
  <type>2</type>

<description>
CoCoA offers only a few operations on strings: length, concatenation,
comparison, substring containment and indexing.
<example>
/**/ str := "Hello" + "World!";  --> string concatenation
/**/ Print str;
HelloWorld!
/**/ len(str);       --> length in characters
11
/**/ "Abc" &lt; str;    --> lexicographical comparison
true
/**/ str[1];         --> character indexing, indexes start from 1
H
</example>

The operator <ttref>IsIn</ttref> can be used to test if one string is
a substring of another.
<example>
/**/  mesg := "Banana";
/**/  "ana" IsIn mesg;
true
/**/  "Ana" IsIn mesg;  --> substring must be an exact match
false
</example>
</description>
<seealso>
  <see>String Literals</see>
  <see>ascii</see>
  <see>concat</see>
  <see>IsIn</see>
  <see>len</see>
</seealso>
<keys>
  <key>concatenation</key>
  <key>characters</key>
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for STRING</title>
  <type>1</type>
<description>
<commands_and_functions_for type="STRING"></commands_and_functions_for>
</description>
</section>

<section>
  <title>Commands and Functions returning STRING</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="STRING"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>LIST</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to LIST</title>
  <type>1</type>
  
<description>
A CoCoA list is a sequence of CoCoA objects between square brackets.
See also <ref>List Constructors</ref>.
<par/>
In particular, a list may contain other lists.  The empty list is <tt>[]</tt>.
If <tt>L</tt> is a list and <tt>N</tt> is an integer, then <tt>L[N]</tt> 
is the <tt>N</tt>-th component of <tt>L</tt>.
<par/>
If <tt>L</tt> contains sublists, then <tt>L[N_1, N_2,...,N_s]</tt>
is shorthand for <tt>L[N_1][N_2]...[N_s]</tt> (see the example below).
<par/>
Lists are often used to build structured objects of type <tt>MAT</tt>,
<tt>MODULEELEM</tt>, <tt>IDEAL</tt>, and <tt>MODULE</tt>.
<example>
/**/  Use R ::= QQ[t,x,y,z];
/**/  L := [34*x+y^2, "a string", [], [True, False]]; -- a list
/**/  L[1];  -- the 1st component
y^2 +34*x
/**/  L[2];
a string
/**/  L[3];
[ ]
/**/  L[4];  -- The 4th component is a list, itself;
[true, false]
/**/  L[4][1]; -- its 1st component;
true
/**/  L[4,1];  -- the same.
true

/**/  [1,"a"]+[2,"b"];  -- Note: one may add lists if their components are
[3, "ab"]               -- compatible (see "Algebraic Operators").

/**/  L := [x^2-y, t*y^2-z^3];
/**/  I := ideal(L);
/**/  I;
ideal(x^2 -y, t*y^2 -z^3)
</example>
</description>
<keys>
  <key>list</key>
</keys>
<seealso>
  <see>List Constructors</see>
  <see>Commands and Functions for LIST</see>
  <see>Commands and Functions returning LIST</see>
</seealso>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>List Constructors</title>
<description>
These operators create new lists.
<verbatim>
A..B
[A,B,C,...]
[X in L: <type>LIST</type> | B: <type>BOOL</type>]: <type>LIST</type>
[E:expression | X in L]: <type>LIST</type>
[E:expression | X in L: <type>LIST</type> and B: <type>BOOL</type>]: <type>LIST</type>
</verbatim>
<tt>A..B</tt> creates the list of integers from <tt>A</tt> to <tt>B</tt>, both ends are included.
<par/>
<tt>[A,B,C,...]</tt> makes a list containing <tt>A</tt>, <tt>B</tt>, <tt>C</tt> and so on, in that order.
<par/>
<tt>[X in L | B]</tt> makes a list of those elements in <tt>L</tt> for which condition <tt>B</tt> is true.
<par/>
<tt>[E | X in L]</tt> evaluates the expression <tt>E</tt> for each <tt>X</tt> in <tt>L</tt>, and collects
the results in a new list.
<par/>
<tt>[E | X in L and B]</tt> evaluates the expression <tt>E</tt> for each <tt>X</tt> in <tt>L</tt> which
satisfies the condition <tt>B</tt>, and collects the results in a new list.
<example>
/**/  [];  --> empty list
[]
/**/  1..4;
[1, 2, 3, 4]
/**/  [3,1,4,2];
[3, 1, 4, 2]
/**/  [N in 1..10 | IsPrime(N)];
[2, 3, 5, 7]
/**/  [N^2 | N in 1..4];
[1, 4, 9, 16]
/**/  [N^2 | N in 1..10 and IsPrime(N)];
[4, 9, 25, 49]
</example>
</description>
<seealso>
  <see>NewList</see>
  <see>append</see>
  <see>concat</see>
  <see>Range Operator</see>
  <see>CartesianProduct, CartesianProductList</see>
</seealso>
<keys>
  <key>[]</key>
  <key>making lists</key>
  <key>empty list</key>
</keys>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for LIST</title>
  <type>1</type>
<description>
<commands_and_functions_for type="LIST"></commands_and_functions_for>
</description>  
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning LIST</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="LIST"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>RECORD</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to RECORD</title>
  <type>1</type>
<description>
A record is a data type in CoCoA representing a list of bindings of
the form <em>name to object</em>.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  P := record[ I := ideal(x,y^2-z), F := x^2 + y, Misc := [1,3,4]];
/**/  P.I;
ideal(x, y^2 -z)
/**/ P["I"];
ideal(x, y^2 -z)

/**/  P.Misc;
[1, 3, 4]
/**/  P.Misc[2];
3

/**/  P.Date := "1/1/98";
/**/ indent(P);
record[
  Date := "1/1/98",
  F := x^2 +y,
  I := ideal(x, y^2 -z),
  Misc := [1, 3, 4]
]

/**/  P["Misc",3];  -- equivalent to P.Misc[3]
4
</example>

Each entry in a record is called a <em>field</em>.  Note that records are
<em>open</em> in the sense that their fields can be extended, as shown in
the previous example.  At present, there is no function for deleting
fields from a record, one must rewrite the record, selecting the
fields to retain:
<example>
/**/   P := record[A := 2, B := 3, C := 5, D := 7];
/**/   Q := record[];

  Foreach F In Fields(P) Do
    If F &lt;&gt; "C" Then Q[F] := P[F]; EndIf;
  EndForeach;

/**/  P := Q;
/**/  P;
record[A := 2, B := 3, D := 7]
</example>
</description>
<seealso>
  <see>Commands and Functions for RECORD</see>
  <see>Commands and Functions returning RECORD</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for RECORD</title>
  <type>1</type>
<description>
<commands_and_functions_for type="RECORD"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning RECORD</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="RECORD"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>FUNCTION</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to FUNCTION</title>
  <type>1</type>
<description>
The most important construct in CoCoA programming is the user-defined
function.  These functions take parameters, perform CoCoA commands,
and return values.  Collections of functions can be stored in text
files and read into CoCoA sessions using <ttref>source</ttref>.  To
prevent name conflicts of the type that are likely to arise if
functions are to be made available for use by others, the functions
can be collected in <em>packages</em>.
<par/>
To learn about user functions, look up <ttref>define</ttref> (online, enter
<tt>?define</tt>).
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>FUNCTIONs are first class objects</title>
  <type>1</type>
<description>
<par/>
In CoCoA-5 functions are "first class objects", and so may be passed
like any other value.
<example>
  -- The following function MyMax takes a function LessThan as parameter,
  -- and returns the maximum of X and Y w.r.t. the ordering defined by the
  -- function LessThan.

/**/  Define MyMax(LessThan, X, Y)
/**/    If LessThan(X, Y) Then Return Y; Else Return X; EndIf;
/**/  EndDefine;

  -- Let&apos;s use MyMax by giving two different orderings.

/**/  Define CompareLT(X, Y)  Return LT(X) &lt; LT(Y);  EndDefine;
/**/  Define CompareLC(X, Y)  Return LC(X) &lt; LC(Y);  EndDefine;

/**/  Use R ::= QQ[x,y,z];
/**/  MyMax(CompareLC, 3*x-y, 5*z-2);
5*z -2
/**/  MyMax(CompareLT, 3*x-y, 5*z-2);
3*x -y
</example>
</description>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for FUNCTION</title>
  <type>1</type>
<description>
<commands_and_functions_for type="FUNCTION"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning FUNCTION</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="FUNCTION"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>TYPE</title>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for TYPE</title>
  <type>1</type>
<description>
<commands_and_functions_for type="TYPE"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning TYPE</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="TYPE"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>RING</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to RING</title>
  <type>1</type>
  
<description>
Rings, and especially polynomial rings, play a central role in CoCoA.
<par/>
The user can define many rings, but at any time a <em>current ring</em> is
active within the system.
<par/>
Once a ring has been defined, the system can handle the following
mathematical objects defined over that ring:
<verbatim>
 * elements of the ring
 * ideals
 * matrices
 * lists of objects
 * modules (submodules of a free module)
 * rings
</verbatim>
Variables containing ring-dependent objects such as polynomials,
ideals, and matrices are <em>labeled</em> by their ring.
Any operation on them is performed in their ring, independently of
what the current ring is.
</description>
<keys>
  <key>ring</key>
</keys>
<seealso>
  <see>Polynomial Rings</see>
  <see>Commands and Functions for RING</see>
  <see>Commands and Functions returning RING</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Polynomial Rings</title>
  <type>1</type>

  <description>
CoCoA starts with the default (polynomial) ring <tt>R = QQ[x,y,z]</tt>.
Polynomial rings are created with the function <ttref>NewPolyRing</ttref>,
but there is a special simplyfied syntax working in most cases:
it must be preceded by the command <ttref>use</ttref> or by the symbol <tt>::=</tt> 
(or both)
<verbatim>
     R ::= C[X:INDETS];           use C[X:INDETS];
     R ::= C[X:INDETS], O;        use C[X:INDETS], O;
</verbatim>
<tt>R</tt> is the identifier of a CoCoALanguage variable,
<tt>C</tt> is a RING,
<tt>X</tt> is an expression that defines the indeterminates,
<tt>O</tt> is a pre-defined ordering (<tt>lex</tt>, <tt>deglex</tt>,
<tt>degrevlex</tt>).  The default ordering is DegRevLex.
<par/>
After the ring is defined using the above syntax, it can be made to be
the current ring with the command <ttref>use</ttref>.
<example>
/**/  Use R ::= QQ[a,b,c];  -- define and use the ring R
/**/  K := NewFractionField(R);
/**/  S ::= K[x,y], Lex;
/**/  CurrentRing;  -- the current ring is still R
RingWithID(21,"QQ[a,b,c]")
/**/  Use S;  -- now the ring S is the current ring
/**/  CurrentRing;
RingWithID(23,"RingWithID(22)[x,y]")
</example>
</description>
<seealso>
  <see>NewPolyRing</see>
  <see>CurrentRing</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Coefficient Rings</title>
  <type>2</type>
<description>
The coefficient ring for a CoCoA polynomial ring may be any ring <tt>R</tt>:
<verbatim>
 1. ZZ: (arbitrarily large) integer numbers;
 2. QQ: (arbitrarily large) rational numbers;
 3. ZZ/(N);
 4. R[a,b,c];
 5. K(a,b,c);  ....
</verbatim>
The first two types of coefficients are based on the GNU-gmp library.
Some operations work only when coefficients are in a field
(a meaningful error message will be thrown).
<example>
/**/  R ::= QQ[x,y];    R;
/**/  S ::= ZZ/(5)[t];  S;
/**/  -- NB: "::=" for special syntax C[X], ":=" for normal function call
/**/  QQi ::= QQ[i];
/**/  K := NewQuotientRing(QQi, ideal(ReadExpr(QQi, "i^2+1")));
/**/  U ::= K[u,v];     U;
</example>
</description>
<seealso>
  <see>CoeffRing</see>
</seealso>
<keys>
  <key>coeffring</key>
  <key>parameters</key>
</keys>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Indeterminates</title>
  <type>2</type>
<description>
An <em>indeterminate</em> is represented by an identifier followed by one or
more indices.
For example, <tt>x</tt>, <tt>alpha[1]</tt>, <tt>x[1,2,3]</tt> are legal (and
different) indeterminates,
as is <tt>x[i, 2*i+1]</tt> if I is of type <tt>INT</tt>.
<par/>
When creating a ring the indeterminates are listed separate by commas.
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  Use R ::= QQ[x[1..2,4..8],y[1..3],u,v];
/**/  Indets(R);
[x[1,4], x[1,5], x[1,6], x[1,7], x[1,8], x[2,4], x[2,5], x[2,6],
x[2,7], x[2,8], y[1], y[2], y[3], u, v]
-------------------------------
</example>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Orderings</title>
  <type>2</type>
<description>
Polynomials are always sorted with respect to the ordering of their
base ring.  All the operations involving polynomials utilize and
preserve this ordering. The user can define custom orderings or choose
a predefined term-ordering (see <ttref>NewPolyRing</ttref>)
<par/>
The predefined term-orderings are:
<par/>
 * standard-degree reverse lexicographic: <tt>DegRevLex</tt>  (default)
<par/>
 * standard-degree lexicographic: <tt>DegLex</tt>
<par/>
 * pure lexicographic: <tt>Lex</tt> (no grading)
<par/>
 * pure xel: <tt>Xel</tt> (NOT YET IMPLEMENTED)
<par/>
If the indeterminates are given in the order <tt>x_1, ...,x_n</tt>,
then <tt>x_1 &gt; ... &gt; x_n</tt> with respect to Lex, and
<tt>x_1 &lt; ... &lt; x_n</tt> with respect to Xel.
</description>
<keys>
  <key>degrevlex</key>
  <key>deglex</key>
  <key>lex</key>
  <key>xel</key>
</keys>
<seealso>
  <see>OrdMat</see>
  <see>elim</see>
</seealso>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Module Orderings</title>
  <type>2</type>

<description>
***** NOT YET UPDATED TO CoCoA-5 *****
<par/>
First we recall the definition of a module term-ordering. We assume
that all our free modules have finite rank and are of the type <formula>M = R^r</formula>
where R is a polynomial ring with n indeterminates.  Let
<formula>[e_i|i=1,...,r]</formula> be the canonical basis of M. A <em>term</em> of M is an
element of the form <formula>Te_i</formula> where T belongs to the set T(R) of the terms
of R.  Hence the set T(M), of the terms of M, is in one-to-one
correspondence with the Cartesian product, <formula>T(R)<times/>[1,...,r]</formula>.
<par/>
A <em>module term-ordering</em> is defined as a total ordering <formula>&gt;</formula> on T(M)
such that for all <tt>T, T_1, T_2</tt> in T(R), with T not equal to 1, and for
all i, j in {1,...,r},
<verbatim>
   (1)  T * T_1 * e_i &gt; T_1 * e_i
   (2)  T_1 * e_i &gt; T_2 * e_j  =&gt;  T * T_1 * e_i &gt; T * T_2 * e_j
</verbatim>
Each term-ordering on the current ring induces several term-orderings
on a free module.  CoCoA allows the user to choose between the
following:
<par/>
   * the ordering called <tt>ToPos</tt> (which is the default one) defined by:
<verbatim>
      T_1 * e_i &gt; T_2 * e_j &lt;=&gt;  T_1 &gt; T_2 in R
                                 or, if  T_1 = T_2 , i &lt; j
</verbatim>
   * the ordering called <tt>PosTo</tt> defined by:
<verbatim>
       T_1 * e_i &gt; T_2 * e_j &lt;=&gt; i &lt; j
                                 or, if i = j, T_1 &gt; T_2 in R .
</verbatim>

The leading term of the vector <formula>(x,y^2)</formula> with respect
to two different module term-orderings:

<example>
  Use R ::= QQ[x,y], ToPos;
  LT(Vector(x,y^2));
Vector(0, y^2)
-------------------------------
  Use R ::= QQ[x,y], PosTo;
  LT(Vector(x,y^2));
Vector(x, 0)
-------------------------------
</example>
</description>

<keys>
  <key>posto</key>
  <key>topos</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Accessing Other Rings</title>
  <type>1</type>
<description>
There are a variety of ways of interacting with a ring outside of the
current ring.
If a variable contains an object which does not depend
on a user-defined ring---for example an integer---that object can be
immediately accessed and used within any ring.
Built-in CoCoA functions should be smart enough to take into account
the rings in which their value was defined, for example
<ttref>GBasis</ttref>, <ttref>LT</ttref>, <ttref>wdeg</ttref>,...
<par/>
If you want to move an object from one ring to another, think
mathematically and use a <tt>RINGHOM</tt> and <ttref>apply</ttref>.
However there are handy (slower) shortcuts like
<ttref>image [OBSOLESCENT]</ttref> and <ttref>BringIn</ttref>,
or the constructors <ttref>matrix</ttref> and <ttref>RingElem</ttref>.
<par/>
<tt>QZP</tt>, <tt>ZPQ</tt> are NOT YET IMPLEMENTED.
</description>
<seealso>
  <see>Commands and Functions for RINGHOM</see>
  <see>Commands and Functions returning RINGHOM</see>
  <see>apply</see>
  <see>CanonicalHom</see>
  <see>PolyAlgebraHom</see>
  <see>PolyRingHom</see>
  <see>matrix</see>
  <see>RingElem</see>
  <see>BringIn</see>
  <see>QZP</see>
  <see>ZPQ</see>
  <see>use</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Quotient Rings</title>
  <type>1</type>
<description>
If <tt>R</tt> is a ring and <tt>I</tt> is an ideal (in <tt>R</tt>)
then <tt>R/I</tt> creates the corresponding quotient ring.
<example>
/**/  Use R ::= QQ[x,y];
/**/  I := ideal(x^3+y^3, x^2*y-y^2*x);
/**/  Q := R/I;
/**/  HilbertFn(Q);  -- the Hilbert function for Q
H(0) = 1
H(1) = 2
H(2) = 3
H(3) = 2
H(4) = 1
H(t) = 0   for t >= 5
</example>
</description>
<seealso>
  <see>NewQuotientRing</see>
</seealso>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for RING</title>
  <type>1</type>
<description>
<commands_and_functions_for type="RING"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning RING</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="RING"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>RINGHOM</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for RINGHOM</title>
  <type>1</type>
<description>
<commands_and_functions_for type="RINGHOM"></commands_and_functions_for>
</description>
</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning RINGHOM</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="RINGHOM"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>RINGELEM</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to RINGELEM</title>
  <type>1</type>
<description>
An object of type RINGELEM in CoCoA represents an element of a ring.
<par/>
To fix terminology about polynomials (elements of a polynomial ring):
a polynomial is a sum of terms;
each term is the product of a coefficient and power-product,
a power-product being a product of powers of indeterminates.
(In English it is standard to use <em>monomial</em> to mean a power-product,
however, in other languages, such as Italian, monomial connotes a
power-product multiplied by a scalar.
In the interest of world peace, we will use the term power-product in those
cases where confusion may arise.)
<example>
/**/  Use R ::= QQ[x,y,z];
/**/  F := ***3xyz + xy^2***;
/**/  F;
xy^2 + 3xyz
-------------------------------
  Use R ::= QQ[x[1..5]];
  Sum([x[N]^2 | N In 1..5]);
x[1]^2 + x[2]^2 + x[3]^2 + x[4]^2 + x[5]^2
-------------------------------
</example>

CoCoA always keeps polynomials ordered with respect to the
term-orderings of their corresponding rings.
<par/>
The following algebraic operations on polynomials are supported:
<verbatim>
  F^N, +F, -F, F*G, F/G if G divides F, F+G, F-G,
</verbatim>
where F, G are polynomials and N is an integer.  The result may be a
rational function.

<example>
  Use R ::= QQ[x,y,z];
  F := x^2+xy;
  G := x;
  F/G;
x + y
-------------------------------
  F/(x+z);
(x^2 + xy)/(x + z)
-------------------------------
  F^2;
x^4 + 2x^3y + x^2y^2
-------------------------------
  F^(-1);
1/(x^2 + xy)
-------------------------------
</example>
</description>

<keys>
  <key>power-product</key>
  <key>world peace</key>
</keys>
      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Evaluation of Polynomials</title>
  <type>1</type>

<description>
***** NOT YET UPDATED TO CoCoA-5: follow with care *****
<par/>
Polynomials may be evaluated using the function <ttref>subst</ttref>.  More
generally, <ttref>subst</ttref> allows one to substitute polynomials from the
current ring for the indeterminates of a given polynomial.  If
substitutions are to be made for each indeterminate, in order, it is
easier to use <ttref>eval</ttref>.
For more general substitutions, see <ttref>PolyAlgebraHom</ttref>.

<example>
  Use R ::= QQ[x,y,z];
  F := x+y+z;
  Eval(F,[2,1]); -- let x=2 and y=1 in F
z + 3
-------------------------------
  Subst(F,[[x,2],[y,1]]);  -- the same thing using Subst
z + 3
-------------------------------
  Subst(F,y,1); -- the syntax is easier when substituting for a single
                -- indeterminate
x + z + 1
-------------------------------
  Subst(F, [[y,x-y], [z,2]]);  -- substitute x-y for y and 2 for z
2x - y + 2
-------------------------------
</example>
</description>

<seealso>
  <see>eval</see>
  <see>subst</see>
</seealso>

      </section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for RINGELEM</title>
  <type>1</type>
<description>
<commands_and_functions_for type="RINGELEM"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning RINGELEM</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="RINGELEM"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>IDEAL</title>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for IDEAL</title>
  <type>1</type>
<description>
<commands_and_functions_for type="IDEAL"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning IDEAL</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="IDEAL"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>MAT</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to MAT</title>
  <type>1</type>

<description>
An m x n matrix is represented in CoCoA by the list of its rows
(see <ttref>matrix</ttref>).
The (A,B)-th entry of a matrix M is given by <tt>M[A][B]</tt> or <tt>M[A,B]</tt>.
<par/>
The following operations are defined as one would expect for matrices
<verbatim>
  M^A, +M, -N, M+N, M-N, M*N, F*M, M*F
</verbatim>
where M, N are matrices, A is a non-negative integer, and F is a
polynomial, with the obvious restrictions on the dimensions of the
matrices involved.
<example>
/**/  Use R ::= QQ[x,y];
/**/  N := matrix(R, [[1,2],[3,4]]);
/**/  N[1,2];
2;

/**/  N^2;
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[7, 10],
  [15, 22]])

/**/  x * N;
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[x, 2*x],
  [3*x, 4*x]])

/**/  N + matrix([[x,x], [y,y]]);
matrix( /*RingDistrMPolyClean(QQ, 2)*/
 [[x +1, x +2],
  [y +3, y +4]])
</example>
</description>

</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for MAT</title>
  <type>1</type>  
<description>
<commands_and_functions_for type="MAT"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning MAT</title>
  <type>1</type>  
<description>
<commands_and_functions_rtn type="MAT"></commands_and_functions_rtn>
</description>
</section>

</chapter>
    
<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>MODULE</title>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for MODULE</title>
  <type>1</type>
<description>
<commands_and_functions_for type="MODULE"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning MODULE</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="MODULE"></commands_and_functions_rtn>
</description>
</section>

</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>MODULEELEM</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Introduction to MODULEELEM</title>
  <type>1</type>
<description>
An object of type MODULEELEM in CoCoA represents a module element;
in CoCoA this usually means an element of the free module <tt>P^r</tt>,
where <tt>P</tt> is a polynomial ring.
For <tt>v</tt> and <tt>w</tt> MODULEELEM in the same MODULE,
and <tt>f</tt> RINGELEM in its base ring, the following are also MODULEELEM:
<verbatim>
   +v, -v, f*v, v*f, v+w, v-w
</verbatim>
See <ttref>ModuleElem</ttref>.
</description>
<seealso>
  <see>Commands and Functions for MODULEELEM</see>
  <see>Commands and Functions returning MODULEELEM</see>
</seealso>

</section>

<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for MODULEELEM</title>
  <type>1</type>
<description>
<commands_and_functions_for type="MODULEELEM"></commands_and_functions_for>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions returning MODULEELEM</title>
  <type>1</type>
<description>
<commands_and_functions_rtn type="MODULEELEM"></commands_and_functions_rtn>
</description>
</section>
</chapter>

<!-- ===  CHAPTER  =============================================== -->
<chapter>
  <title>Creating new types</title>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Tagging an Object</title>
  <type>1</type>
<description>
If <tt>E</tt> is any CoCoA object and <tt>S</tt> a string, then the function
<tt>Tagged(E, S)</tt> returns the object <tt>E</tt> tagged with the string <tt>S</tt>.
The returned object is then of type <tt>TAGGED(S)</tt>.
The function <ttref>tag</ttref> returns <tt>S</tt>, the tag string of an object,
and the function <ttref>untagged</ttref> returns <tt>E</tt>, the
original object, stripped of its tag.
<par/>
This is the way to add a new type at run-time.
<example>
/**/  L := ["Dave", "March 14, 1959", 372];
/**/  M := Tagged(L, "MiscData");  -- L tagged with the string "MiscData"
/**/  type(L);  -- L is a list
LIST
/**/  type(M);  -- M is a tagged object
TAGGED("MiscData")
/**/  M;  -- Until a special print function is defined, the printing of M
          -- is the same as L (with a WARNING)
["Dave", "March 14, 1959", 372]
</example>
The next section explains how to define functions for pretty printing
of tagged objects.
</description>
<keys>
  <key>dave</key>
</keys>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Printing a Tagged Object</title>
  <type>1</type>
<description>
Suppose the object <tt>E</tt> is tagged with the string <tt>S</tt>.
When one tries to print <tt>E</tt>---say with <tt>Print E</tt>---
CoCoA looks for a user-defined function with name <tt>Print_S</tt>.  If no such function is
available, CoCoA prints E as if it were not tagged, otherwise, it
executes <tt>Print_S</tt>.
<example>
/**/  L := ["Dave", "March 14", 1959, 372];
/**/  M := tagged(L,"MiscData");

/**/  Define SpecialPrinting(Dev, Obj)
/**/    Print Obj[1],"'s birthday is: ", Obj[2] on Dev;
/**/  EndDefine;

/**/  PrintTagged := record[MiscData := SpecialPrinting];

/**/  Print M;
Dave's birthday is: March 14
</example>
</description>
</section>
<!-- ===  SECTION  =============================================== -->
<section>
  <title>Commands and Functions for Tags</title>
  <type>1</type>
<description>
The following are commands and functions involving tags:
<commands_and_functions_for type="tags"></commands_and_functions_for>
</description>
</section>

</chapter>





</part>

</manual_parts>

</help>

<!--
 $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/CoCoA-5/CoCoAManual/CoCoAHelp.xml,v 1.352 2014/09/11 14:56:55 abbott Exp $
 $Log: CoCoAHelp.xml,v $
 Revision 1.352  2014/09/11 14:56:55  abbott
 Summary: Added a missing syntax to entry for operators/shortcuts
 Author: JAA

 Revision 1.351  2014/09/05 15:20:25  bigatti
 ++ fixed reference for tagged printing

 Revision 1.350  2014/09/05 15:15:13  bigatti
 ++ minor fix

 Revision 1.349  2014/09/05 10:33:45  bigatti
 ++ improved references to authors and to external libraries

 Revision 1.348  2014/09/04 16:46:00  bigatti
 ++ improved chapter about tags

 Revision 1.347  2014/09/04 12:36:37  bigatti
 ++ cleaned up max,min
 ++ added some thanks
 ++ removed some empty lines

 Revision 1.346  2014/09/03 13:41:18  abbott
 Summary: Improved entries for sum and product; replaced some "TypeA or TypeB" by "TypeA|TypeB"
 Author: JAA

 Revision 1.345  2014/09/03 12:11:34  abbott
 Summary: Corrected capital letters in entries for max and min
 Author: JAA

 Revision 1.344  2014/09/02 10:17:53  bigatti
 ++ added VerboseFlag to gin

 Revision 1.343  2014/08/29 12:42:16  bigatti
 ++ added test for ApproxSolve

 Revision 1.342  2014/08/16 13:40:42  abbott
 Summary: Changed  Latex -> LaTeX;  added kwd "matrix" to GetRow/GetCol
 Author: JAA

 Revision 1.341  2014/08/01 11:38:41  bigatti
 == added PLOT to plot file names

 Revision 1.340  2014/08/01 11:25:10  bigatti
 *** empty log message ***

 Revision 1.339  2014/08/01 11:24:33  bigatti
 == added CheckArgTypes
 == using '>' in examples instead of &gt

 Revision 1.338  2014/07/31 15:37:15  bigatti
 == all syntax is now above description

 Revision 1.337  2014/07/31 15:13:18  bigatti
 == syntax above

 Revision 1.336  2014/07/31 15:06:49  bigatti
 == syntax above (with macro)

 Revision 1.335  2014/07/31 14:51:15  bigatti
 == moved syntax above (with emacs macro)

 Revision 1.334  2014/07/31 14:46:03  bigatti
 ++ and more alignments

 Revision 1.333  2014/07/31 14:42:53  bigatti
 ++ more alignments

 Revision 1.332  2014/07/31 14:37:41  bigatti
 ++ mostly aligned now

 Revision 1.331  2014/07/31 14:22:54  bigatti
 ++ GradingMat (WeightsMatrix)
 ++ removed insert, NFsAreZero
 ++ fixed references

 Revision 1.330  2014/07/30 16:53:15  bigatti
 ++ fixed case in see reference (LIST)

 Revision 1.329  2014/07/30 16:49:32  bigatti
 ++ fixed date

 Revision 1.328  2014/07/30 16:48:14  bigatti
 ++ updated: chapter on rings
 ++ updated: subalgebra functions
 ++ reorganized lists

 Revision 1.327  2014/07/30 14:25:53  abbott
 Summary: Updated entry for BaseRing
 Author: JAA

 Revision 1.326  2014/07/29 13:07:24  abbott
 Summary: Added ".." as keyword for  Range Operator; cleaned entry for  LinSolve
 Author: JAA

 Revision 1.325  2014/07/29 07:53:13  bigatti
 ++ removed IsInImage, enriched PreImage

 Revision 1.324  2014/07/28 15:32:04  bigatti
 ++ insert is now obsolescent

 Revision 1.323  2014/07/28 14:58:19  abbott
 Summary: Improved return types for RationalSolve & friends
 Author: JAA

 Revision 1.322  2014/07/25 15:14:18  bigatti
 ++ added implicit
 ++ added section about recent changes in cocoa language
 ++ fixed a few things here and there

 Revision 1.321  2014/07/23 15:19:19  bigatti
 ++ added BettiDiagram and BettiMatrix

 Revision 1.320  2014/07/23 11:17:25  bigatti
 ++ fixed sorting on Nmz functions

 Revision 1.319  2014/07/22 14:15:40  bigatti
 ++ MinPoly, CharPoly

 Revision 1.318  2014/07/22 11:04:49  bigatti
 ++ updated BringIn for changing characteristic

 Revision 1.317  2014/07/18 12:48:53  bigatti
 ++ fixed some errors thank to make ManExamples

 Revision 1.316  2014/07/18 11:50:52  bigatti
 ++ minor fixes (found by E.Palezzato)

 Revision 1.315  2014/07/16 13:52:24  bigatti
 ++ minor changes for obsolete

 Revision 1.314  2014/07/16 13:23:51  bigatti
 ++ made new chaper about updating to cocoa5 and listing obsolete functions

 Revision 1.313  2014/07/15 16:25:45  bigatti
 ++ added citation for twin-float arithmetic
 ++ resurrected gin

 Revision 1.312  2014/07/15 12:50:28  bigatti
 ++ added [OBSOLETE] int the titel of obsolete functions

 Revision 1.311  2014/07/15 11:15:21  bigatti
 ++ fixed formulas for Nmz functions
 ++ fixed typos for htmk/tex compilation
 ++ added (obsolete) to some titles

 Revision 1.310  2014/07/14 16:26:57  bigatti
 ++ cleaning and updating HilbertXX functions

 Revision 1.309  2014/07/14 13:33:27  bigatti
 ++ added EmbeddingHom
 ++ minor corrections

 Revision 1.308  2014/07/14 10:07:17  abbott
 Summary: Added keyword length to "len" and "NumTerms"
 Author: JAA

 Revision 1.307  2014/07/14 08:45:12  bigatti
 ++ added IsInjective, IsSurjective, PreImage, IsInImage
 ++ modified entries about subalgebra

 Revision 1.306  2014/07/14 07:39:12  bigatti
 ++ updated ker (HomomorphismFns package)
 ++ added ReadExpr, updated RingElem
 ++ lower case in entry "use"

 Revision 1.305  2014/07/07 13:36:43  abbott
 Summary: Doc for Christof's new normaliz fns
 Author: JAA

 Revision 1.304  2014/07/04 10:59:02  bigatti
 ++ added ID(RING)

 Revision 1.303  2014/07/02 14:44:02  bigatti
 ++ added "obsolete" search key

 Revision 1.302  2014/07/02 14:05:56  bigatti
 ++ added RationalSolve & friends

 Revision 1.301  2014/07/01 14:35:11  bigatti
 ++ added SetRow, SwapRows

 Revision 1.300  2014/06/27 15:54:33  bigatti
 fixed missing parenthesis in CoeffEmbeddingHom

 Revision 1.299  2014/06/26 10:44:09  abbott
 Summary: Improved entry for NewRingFp (incl, mention of ZZ/(p) syntax)
 Author: JAA

 Revision 1.298  2014/06/04 09:17:04  bigatti
 added ")"

 Revision 1.297  2014/05/30 07:49:27  bigatti
 ++ minor: new key for bool and matrix entry

 Revision 1.296  2014/05/28 16:08:48  abbott
 Summary: Added <> as key for Equality Operator; modified a few seealso.
 Author: JAA

 Revision 1.295  2014/05/16 15:21:08  abbott
 Summary: Added ref to obs fn FloatApprx10 to entry for FloatApprox; improved entry for Func..EndFunc
 Author: JAA

 Revision 1.294  2014/05/16 11:57:57  bigatti
 ++ added MinGensGeneral
 ++ removed HIntersection
 ++ removed dangling references

 Revision 1.293  2014/05/14 15:53:26  bigatti
 ++ date

 Revision 1.292  2014/05/14 15:39:05  bigatti
 ++ finished cleaning after ManExamples-out

 Revision 1.291  2014/05/14 15:28:51  bigatti
 ++ more small correction after ManExamples-out

 Revision 1.290  2014/05/14 15:19:50  abbott
 Summary: Improved reference in page for PreprocessPts
 Author: JAA

 Revision 1.289  2014/05/14 14:56:45  bigatti
 ++ IndetSymbols

 Revision 1.288  2014/05/14 14:53:28  bigatti
 ++ Record to record

 Revision 1.287  2014/05/14 14:31:46  bigatti
 ++ small correctiosn after ManExamples-out

 Revision 1.286  2014/05/14 13:18:59  abbott
 Summary: Corrected entry for PreprocessPts (& reflowed the text)
 Author: JAA

 Revision 1.285  2014/05/14 13:17:34  bigatti
 ++ lots of small fixes (after running make ManExamples)

 Revision 1.284  2014/05/14 11:43:44  bigatti
 ++ removed one section about tags

 Revision 1.283  2014/05/14 07:34:53  bigatti
 ++ many little fixes (found with make AllExamples)

 Revision 1.282  2014/05/14 05:56:07  bigatti
 ++ improved intersection
 ++ cleaned up old packages

 Revision 1.281  2014/05/13 16:35:17  bigatti
 ++ more cleaning in the introductory part

 Revision 1.280  2014/05/13 16:25:02  abbott
 Summary: Revised entrioes for MantissaAndExponent10 and MantissaAndExponent2
 Author: JAA

 Revision 1.279  2014/05/13 16:18:34  bigatti
 ++ minor (on packages)

 Revision 1.278  2014/05/13 16:13:59  bigatti
 ++ quick update on packages

 Revision 1.277  2014/05/13 11:08:57  abbott
 Summary: Added entry MantissaAndExponent2; cleaned MantissaAndExponent10
 Author: JAA

 Revision 1.276  2014/05/12 16:58:13  bigatti
 ++ shortened manual for rings in descriptive part
 ++ added NumTerms entry
 ++ some smaller fixes and updates

 Revision 1.275  2014/05/09 20:31:11  abbott
 Summary: Added entry for NewRingTwinFloat; filled entry for NewRingFp
 Author: JAA

 Revision 1.274  2014/05/08 15:41:18  abbott
 Summary: Updated more fn signatures
 Author: JAA

 Revision 1.273  2014/05/08 13:46:37  abbott
 Summary: Improved entry for MantissaAndExponent10
 Author: JAA

 Revision 1.272  2014/05/08 13:38:53  abbott
 Summary: Much cleaning of syntaxes; also some entried cleaned a bit.
 Author: JAA

 Revision 1.271  2014/05/08 10:39:52  abbott
 Summary: Cleaned/improved entry for CpuTime; corrected fn signatures for FloatStr,DecimalStr,ScientificStr
 Author: JAA

 Revision 1.270  2014/05/07 15:20:51  abbott
 Summary: Added several <rtn>...</rtn> brackets to fn signatures
 Author: JAA

 Revision 1.269  2014/05/07 15:17:47  abbott
 Summary: Added many <type>...</type> brackets to fn signatures
 Author: JAA

 Revision 1.268  2014/05/07 12:55:59  abbott
 Summary: Fn "Comp" is now obsolete; updated manual too
 Author: JAA

 Revision 1.267  2014/05/07 11:31:53  abbott
 Summary: Improved entry for RingOf
 Author: JAA

 Revision 1.266  2014/05/06 16:19:48  abbott
 Summary: Reflowed entry for describe
 Author: JAA

 Revision 1.265  2014/05/06 13:22:46  abbott
 Summary: Added seealso append to concat & ConcatLists; improved MakeSet; corrected String Literals
 Author: JAA

 Revision 1.264  2014/05/02 14:54:31  abbott
 Summary: Improved entry for TimeFrom: reflowed, removed redundant seealso
 Author: JAA

 Revision 1.263  2014/05/02 14:49:10  abbott
 Summary: Cosmetic change to entry for String Literals
 Author: JAA

 Revision 1.262  2014/04/29 07:12:43  bigatti
 ++ more cleaning about OBSOLETE parts

 Revision 1.261  2014/04/28 12:16:39  abbott
 Summary: Added entry for IsQuotientRing
 Author: JAA

 Revision 1.260  2014/04/28 10:47:31  abbott
 Summary: added etry for  DefiningIdeal; revised entries for GBasis, ReducedGBasis
 Author: JAA

 Revision 1.259  2014/04/28 10:34:45  bigatti
 ++ updated image, matrix, PolyAlgebraHom

 Revision 1.258  2014/04/24 18:43:55  abbott
 Summary: Renamed SimplestRATBetween to SimplestRatBetween
 Author: JAA

 Revision 1.257  2014/04/24 18:00:16  abbott
 Summary: Added entries for GetCol, GetCols, ScientificStr; corrected entries for DecimalStr and FloatStr; also MantissaAndExponent10, and LinSol updated
 Author: JAA

 Revision 1.256  2014/04/24 16:21:27  bigatti
 ++ improvements

 Revision 1.255  2014/04/24 16:14:12  bigatti
 ++ updated TYPE
 ++ chapter for TYPE
 ++ moved chapter for MAT after RING

 Revision 1.254  2014/04/24 15:57:20  bigatti
 ++ more cleaning

 Revision 1.253  2014/04/24 15:35:05  bigatti
 ++ added author: soeger
 ++ more cleaning

 Revision 1.252  2014/04/24 15:30:25  bigatti
 ++ changed again author to <key>author: ..</key> still unused bu searchable

 Revision 1.251  2014/04/24 15:25:13  bigatti
 ++ new tag "author" (used to be "key"), in "keys".  Currently unused

 Revision 1.250  2014/04/24 14:48:52  bigatti
 ++ cleaning for FUNCTION
 ++ new chapter for FUNCTION in "data types"

 Revision 1.249  2014/04/24 13:57:55  bigatti
 ++ more cleaning on types

 Revision 1.248  2014/04/24 13:31:39  bigatti
 ++ more cleaning about types

 Revision 1.247  2014/04/24 13:25:54  bigatti
 ++ removed more "types"

 Revision 1.246  2014/04/24 13:18:30  bigatti
 ++ removed more "types"

 Revision 1.245  2014/04/24 13:02:43  bigatti
 ++ removed more "types"

 Revision 1.244  2014/04/24 12:35:43  bigatti
 ++ removed more "types"

 Revision 1.243  2014/04/24 12:29:19  bigatti
 ++ removed chapter on rational functions

 Revision 1.242  2014/04/24 12:22:06  bigatti
 ++ removed more "types"

 Revision 1.241  2014/04/24 12:16:17  bigatti
 ++ removed more "types"

 Revision 1.240  2014/04/24 11:40:46  bigatti
 ++ removed more "types"

 Revision 1.239  2014/04/24 11:36:47  bigatti
 ++ removed some "types"

 Revision 1.238  2014/04/24 11:15:57  bigatti
 ++ POLY to RINGELEM

 Revision 1.237  2014/04/24 10:59:49  bigatti
 ++ rtntype changed into rtn

 Revision 1.236  2014/04/24 10:55:37  bigatti
 ++ LIST

 Revision 1.235  2014/04/24 10:28:53  bigatti
 ++ RING, RINGELEM

 Revision 1.234  2014/04/24 10:22:46  bigatti
 ++ INT and STRING

 Revision 1.233  2014/04/24 10:00:11  bigatti
 ++ type RAT

 Revision 1.232  2014/04/24 09:56:34  bigatti
 ++ more rtntype conversions

 Revision 1.231  2014/04/24 09:51:07  abbott
 Summary: Revised entries for rational reconstruction
 Author: JAA

 Revision 1.230  2014/04/23 15:43:35  bigatti
 ++ type IDEAL in syntax

 Revision 1.229  2014/04/23 15:25:28  bigatti
 ++ more type/rtntype keys in syntax (MODULE MODULEELEM)

 Revision 1.228  2014/04/23 15:15:41  bigatti
 ++ updated chapters, removed some redundant parts (introduction to..)

 Revision 1.227  2014/04/23 15:03:16  bigatti
 ++ split numbers into INT and RAT

 Revision 1.226  2014/04/23 14:48:51  bigatti
 ++ more on types and rtntypes (BOOL)

 Revision 1.225  2014/04/23 13:48:40  bigatti
 ++ moved type MAT from types to syntax

 Revision 1.224  2014/04/23 12:45:38  bigatti
 capitalized MAT

 Revision 1.223  2014/04/23 12:41:44  bigatti
 ++ capitalized LIST

 Revision 1.222  2014/04/23 12:39:55  bigatti
 ++ first experiment on commands and functions for LIST

 Revision 1.221  2014/04/23 07:29:05  bigatti
 ++ more cleaning on chapter/section
 ++ MATRIX to MAT

 Revision 1.220  2014/04/23 06:59:36  bigatti
 ++ more cleaning on chapter/section parts
 ++ minor cleaning on alphabetical part

 Revision 1.219  2014/04/22 17:20:02  bigatti
 ++ removed backslash (no longer needed)
 ++ more cleaning

 Revision 1.218  2014/04/22 14:07:18  bigatti
 ++ updates (cleaning TeX compilation)

 Revision 1.217  2014/04/22 13:21:06  bigatti
 ++ updates for TeX

 Revision 1.216  2014/04/22 12:50:23  bigatti
 ++ removed entries GB.Blah

 Revision 1.215  2014/04/22 12:47:46  bigatti
 ++ removed content of functions GB.Blah

 Revision 1.214  2014/04/22 12:43:39  bigatti
 ++ rimosso contenuto di molti "chapter"

 Revision 1.213  2014/04/22 10:48:18  abbott
 Summary: Added new pages for "String Literals" and "String Operations"; other minor changes
 Author: JAA

 Revision 1.212  2014/04/17 13:44:13  bigatti
 ++ cleaning, especially on matrices

 Revision 1.211  2014/04/16 10:56:43  abbott
 Summary: Cleaned entry for TimeFrom; some other minor cleaning
 Author: JAA

 Revision 1.210  2014/04/15 13:45:17  abbott
 Summary: Shortened entry for "factor"; some other minor cleaning
 Author: JAA

 Revision 1.209  2014/04/15 13:32:00  abbott
 Summary: Added entry for PrimitiveRoot; some minor cleaning
 Author: JAA

 Revision 1.208  2014/04/11 14:25:24  bigatti
 ++ fixed some cross-links
 ++ added ZeroMat

 Revision 1.207  2014/04/11 14:08:58  bigatti
 ++ fixed for Latex

 Revision 1.206  2014/04/11 13:47:12  bigatti
 ++ vector to moduleelem and some related cleaning

 Revision 1.205  2014/04/10 16:16:56  bigatti
 ++ mixed matrices

 Revision 1.204  2014/04/10 16:02:20  bigatti
 ++ minimalized(submodule)

 Revision 1.203  2014/04/10 15:33:30  abbott
 Summary: Added entry for TimeFrom
 Author: JAA

 Revision 1.202  2014/04/10 07:30:12  bigatti
 ++ added PrintBettiDiagram, PrintBettiMatrix, PrintRes

 Revision 1.201  2014/04/09 15:11:11  abbott
 Summary: Cleaned/compacted man page about list ctors; other minor cleaning
 Author: JAA

 Revision 1.200  2014/04/09 14:54:24  abbott
 Summary: Added new entries "GetRow" & "GetRows"; removed obsolete "list"
 Author: JAA

 Revision 1.199  2014/04/09 14:25:04  abbott
 Summary: Updated entry for list contructors
 Author: JAA

 Revision 1.198  2014/04/09 13:55:39  abbott
 Summary: Added entries for "protect" and "unprotect"
 Author: JAA

 Revision 1.197  2014/04/09 13:44:45  bigatti
 ++ improved ideal, submodule, SubmoduleRows

 Revision 1.196  2014/04/09 13:29:42  bigatti
 ++ changed examples SyzOfGens

 Revision 1.195  2014/04/09 12:50:03  abbott
 Summary: Split "not,and,or" page into 3; split "Relational Operators" into "Equality Test" and "Comparison Operators"
 Author: JAA

 Revision 1.194  2014/04/08 16:36:12  abbott
 Summary: Changed SqfreeFactor to SqFreeFactor
 Author: JAA

 Revision 1.193  2014/04/07 16:50:23  bigatti
 ++ changes NewMat and NewMatFilled

 Revision 1.192  2014/04/07 10:34:32  abbott
 Summary: Added entry for "record field selector"; removed "see also operators"
 Author: JAA

 Revision 1.191  2014/04/04 15:45:07  abbott
 Summary: Cleaned entries for CFApprox, CFApproximants, ContFrac, ContFracToRat
 Author: JAA

 Revision 1.190  2014/04/04 10:29:51  abbott
 Summary: Separated man pages for floor and ceil
 Author: JAA

 Revision 1.189  2014/04/04 10:16:13  abbott
 Summary: Improved font on page "and, or, not"; added keywords
 Author: JAA

 Revision 1.188  2014/04/02 11:14:45  bigatti
 ++ updated BringIn

 Revision 1.187  2014/04/02 10:41:54  abbott
 Summary: Revised entries for PolyAlgebraHom, CoeffListWRT, and BringIn (minor)
 Author: JAA

 Revision 1.186  2014/03/28 18:23:32  bigatti
 ++ minor correctio for Normaliz

 Revision 1.185  2014/03/28 15:51:53  bigatti
 ++ cleaned some "commands and functions for .."

 Revision 1.184  2014/03/28 15:35:41  bigatti
 removed "H." entries

 Revision 1.183  2014/03/28 15:28:07  abbott
 Summary: Added new page "list constructors"; reduce page "in" to a reference to "list ctors"; updated "operators, shortcuts"
 Author: JAA

 Revision 1.182  2014/03/28 13:21:39  bigatti
 ++ some fixes for xsl
 ++ updated Frb functions

 Revision 1.181  2014/03/28 07:14:12  bigatti
 ++ cleaned eigenvectors and LinearSimplify
 ++ cleaned and fixed Frobby

 Revision 1.180  2014/03/27 17:36:42  bigatti
 ++ minimalize, minimalized

 Revision 1.179  2014/03/27 15:11:09  bigatti
 ++ fixed return
 ++ improved RingElem

 Revision 1.178  2014/03/27 15:09:56  abbott
 Summary: Lowercased several fn calls in examples
 Author: JAA

 Revision 1.177  2014/03/26 18:00:56  bigatti
 ++ MinGens for submodule

 Revision 1.176  2014/03/26 16:33:11  abbott
 Summary: Corrected entry for binomial
 Author: JAA

 Revision 1.175  2014/03/26 15:45:22  bigatti
 ++ example for NewQuotientRing

 Revision 1.174  2014/03/26 15:28:28  bigatti
 ++ removed "/DOS"

 Revision 1.173  2014/03/26 13:18:26  abbott
 Summary: Corrected/cleaned entries for DerivationAction, InverseSystem, PerpIdealOfForm
 Author: JAA

 Revision 1.172  2014/03/26 12:19:33  abbott
 Summary: Removed several GRATUITOUS CoCoA-4 mode expressions from examples
 Author: JAA

 Revision 1.171  2014/03/26 12:11:58  abbott
 Summary: Corrected entry for CoefficientsWRT; added entries for incr/decr, CoCoA-4 mode, updating CoCoA-4 code
 Author: JAA

 Revision 1.170  2014/03/25 15:23:40  abbott
 Summary: Corrected XML syntax of enty for TgCone
 Author: JAA

 Revision 1.169  2014/03/25 15:21:25  abbott
 Summary: Added entries for ImportByRef/ImportByValue and TopLevel
 Author: JAA

 Revision 1.168  2014/03/25 14:56:30  bigatti
 ++ some changes to BinRepr
 ++ some changes to NumPartitions

 Revision 1.167  2014/03/25 14:34:09  abbott
 Summary: Improved entry for  ref
 Author: JAA

 Revision 1.166  2014/03/25 14:18:30  abbott
 Summary: Cleaned entries for append, func, swap
 Author: JAA

 Revision 1.165  2014/03/25 12:08:14  abbott
 Summary: Improved entry for remove; changed name of IntersectionList; minor cleaning
 Author: JAA

 Revision 1.164  2014/03/21 15:48:34  bigatti
 ++ improved example in DF

 Revision 1.163  2014/03/21 12:03:00  abbott
 Summary: Improved entry for strings (e.g. added ops on strings)
 Author: JAA

 Revision 1.162  2014/03/21 11:54:06  bigatti
 ++ improved doc for SyzOfGens (module)

 Revision 1.161  2014/03/21 10:49:53  bigatti
 ++ improved MinGens, minimalize, minimalized
 ++ in IsFactorClosed used "1"
 ++ resurrected RelNotes

 Revision 1.160  2014/03/20 17:29:00  abbott
 Summary: Added CoeffEmbeddingHom
 Author: JAA

 Revision 1.159  2014/03/20 16:23:51  bigatti
 ++ comment on LinKer

 Revision 1.158  2014/03/19 16:56:03  abbott
 Summary: Revised entry for NewLine
 Author: JAA

 Revision 1.157  2014/03/19 16:22:51  abbott
 Summary: Added entries for floor/ceil/round; revised entries for describe/Function/Functions/Other help
 Author: JAA

 Revision 1.156  2014/03/14 11:49:37  abbott
 Summary: Added L[N] to page about operators
 Author: JAA

 Revision 1.155  2014/03/14 11:45:45  abbott
 Summary: Many changes: operators, CpuTime, CRT, fields, foreach, div & mod, monic, record, comments, strings
 Author: JAA

 Revision 1.154  2014/03/12 21:53:44  bigatti
 ++ added "All CoCoA commands"

 Revision 1.153  2014/03/06 15:56:42  abbott
 Summary: Corrected entry for LinSolve
 Author: JAA

 Revision 1.152  2014/03/05 17:35:14  abbott
 Summary: Added missing end-of-description marker
 Author: JAA

 Revision 1.151  2014/03/05 17:28:59  abbott
 Summary: Completed syntax for operators; greatly simplified page for "manual"
 Author: JAA

 Revision 1.150  2014/03/05 16:18:13  abbott
 Summary: Improved man page for logical operators (and, or, not)
 Author: JAA

 Revision 1.149  2014/03/05 14:49:31  bigatti
 ++ improved NewPolyRing, use, operators/shortcuts

 Revision 1.148  2014/03/05 13:48:02  abbott
 Summary: Added entry for cyclotomic; added note to entry for IsFactorClosed.
 Author: JAA

 Revision 1.147  2014/03/05 13:10:24  abbott
 Summary: Clean up page for operators (removed @, ??)
 Author: JAA

 Revision 1.146  2014/03/05 12:55:45  bigatti
 ++ removed minus-es in the log (for XSL)

 Revision 1.145  2014/03/05 12:53:56  bigatti
 ++ improved doc for E_

 Revision 1.144  2014/03/05 10:01:58  bigatti
 ++ some improvements

 Revision 1.143  2014/03/03 18:16:46  bigatti
 ++ added PrimaryPoincare

 Revision 1.142  2014/02/28 21:55:36  bigatti
 ++ added InitialIdeal
 ++ improved TgCone

 Revision 1.141  2014/02/26 15:37:34  abbott
 Summary: Added to QuotientBasis see-also IsFactorClosed
 Author: JAA

 Revision 1.140  2014/02/25 11:16:13  abbott
 Summary: Moved entry for "swap" to correct place
 Author: JAA

 Revision 1.139  2014/02/25 11:03:02  abbott
 Summary: Replaced  Lambda...EndLambda by Func...EndFunc; renamed Not to not(...)
 Author: JAA

 Revision 1.138  2014/02/21 11:27:43  abbott
 Summary: Improved entry for "div"; added entry for "IsIndet"; updated entry for "eigenvectors"
 Author: JAA

 Revision 1.137  2014/01/28 17:12:50  bigatti
 ++ added doc for NmzComputation

 Revision 1.136  2014/01/28 12:27:53  bigatti
 ++ improved doc for LF and DF

 Revision 1.135  2014/01/23 13:03:23  abbott
 Completed doc for IsDivisible.

 Revision 1.134  2014/01/16 16:20:05  abbott
 Added doc for NumPartitions.
 Corrected entries for  IsPrime, NextPrime, NextProbPrime.
 Sundry other cleaning.

 Revision 1.133  2013/11/21 08:35:16  abbott
 Improved entry for SortBy.  A couple of other minor changes.

 Revision 1.132  2013/10/30 08:52:32  bigatti
 ++ some label/reference fixes
 ++ the variable it  moved in "commands" and titled "It" (as for CurrentRing)
 ++ added a couple of missing closed command tags
 ++ NmzComputation had empty syntax breaking tex compilation

 Revision 1.131  2013/10/28 13:01:52  bigatti
 ++ added Elim(RingElem, ideal)

 Revision 1.130  2013/10/22 14:15:07  abbott
 Added SqFreeFactor.

 Revision 1.129  2013/10/15 16:22:57  abbott
 Added doc for valuation (also IsConstant, and ContentFreeFactor?).

 Revision 1.128  2013/10/11 10:32:50  bigatti
 ++ added R/I to Shortcuts

 Revision 1.127  2013/10/02 13:54:47  abbott
 Improved entry for dot-dot operator.

 Revision 1.126  2013/08/02 16:37:26  bigatti
 ++ added shifts to NewFreeModule

 Revision 1.125  2013/08/02 15:06:08  bigatti
 ++ fixed naming conventions for record field names
  MantissaAndExponent, RealRoots, IdealAndSeparatorsOfPoints

 Revision 1.124  2013/08/02 14:46:11  bigatti
 ++ updated DivAlg for moduleelem
 ++ updated LC for moduleelem
 ++ changed LPos into LPosn

 Revision 1.123  2013/07/31 14:44:00  bigatti
 added NumCompts

 Revision 1.122  2013/07/31 14:21:00  bigatti
 ++ added HilbertSeries and HilbertFn for MODULE

 Revision 1.121  2013/07/31 09:44:45  bigatti
 added some comments about naming conventions

 Revision 1.120  2013/07/31 09:42:01  bigatti
 updated "hilbert" entries

 Revision 1.119  2013/07/30 16:47:33  bigatti
 ++ improved entries HilbertSeries and factor/SmoothFactor

 Revision 1.118  2013/07/30 14:54:49  bigatti
 ++ updated factor, SmoothFactor (Exponents into multiplicities)
 ++ updated Frobby functions (Frb)
 ++ added IsStdGraded

 Revision 1.117  2013/06/26 17:58:31  bigatti
 ++ improved entry for append

 Revision 1.116  2013/06/26 10:02:58  bigatti
 ++ added RingQQ, RingQQt, RingZZ
 ++ added JanetBasis
 ++ updated Frobby functions and PrimaryDecomposition

 Revision 1.115  2013/06/17 10:20:02  bigatti
 merged entries for IsFactorClosed

 Revision 1.114  2013/06/17 10:10:27  bigatti
 added IsFactorClosed

 Revision 1.113  2013/06/17 09:39:02  abbott
 Added entry for IsFactorClosed.

 Revision 1.112  2013/06/17 08:58:28  abbott
 Updated entry for LinearSimplify.

 Revision 1.111  2013/06/13 07:39:29  bigatti
 updated ColumnVectors

 Revision 1.110  2013/06/13 07:32:46  bigatti
 added TgCone

 Revision 1.109  2013/06/13 07:22:25  bigatti
 *** empty log message ***

 Revision 1.108  2013/06/12 08:58:57  bigatti
 improved doc for CartesianProduct
 added new MinGens

 Revision 1.107  2013/06/06 06:01:05  bigatti
 Improved NewFreeModule, NewFractionField
 added IsElem, IsContained

 Revision 1.106  2013/06/03 11:47:26  abbott
 Moved BinomialRepr to correct place; corrected signature of fn LC.

 Revision 1.105  2013/05/31 14:54:17  bigatti
 cleaned entry for submodule

 Revision 1.104  2013/05/31 12:42:35  bigatti
 changed BlockMat into BlockMat2x2
 changed MultiBlockMat into BlockMat

 Revision 1.103  2013/05/31 07:50:32  bigatti
 improved deriv

 Revision 1.102  2013/05/31 07:28:02  bigatti
 added MultiBlockMat

 Revision 1.101  2013/05/30 07:21:20  bigatti
 *** empty log message ***

 Revision 1.100  2013/05/30 07:20:16  bigatti
 ++ added TimeOfDay
 ++ fixed date
 ++ added IsZeroDivisor

 Revision 1.99  2013/05/28 15:26:28  abbott
 Synchronized the entries for CharPoly and MinPoly.

 Revision 1.98  2013/05/28 15:14:26  bigatti
 ++ added MinPoly
 ++ improved submodule manual

 Revision 1.97  2013/05/21 15:38:47  abbott
 Improved/completed entry for "indent".

 Revision 1.96  2013/05/21 14:31:45  abbott
 Added BinomialRepr and BinomialReprShift to CoCoALib and CoCoA-5.

 Revision 1.95  2013/05/21 11:33:37  abbott
 Added rows and cols as keywords for entry about MakeMatByRows/Cols.

 Revision 1.94  2013/05/06 12:11:48  abbott
 Changed entry for "deriv" (previously "Der").

 Revision 1.93  2013/05/03 15:20:10  bigatti
 ++ added IsZeroDim
 ++ changed HilbertBasis into HilbertBasisKer

 Revision 1.92  2013/04/29 09:12:00  abbott
 Added keyword "quotient" to colon operator.

 Revision 1.91  2013/04/24 09:15:56  abbott
 Moved an entry into the right alphabetical place.

 Revision 1.90  2013/04/17 16:41:02  abbott
 Removed ref to FullRed from interreduce.
 Added new keys to IsDivisible.

 Revision 1.89  2013/04/16 15:44:23  bigatti
 ++ updated entry IdealOfPoints
 ++ updated entry QuotientBasis
 ++ removed NormalizHilbertBasis (is NmzHilbertBasis)

 Revision 1.88  2013/04/16 14:46:16  abbott
 Further improvement to page for interreduce.

 Revision 1.87  2013/04/15 12:35:07  abbott
 Improved entry for interreduce/interreduced.

 Revision 1.86  2013/04/05 15:03:16  bigatti
 ++ added indent

 Revision 1.85  2013/04/04 16:11:44  abbott
 Added some search keys to the entry for logical operators and/or/not.

 Revision 1.84  2013/03/28 15:16:55  abbott
 Changed preprocessing fns so that they produce a matrix containing the
 new points (consistent with the input being a matrix containing the
 points).

 Revision 1.83  2013/03/27 18:25:04  abbott
 Added doc for approx point preprocessing fns.

 Revision 1.82  2013/03/27 17:00:02  bigatti
 ++ updated syntax for format

 Revision 1.81  2013/03/26 15:38:46  abbott
 Improved entry for "ref".

 Revision 1.80  2013/03/21 15:44:17  bigatti
 ++ improved example for format

 Revision 1.79  2013/03/21 15:10:12  bigatti
 ++ added doc for functions and commands for ring homomorphisms
 ++ added doc for RingElem(RING, RINGELEM)

 Revision 1.78  2013/03/15 17:48:37  abbott
 Improved (alphabetical) order of entries.

 Revision 1.77  2013/03/14 15:40:01  bigatti
 minor fix in log tail comments

 Revision 1.76  2013/03/14 15:38:57  bigatti
 ++ fixed NmzIntClosureToricRing
 ++ added NmzNormalToricRing

 Revision 1.75  2013/03/12 14:43:54  abbott
 Improved the order of entries in the manual.

 Revision 1.74  2013/03/11 17:57:47  abbott
 Improved entry for SourceRegion.

 Revision 1.73  2013/03/08 10:07:21  abbott
 Added doc for SourceRegion.

 Revision 1.72  2013/03/07 17:49:59  abbott
 Added key "chinese" to entry for CRT.

 Revision 1.71  2013/02/27 10:43:37  bigatti
 ++ changed title (without <em>) in  The variable It

 Revision 1.70  2013/02/26 14:10:55  abbott
 Changed name of fn "ord" into "OrdMat".

 Revision 1.69  2013/02/26 11:49:34  abbott
 Added RatReconstructWithBounds.
 Updated entries for CurrentRing, the variable It, the Use command.

 Revision 1.68  2013/02/25 11:48:11  bigatti
 ++ swapped some unsorted entries

 Revision 1.67  2013/02/22 22:44:59  abbott
 Added doc for new fn CRT.

 Revision 1.66  2013/02/22 18:58:04  abbott
 Added new fns RatReconstructByContFrac and RatReconstructByLattice.

 Revision 1.65  2013/02/22 12:43:06  bigatti
 ++ changed GenRepr

 Revision 1.64  2013/02/22 11:06:44  bigatti
 ++ added CanonicalHom
 ++ added content
 ++ updated some "NOT YET IMPLEMENTED" entries
 ++ fixed some broken references (thanks TeX)

 Revision 1.63  2013/02/21 17:21:04  bigatti
 *** empty log message ***

 Revision 1.62  2013/02/21 17:20:26  bigatti
 ++ added GensAsCols, GensAsRows

 Revision 1.61  2013/02/21 12:53:24  bigatti
 ++ added DF and improved LF
 ++ updated SyzOfGens and syz

 Revision 1.60  2013/02/19 18:53:54  abbott
 Improved doc for "indets".

 Revision 1.59  2013/02/15 16:05:08  bigatti
 ++ added ElimMat, HomogElimMat
 ++ added ex for matrix(R,M)

 Revision 1.58  2013/02/14 09:49:47  bigatti
 ++ added ConcatHorList, ConcatVerList
 ++ updated PerpIdealOfForm

 Revision 1.57  2013/02/12 16:20:20  bigatti
 ++ fixed some entries for modules
 ++ updated IsHomog for GradingDim=0

 Revision 1.56  2013/02/11 11:06:36  bigatti
 ++ minor improvement to CpuTime
 ++ updated section Timer and Indentation

 Revision 1.55  2013/02/06 11:41:15  bigatti
 ++ added LinKerBasis

 Revision 1.54  2013/02/04 16:19:02  bigatti
 ++ added Normaliz (Nmz) functions

 Revision 1.53  2013/01/30 15:53:51  bigatti
 ++ added some search keys

 Revision 1.52  2013/01/30 15:49:27  bigatti
 ++ added SubmoduleCols/Rows, ModuleOf
 ++ some improvements to modules
 ++ removed unnecessary &gt;

 Revision 1.51  2013/01/24 17:39:37  bigatti
 ++ moved in the correct alphabetical position: wdeg
 ++ fixed deg

 Revision 1.50  2013/01/24 17:29:33  bigatti
 ++ moved in the correct alphabetical position: PoincareShifts,
    subalgebra.., factorial

 Revision 1.49  2013/01/24 17:26:04  bigatti
 ++ moved in the correct alphabetical position: QQ, StdDeg.., HilbertBasis

 Revision 1.48  2013/01/24 17:19:56  bigatti
  ++ moved in the correct alphabetical position: CoeffRing, submat

 Revision 1.47  2013/01/24 14:53:41  bigatti
  ++ moved in the correct alphabetical position: Concat..,
     NextProbPrime, IndetSubscripts

 Revision 1.46  2013/01/24 14:45:02  bigatti
  ++ moved in the correct alphabetical position: IsDivisible,
     IsProbPrime, Lambda

 Revision 1.45  2013/01/24 14:41:28  bigatti
 ++ moved in the correct alphabetical position: IndetName, SortBy, Sylvester

 Revision 1.44  2013/01/24 14:36:01  bigatti
 ++ moved in the correct alphabetical position: moduleelem and ref

 Revision 1.43  2013/01/24 14:27:50  bigatti
 ++ changed VECTOR to MODULEELEM

 Revision 1.42  2013/01/23 14:37:53  bigatti
 ++ added first function for modules
 ++ added NewFractionField
 ++ added CpuTime

 Revision 1.41  2013/01/21 13:24:51  bigatti
 ++ replaced <quotes> in syntax and example into "

 Revision 1.40  2013/01/21 11:30:29  bigatti
 ++ merged "IndetsCalled" documentation into "indets" (after renaming)

 Revision 1.39  2013/01/14 17:19:32  bigatti
 ++ improved NF, NR
 ++ added ZZ, QQ

 Revision 1.38  2013/01/07 17:06:41  bigatti
 ++ added example for InducedHom and PolyRingHom
 ++ added ZZ, QQ in Reserved Names
 ++ minor fixes

 Revision 1.37  2012/12/17 15:05:04  bigatti
 ++ added InducedHom, IsDivisible, PolyRingHom

 Revision 1.36  2012/12/11 17:31:36  abbott
 Changed name from SimplestRationalInInterval to SimplestRATBetween.

 Revision 1.35  2012/12/05 15:33:48  abbott
 Corrected an example for SimplestRationalInInterval.

 Revision 1.34  2012/12/05 15:33:02  abbott
 Added new fn SimplestRationalInInterval.

 Revision 1.33  2012/12/05 15:11:00  abbott
 Corrected entry for CFApprox.
 Replaced "denominator" by "quotient" in all doc about continued fractions.
 Some minor cleaning.

 Revision 1.32  2012/11/28 10:51:43  bigatti
 ++ added one, zero
 ++ added cast/convert key to some functions
 ++ added CoeffListWRT and fixed coefficients and CoefficientsWRT

 Revision 1.31  2012/11/23 17:51:48  bigatti
 ++ added manual for CompleteToOrd

 Revision 1.30  2012/10/05 10:24:20  bigatti
 ++ added LF (leading form)

 Revision 1.29  2012/10/02 16:48:55  bigatti
 ++ added homog for ideal

 Revision 1.28  2012/07/31 13:27:30  bigatti
 ++ updated entry: NBM

 Revision 1.27  2012/07/11 15:15:00  bigatti
 ++ some alphabethical sorting
 ++ added "empty" normaliz functions
 ++ added TopLevelFunctions

 Revision 1.26  2012/07/10 12:02:02  bigatti
 ++ added LinKer
 ++ removed body for LinSol

 Revision 1.25  2012/06/19 15:39:20  bigatti
 ++ minor update for VersionInfo
 ++ replaced some <quotes> in <tt> and <example> with "

 Revision 1.24  2012/06/18 10:08:10  bigatti
 ++ added version
 ++ removed some quotes

 Revision 1.23  2012/06/08 15:34:56  bigatti
 ++ added some entires (see redmine)
 ++ fixed casing for broken links
 ++ changed some  quotes  into  "

 Revision 1.22  2012/05/30 14:24:24  abbott
 Minor improvements to doc for AsINT and AsRAT.

 Revision 1.21  2012/05/30 12:46:34  abbott
 Improved example for SortBy and SortedBy.
 Made sure the keyword Define has a capital D,
 and that the keyword ref is all lower case.

 Revision 1.20  2012/05/28 10:33:34  abbott
 Added IsTrueGCDDomain.

 Revision 1.19  2012/05/25 13:07:23  abbott
 Added entry for Bool01.
 Added signature abs(RINGELEM):RINGELEM
 Cleaned entry for "Try".

 Revision 1.18  2012/05/24 14:54:20  bigatti
 ++ changed symbol "index" into "subscripts"
 ++ added manual entry for "lambda"

 Revision 1.17  2012/05/16 13:04:14  bigatti
 ++ added AsINT, AsRAT

 Revision 1.16  2012/05/15 13:56:43  bigatti
 ++ fixed manual for gcd and lcm

 Revision 1.15  2012/04/27 14:56:35  bigatti
 ++ added some "*"

 Revision 1.14  2012/04/27 14:50:03  abbott
 Added LinSolve

 Revision 1.13  2012/04/24 14:26:28  abbott
 Added IsFiniteField, IsPthPower, LogCardinality, PthRoot.
 Corrected CheckArgTypes.

 Revision 1.12  2012/04/04 15:57:48  bigatti
 *** empty log message ***

 Revision 1.11  2012/04/04 11:10:43  bigatti
 ++ added ***** NOT YET UPDATED TO CoCoA-5: follow with care ***** in sections

 Revision 1.10  2012/04/04 08:16:05  bigatti
 ++ minor changes (new syntax for IdealOfPoints)
 ++ highlighted "NOT YET IMPLEMENTED" and "OBSOLETE MANUAL"

 Revision 1.9  2012/04/03 10:46:32  bigatti
 ++ added IndetSymbols, SymbolRange
 ++ more cleaning and perfectioning

 Revision 1.8  2012/03/30 09:31:15  bigatti
 ++ minor change

 Revision 1.7  2012/03/29 08:42:14  bigatti
 ++ changed Mat/matrix and updated doc on matrices
 ++ changed syntax for ContentWRT/CoefficientsWRT

 Revision 1.6  2012/03/21 09:41:14  abbott
 Cleaned entry for command "if".

 Revision 1.5  2012/03/20 15:09:39  bigatti
 ++ updated manual for mat and ScalarProduct

 Revision 1.4  2012/03/16 14:44:24  bigatti
 ++ removed spurious </example>

 Revision 1.3  2012/03/16 10:01:23  bigatti
 ++ merged more updates by Elisa Fascio (finished?)
 ++ more improvements and updates

 Revision 1.2  2012/03/14 10:58:45  bigatti
 ++ merged more changes by Elisa Fascio
 ++ changed man for return, 0 values, ..

 Revision 1.1  2012/03/13 16:00:31  bigatti
 ++ used to be in /packages/man/
 ++ updated IndetSubscripts

 Revision 1.15  2012/03/12 16:01:11  bigatti
 ++ fixed version and date

 Revision 1.14  2012/03/09 17:00:29  bigatti
 ++ merged more changes by Elisa Fascio
 ++ fixed manual for  try

 Revision 1.13  2012/03/07 18:05:54  bigatti
 ++ more changes by elisa Fascio and updates

 Revision 1.12  2012/02/24 13:27:12  bigatti
 ++ merged in some updates by Elisa Fascio
 ++ added CoefficientsWRT, ContentWRT

 Revision 1.11  2011/11/02 16:28:03  bigatti
 ++ updates by Elisa Fascio

 Revision 1.10  2011/05/26 11:25:00  bigatti
 ++ minor fixes

 Revision 1.9  2011/03/23 17:27:36  bigatti
 ++ minor fixes

 Revision 1.8  2011/02/16 17:24:18  bigatti
 *** empty log message ***

 Revision 1.7  2011/02/16 17:23:22  bigatti
 ++ removed line breakes in short_description

 Revision 1.6  2011/02/15 09:41:19  bigatti
 ++ added a "*"

 Revision 1.5  2011/01/25 09:52:07  bigatti
  Updated entry for LinSol: left the old interface as public but
  "experimental". (abbott)

 Revision 1.4  2011/01/25 09:47:26  bigatti
 fixed a typo

 Revision 1.3  2011/01/19 16:03:23  bigatti
 ++ minor fix

 Revision 1.2  2010/12/16 17:48:23  bigatti
 changed  coc-quotes  into  quotes

 Revision 1.1  2010/08/31 15:11:58  bigatti
 ++ same as cocoa-4 manual

 Revision 1.51  2010/08/31 14:34:44  bigatti
 ++ added tag <keys>..<keys>  around keys list
 ++ minor fixes and key/type additions

 Revision 1.50  2010/07/12 12:28:56  bigatti
 ++ fixed some quotes
 ++ added obsolescent for help in functions

 Revision 1.49  2010/03/12 00:04:03  abbott
 Improved entries for Factor and SmoothFactor; extra keywords too.

 Revision 1.48  2009/11/26 17:35:04  bigatti
 ++ fixed some "quotes"
 ++ added "downto" key to for loop entry

 Revision 1.47  2009/10/27 16:38:41  abbott
 Added StarSprint & StarSprintFold.
 Extended StarPrint to rational functions.
 Created new version (4.7.6).

 Revision 1.46  2009/10/09 13:20:09  bigatti
 ++ added IsInRadical and MinPowerInIdeal

 Revision 1.45  2009/10/07 14:35:15  abbott
 Improved the man page for the command "Using".

 Revision 1.44  2009/10/01 15:51:05  bigatti
 ++ improved doc for Reg5

 Revision 1.43  2009/09/30 15:17:16  bigatti
 ++ added Reg5
 ++ fixed some Hilbert/Poincare names

 Revision 1.42  2009/09/24 08:23:50  bigatti
 *** empty log message ***

 Revision 1.41  2009/09/22 15:59:04  bigatti
 ++ ElsIf changed into Elif

 Revision 1.40  2009/09/03 15:36:24  abbott
 Minor update to entries for StableBBasis5 and StableBBasisNBM5.

 Revision 1.39  2009/07/01 15:14:05  bigatti
 ++ separated Max/Min
 ++ minor

 Revision 1.38  2009/06/22 15:15:08  abbott
 Minor changes to some examples.

 Revision 1.37  2009/06/09 15:23:11  abbott
 Replaced some Qs by QQs;  corrected a package name in a comment.

 Revision 1.36  2009/06/09 10:01:38  bigatti
 ++ added Reg
 ++ changed resolutions exponents

 Revision 1.35  2009/06/08 16:41:31  bigatti
 ++ fixed some quotes
 ++ fixed RegularityIndex

 Revision 1.34  2009/06/04 15:14:09  bigatti
 ++ added some functions for the school (subalgebra, apolarity)

 Revision 1.33  2009/05/26 14:44:02  bigatti
 ++ obsolescent: NewId, NewLine, Source $pkgname
 ++ new: function NewLine()

 Revision 1.32  2009/05/22 12:40:36  bigatti
 ++ changed obsolescent: GB.Step, Print(..), Repeat .. EndRepeat

 Revision 1.31  2009/05/15 16:28:42  bigatti
 ++ new tag <backslash/>

 Revision 1.30  2009/05/15 16:14:15  bigatti
 ++ updated entry for Latex

 Revision 1.29  2009/05/14 09:04:37  bigatti
 ++ Delete, Clear, Destroy obsolescent

 Revision 1.28  2009/05/06 16:03:18  bigatti
 new way to escape quotes in strings

 Revision 1.27  2009/05/05 12:14:10  bigatti
 updated for obsolescent syntax for Record

 Revision 1.26  2009/04/21 14:05:11  bigatti
 ++ added CheckArgTypes
 ++ added Frobby functions
 ++ split LinKer and LinKerModP
 ++ Q to QQ, Z to ZZ
 ++ updates for Record[..:=..] and Mat(..)
 ++ added some spaces and semicolons
 ++ added some search keys

 Revision 1.25  2009/02/05 15:41:23  bigatti
 ++ added key "factorial" for Fact
 ++ minor tidying

 Revision 1.24  2008/12/11 10:27:33  bigatti
 ++ minor changes to ImplicitPlotOn, PlotPointsOn

 Revision 1.23  2008/11/24 09:46:51  bigatti
 ++ added RelNotes

 Revision 1.22  2008/11/24 09:18:37  bigatti
 ++ ApproxBBasis5 and NBM5 renamed into StableBBasis5 and StableBBasisNBM5

 Revision 1.21  2008/11/23 17:22:06  abbott
 Changed name of NBM5 to StableBBasisNBM5; the new name is clumsy but
 more meaningful.

 Revision 1.20  2008/11/23 17:09:16  abbott
 Removed "warning" about approx output from the preprocessing algms, as the
 code now does the right thing.

 Revision 1.19  2008/11/21 21:07:27  abbott
 Changed name of ApproxBBasis5 to StableBBasis5.
 A few other minor changes.

 Revision 1.18  2008/11/20 12:43:40  bigatti
 ++ minor changes

 Revision 1.17  2008/11/19 17:37:17  bigatti
 ++ minor cleanup

 Revision 1.16  2008/11/19 16:29:42  abbott
 Updated entry for PreprocessPts5.

 Revision 1.15  2008/11/14 13:04:25  bigatti
 ++ added PlotPoints and keys for the plot functions
 ++ fixed LexSegmentIdeal (for an ideal)

 Revision 1.14  2008/11/07 15:05:20  bigatti
 ++ minor improvement for ImplicitPlot/ImplicitPlotOn

 Revision 1.13  2008/11/07 14:19:21  bigatti
 ++ added AllIndetsCalled, ImplicitPlot, ImplicitPlotOn
 ++ a few minor fixes and new keys

 Revision 1.12  2008/10/22 15:15:03  bigatti
 ++ minor changes

 Revision 1.11  2008/10/17 16:25:46  bigatti
 ++ changed all Z into ZZ and Q into QQ
 ++ added some spaces after commas

 Revision 1.10  2008/10/14 16:09:16  bigatti
 ++ using new (preferred) syntax "ZZ/(P)"

 Revision 1.9  2008/09/12 14:56:19  bigatti
 ++ added NBM5

 Revision 1.8  2008/07/17 15:10:24  bigatti
 ++ added LexSegmentIdeal(I:IDEAL)

 Revision 1.7  2008/06/30 15:34:35  bigatti
 ++ fixed manual for old help: "Help S;" into "Help(S);"

 Revision 1.6  2008/06/12 15:41:15  cocoa
  ++ removed obsolete title-keys (finished)

 Revision 1.5  2008/06/11 16:32:10  cocoa
 ++ removed obsolete title-keys (up to letter S)

-->

<!--  LocalWords:  CoCoA adjoints indeterminates equidimensional towards
 -->
