<?xml version="1.0" encoding="ascii"?>
<!-- XML document for the CoCoA online help system -->
<!-- last modified 10 May 2005 -->
<!-- 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 only have to change the version stuff here, -->
<!--i.e., just once, when revising the manual -->
  <version>
    <man_version>2.0</man_version>
    <cocoa_version>4.5</cocoa_version>
    <date>2005/10/4</date>
  </version>

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

-- This package provides online help for CoCoA <coc_version/>.  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 <code>H.Man</code> 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 <code>man</code> 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 <code>H.Commands</code> 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 <code>H.Man</code>.  
--
-- Information about the other online help functions and more details
-- concerning <code>H.Man</code> and <code>H.Commands</code> can be found through the online
-- help system itself.  To get started, set up the help package as 
-- described below,  start CoCoA, and enter <code>H.Man()</code>, with no arguments. 
-- 
-- Note: in a CoCoA session, the command <code>Man</code> is synonymous with
-- <code>H.Man</code>.  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. <code>Man</code> 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: If 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. <code>H.Toc</code> has been changed so that <code>H.Toc()</code>; displays only
-- chapter titles.  To see the full table of contents, one must now
-- type <code>H.Toc(<coc-quotes>all</coc-quotes>)</code>.
-- 5. <code>H.Chapters</code> is hidden from view, and its entry is removed from
-- the manual.
-- 6. <code>Decap</code> 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 <code>EvalHilbertFn</code>.
-- 
-- TODO: write section on finite point sets and Buchberger-Moeller
--
-- 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 <code>PotentialFlag</code> variable).
--
-- VERSION 1.0, 1.1
-- 1. updated entries
--
-- VERSION 1.2
-- 1. updated entries
-- 2. Replace GetEnv(<coc-quotes>COCOA_LIBRARY</coc-quotes>) with CocoaLibrary() (and changed
--    <code>lib</code> to <code>/lib/</code>).
--
-- VERSION 1.3
-- 1. updated entries
-- 2. <code>Man</code> is now called with ?
--
-- VERSION 1.4
-- 1. updated entries
  </changes>

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

 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>Symbol</chapter_name>


 <!-- ===  COMMAND  =============================================== -->
 <command>
    <title>..</title>
    <short_description>range operator</short_description>

    <description>
If M and N are of type INT, then the expression:  <code>M .. N</code> returns 

      * the list <code>[M, M+1, ... ,N]</code> if <formula>M <less_eq/> N;</formula>
      * the empty list, <code>[]</code>, 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/>
If x and y are indeterminates in a ring, then
 
      <code>x .. y</code>

gives the indeterminates lying 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 ::= Q[x,y,z,a,b,c,d];
z..c;
[z, a, b, c]
------------------------------- 
</example>
    </description>

    <syntax>
M .. N

where M and N are of type INT or M and N are indeterminates of the
current ring.
</syntax>

    <see>CoCoA Operators</see>

    <type>list</type>

    <key>..</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>:</title>
    <short_description>ideal or module quotient</short_description>

    <description>
See <coderef>Colon</coderef>.
    </description>

    <syntax>
M : N

where M and N are modules or ideals.
</syntax>

    <see>Colon</see>
    <see>HColon</see>
    <see>Saturation</see>
    <see>HSaturation</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>:</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title><formula>&lt;&lt;</formula></title>
    <short_description>read commands from a file or device</short_description>

    <description>
This command executes all CoCoA commands in the file or device named
S.  Same as <coderef>Source</coderef>.
    </description>

    <syntax>
&lt;&lt; S:STRING
</syntax>

    <see>Introduction to IO</see>
    <see>Introduction to Packages</see>
    <see>User Initialization</see>
    <see>Source</see>

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

    <key>&lt;&lt;</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title><formula>&gt;&lt;</formula></title>
    <short_description>Cartesian product</short_description>

    <description>
This operator (made using a greater-than sign <code>&gt;</code> and a less-than
sign <code>&lt;</code>) returns the list whose elements form the Cartesian product
        of <formula>L_1,...,L_n</formula>.  For the N-fold product of a list with itself, one may
use <coderef>Tuples</coderef>.

        
<example>
L := [1,2,3];
L &gt;&lt; [<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>] &gt;&lt; [5];
[[1, <coc-quotes>a</coc-quotes>, 5], [1, <coc-quotes>b</coc-quotes>, 5], [2, <coc-quotes>a</coc-quotes>, 5], [2, <coc-quotes>b</coc-quotes>, 5], [3, <coc-quotes>a</coc-quotes>, 5], [3, <coc-quotes>b</coc-quotes>, 5]]
-------------------------------
ChessBoard := (1..8)&gt;&lt;(1..8); -- Need brackets around 1..8 otherwise
                              -- we get a parse error. 
</example>
Note that only <code>&lt;&gt;</code> is used for <em>not equal</em> in CoCoA.
    </description>

    <syntax>
L_1 &gt;&lt; ... &gt;&lt; L_n

where each L_i is a list.
</syntax>

    <see>CoCoA Operators</see>
    <see>Tuples</see>

    <type>list</type>

    <key>&gt;&lt;</key>
    <key>cartesian product</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>?</title>
    <short_description>search online help system</short_description>

    <description>
The <code>?</code> function is used to search the online help system for
information matching a keyword.  In the forms <code>?key</code> and <code>??key</code>, the
<em>key</em> is a literal string.  This means that <em>key</em> should not appear
enclosed in quotes.  For instance, type <code>?gbasis</code> rather than
<code>?<coc-quotes>gbasis</coc-quotes></code>.  The command <code>?</code> is case insensitive and does not
notice 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 online help contains a manual and a list of commands.  Each
section of the manual and each command has an associated list of
keywords.  To explain how the search system works, we will use the
following terminology: say the key S <em>matches</em> a keyword K if S is a
substring of K, not counting capitalization.  The key S is an <em>exact
match</em> if it is identical to K, not counting capitalization.  The
command <code>?S</code> searches for keywords in the online help system matching
the S.  If only one match occurs or an exact match occurs, the
corresponding information is displayed.  Otherwise, if more than one
match occurs (and no exact match), matching keywords are listed.  It
is often advisable to make search words small at first to get as many
matches as possible.

        
<example>
?po

See:
  Commands and Functions for Polynomials
  DensePoly
  EquiIsoDec
  Evaluation of Polynomials
  Factoring Polynomials

            --&gt; Output suppressed  &lt;--

?for poly

============ Commands and Functions for Polynomials =============

The following are commands and functions for polynomials:

            --&gt; Output suppressed  &lt;-- 
</example>

Intelligent choice of the string S can save a lot of typing.  For
example, there are many sections in the manual whose titles begin:
<em>Commands and Functions for</em>; in the example above, we matched the
corresponding section for polynomials by choosing the search string
<em>for poly</em>. 

<par/>
The command <code>??S</code> displays all keywords in the online help system that
match S (an exact match is not required, and *all* keywords are listed
even if there is an exact match).

        
<example>
??gbasis

See:
  GB.Start_GBasis
  GBasis
  ReducedGBasis
------------------------------- 
</example>

Typing <code>?gbasis</code>, with a single question mark produces only the manual
entry for <code>GBasis</code>.

<par/>
The function <code>Man</code> is equivalent to <code>?</code> except it requires an actual
string, e.g., <code>Man(<coc-quotes>gbasis</coc-quotes>)</code> rather than <code>Man(gbasis)</code>.  <code>Man</code> with
the optional second argument set to the number 0 is equivalent to
<code>??</code>.  Since <code>Man</code> requires more typing than <code>?</code>, there should never
be a need to use it.  (The command <code>?</code> was introduced in CoCoA 4.2 and
is intended to replace <code>Man</code>.)

<par/>
Note: The set of keywords associated with any section of the manual
always includes the title of the manual, so it might help to first
take a look at the table of contents, using <code>H.Toc</code>.  (The titles of
Parts, which are numbered by <code>H.Toc</code> do *not* appear as keywords: only
titles of chapters and sections.)  Similarly, the set of keywords for
a command always includes the command&apos;s name.  The complete list of
documented commands can be printed by entering <code>H.Commands(<coc-quotes></coc-quotes>)</code>.
    </description>

    <syntax>
?key:NULL
??key:NULL

where <em>key</em> is a literal string.
</syntax>

    <see>H.Commands</see>
    <see>H.Syntax</see>

    <type>help</type>
    <type>online-help</type>

    <key>?, man</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>@</title>
    <short_description>untag an object</short_description>

    <description>
This function strips an object E of its tag, if any.
<code>@E</code> is equivalent to <code>Untagged(E)</code>.

<pre/>
Tags are used for pretty printing of objects.  See the reference
listed below.
        
<example>
L := [1,2,3];
M := Tagged(L, <coc-quotes>MyTag</coc-quotes>);
Type(M);
TAGGED(<coc-quotes>MyTag</coc-quotes>)
-------------------------------
Type(@M);
LIST
------------------------------- 
</example>
    </description>

    <syntax>
@E:TAGGED_OBJECT:UNTAGGED_OBJECT
</syntax>

    <see>Tagged Printing</see>
    <see>Tag</see>
    <see>Tagged</see>
    <see>Untagged</see>

    <type>io</type>
    <type>printing</type>
    <type>tags</type>

    <key>@</key>
  </command>

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

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

    <description>
This function returns the absolute value of N.

        
<example>
Abs(-3);
3
-------------------------------
Abs(-2/3);
2/3
------------------------------- 
</example>
    </description>

    <syntax>
Abs(N:INT):INT
Abs(N:RAT):RAT
</syntax>

    <type>integer</type>
    <type>rat</type>

    <key>abs</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Adjoint</title>
    <short_description>adjoint matrix</short_description>

    <description>
This function returns the adjoint matrix of M.

        
<example>
Adjoint(Mat([[x,y,z],[t,y,x],[x,x^2,xy]]));
Mat([
  [-x^3 + xy^2, -xy^2 + x^2z, xy - yz],
  [-txy + x^2, x^2y - xz, -x^2 + tz],
  [tx^2 - xy, -x^3 + xy, -ty + xy]
])
-------------------------------
Adjoint(Mat([[1%5,2%5],[3%5,1%5]]));
Mat([
  [1 % 5, -2 % 5],
  [2 % 5, 1 % 5]
])
------------------------------- 
</example>
    </description>

    <syntax>
Adjoint(M:MAT):MAT

where M is a square matrix.
</syntax>

    <type>matrix</type>

    <key>adjoint</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>AffHilbert</title>
    <short_description>the affine Hilbert function</short_description>

    <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 <coderef>EvalHilbertFn</coderef> 
instead of <code>Hilbert(R,N)</code> in order to speed up execution.
<par/>
This function is the same as <coderef>AffHilbertFn</coderef>.
<par/>
The coefficient ring must be a field.

        
<example>
  Use R ::= Q[x,y,z];
  AffHilbert(R/Ideal(z^4-1, xz^4-y-3));
H(0) = 1
H(1) = 3
H(t) = 4t - 2   for t >= 2
-------------------------------
</example>
    </description>

    <syntax>
AffHilbert(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes><code>$hp.Hilbert</code></coc-quotes>)
AffHilbert(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>),N:INT):INT
</syntax>

    <see>AffHilbertSeries</see>
    <see>EvalHilbertFn</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>affhilbert</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>AffHilbertFn</title>
    <short_description>the affine Hilbert function</short_description>

    <description>
Same as <coderef>AffHilbert</coderef>.        
    </description>

    <syntax>
AffHilbertFn(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes><code>$hp.Hilbert</code></coc-quotes>)
AffHilbertFn(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>),N:INT):INT
</syntax>

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

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertfn</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>AffHilbertSeries</title>
    <short_description>the affine Hilbert-Poincare series</short_description>

    <description>
This function computes the affine Hilbert-Poincare series of M.
The grading must be a positive <formula>Z^1</formula>-grading (i.e. <coderef>WeightsMatrix</coderef>
must have a single row with positive entries), and the ordering must
be degree compatible (i.e. for a buggy behaviour of cocoa-4,
<coderef>Ord</coderef> must have all 1's in the first row).
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/>
It is exacly the same as <coderef>AffPoincare</coderef>.

<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 "Computer Commutative Algebra II", Section 5.6.
        
<example>
  Use R ::= Q[x,y,z];
  AffPoincare(R/Ideal(z^4-1, xz^4-y-3));
(1 + x + x^2 + x^3) / (1-x)^2
-------------------------------
</example>
    </description>

    <syntax>
HilbertSeries(M:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>AffHilbert</see>
    <see>HilbertSeries</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>affhilbertseries</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>AffPoincare</title>
    <short_description>the affine Hilbert-Poincare series</short_description>

    <description>
Same as <coderef>AffHilbertSeries</coderef>.

    </description>

    <syntax>
AffPoincare(M:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>AffHilbert</see>
    <see>AffHilbertSeries</see>
    <see>Hilbert</see>
    <see>HilbertSeries</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>affpoincare</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Alias</title>
    <short_description>define aliases for package names</short_description>

    <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.  Aliases for packages that are routinely
loaded, may be added to <code>userinit.coc</code> (see <ref>User Initialization</ref>).

<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 <coderef>Aliases</coderef>.  For examples, see the chapter on packages in the
manual, in particular the section, <ref>Global Aliases</ref>.  Online, enter
<code>?global aliases</code>.

<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();

H      = $help
IO     = $io
GB     = $gb
HP     = $hp
HL     = $hilop
List   = $list

Mat    = $mat
Latex  = $latex
LaTeX  = $latex
Toric  = $toric
Coclib = $coclib
------------------------------- 
</example>
    </description>

    <syntax>
Alias B_1,..., B_r

where each B_i is a <em>binding</em> of the form: Identifier := $PackageName
</syntax>

    <see>Alias In</see>
    <see>Aliases</see>
    <see>Global Aliases</see>
    <see>Introduction to Packages</see>
    <see>Local Aliases</see>

    <type>packages</type>

    <key>alias</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Alias In</title>
    <short_description>temporarily override global aliases</short_description>

    <description>
This command allows one to use the aliases defined by the <code>B_i</code>&apos;s in
the command sequence C without affecting the global aliases.

        
<example>
Aliases(); -- the global aliases

H      = $help
IO     = $io
GB     = $gb
HP     = $hp
HL     = $hilop
List   = $list
Mat    = $mat
Latex  = $latex
LaTeX  = $latex
Toric  = $toric
Coclib = $coclib
-------------------------------
Alias HP := $help In HP.Man(<coc-quotes>Alias In</coc-quotes>) EndAlias;  
============ Alias In =============
SYNTAX
Alias B_1,...,B_r In C EndAlias

where each B_i is a <em>binding</em> of the form: Identifier := $PackageName, 
and C is a command sequence.
   ---&gt; Output suppressed &lt;---
HP.Examples();  -- the global alias HP is unaffected

    ----   STANDARD   ----
    Use R ::= Q[txyz];
    Poincare(R);
   ---&gt; Output suppressed &lt;--- 
</example>
    </description>

    <syntax>
Alias B_1,...,B_r In C EndAlias

where each B_i is a <em>binding</em> of the form: Identifier := $PackageName, 
and C is a command sequence.
</syntax>

    <see>Alias</see>
    <see>Introduction to Packages</see>

    <type>packages</type>

    <key>alias in</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Aliases</title>
    <short_description>list of global aliases</short_description>

    <description>
This function prints a list of global aliases for packages. Aliases
are formed with the function <coderef>Alias</coderef>.

        
<example>
Aliases();

H      = $help
IO     = $io
GB     = $gb
HP     = $hp
HL     = $hilop
List   = $list
Mat    = $mat
Latex  = $latex
LaTeX  = $latex
Toric  = $toric
Coclib = $coclib
-------------------------------
Alias TT := $abc;
Aliases();

H      = $help
IO     = $io
GB     = $gb
HP     = $hp
HL     = $hilop
List   = $list
Mat    = $mat
Latex  = $latex
LaTeX  = $latex
Toric  = $toric
Coclib = $coclib
TT     = $abc
------------------------------- 
</example>
    </description>

    <syntax>
Aliases():TAGGED(<coc-quotes>Aliases</coc-quotes>)
</syntax>

    <see>Alias</see>
    <see>Introduction to Packages</see>

    <type>packages</type>

    <key>aliases</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Ascii</title>
    <short_description>convert between characters and ascii code</short_description>

    <description>
In the first form, Ascii returns the character whose ascii code is N.

<par/>
In the second form, Ascii returns the string whose characters, in
order, have the ascii codes listed in L.

<par/>
The third form is the inverse of the second: it returns the ascii codes
of the characters in S.

        
<example>
Ascii(97);
a
-------------------------------
C := Ascii(<coc-quotes>hello world</coc-quotes>);
C;
[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
-------------------------------
Ascii(C);
hello world
------------------------------- 
</example>
    </description>

    <syntax>
Ascii(N:INT):STRING
Ascii(L:LIST of INT):STRING
Ascii(S:STRING):LIST of INT
</syntax>

    <type>string</type>

    <key>ascii</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Append</title>
    <short_description>append an object to an existing list</short_description>

    <description>
This function appends the object E to the list V.
        
<example>
Use R ::= Q[t,x,y,z];
L := [1,2,3];
Append(L,4);
L;
[1, 2, 3, 4]
------------------------------- 
</example>
    </description>

    <syntax>
Append(V:LIST, E:OBJECT):NULL

where V is a variable containing a list.
</syntax>

    <see>Concat</see>
    <see>ConcatLists</see>
    <see>Insert</see>
    <see>Remove</see>

    <type>list</type>

    <key>append</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>BettiDiagram</title>
    <short_description>the diagram of the graded Betti numbers</short_description>

    <description>
This function returns the (<quotes>Macaulay style</quotes>) Betti
diagram for M. 

        
<example>
  Use R ::= Q[t,x,y,z];
  I := Ideal(x^2-yt,xy-zt,xy);
  Res(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
-------------------------------
  BettiDiagram(I);
        0    1    2
--------------------
 2:     3    -    -
 3:     -    4    2
--------------------
Tot:    3    4    2
-------------------------------
  Untagged(BettiDiagram(I));
Record[Diagram = Mat([
  [3, 0, 0],
  [0, 4, 2]
]), FirstShift = 2]
</example>
    </description>

    <syntax>
BettiDiagram(M:IDEAL or MODULE):TAGGED(<coc-quotes>$gb.BettiDiagram</coc-quotes>)
</syntax>

    <see>Res</see>
    <see>GB.GetBettiMatrix</see>
    <see>BettiMatrix</see>

    <type>groebner</type>
    <type>ideal</type>
    <type>module</type>

    <key>bettidiagram</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>BettiMatrix</title>
    <short_description>the matrix of the graded Betti numbers</short_description>

    <description>
This function returns the Betti matrix for M.

        
<example>
  Use R ::= Q[t,x,y,z];
  I := Ideal(x^2-yt,xy-zt,xy);
  Res(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
-------------------------------
  BettiMatrix(I);
--------------
               
--------------
   0    0    0 
   0    0    3 
   0    0    0 
   0    4    0 
   2    0    0 
--------------

-------------------------------
  Untagged(BettiMatrix(I));
Mat([
  [0, 0, 0],
  [0, 0, 3],
  [0, 0, 0],
  [0, 4, 0],
  [2, 0, 0]
])
-------------------------------
</example>
    </description>

    <syntax>
BettiMatrix(M:IDEAL or MODULE):TAGGED(<coc-quotes>$io.Matrix</coc-quotes>)
</syntax>

    <see>Res</see>
    <see>GB.GetBettiMatrix</see>
    <see>BettiDiagram</see>

    <type>groebner</type>
    <type>ideal</type>
    <type>module</type>

    <key>bettimatrix</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Bin</title>
    <short_description>binomial coefficient</short_description>

    <description>
This function computes the binomial coefficient, <em>N choose K</em>
according to the formula
  
      (N)(N-1)(N-2)...(N-K+1)/ K!

<par/>  
The same formula is used if N is a polynomial.  The integer K cannot
be negative.

        
<example>
Bin(4,2);
6
-------------------------------
Bin(-4,3);
-20
-------------------------------
Bin(x^2+2y,3);
1/6x^6 + x^4y - 1/2x^4 + 2x^2y^2 - 2x^2y + 4/3y^3 + 1/3x^2 - 2y^2 + 2/3y
-------------------------------
It = (x^2+2y)(x^2+2y-1)(x^2+2y-2)/6;
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
Bin(N:INT or POLY, K:INT):INT
</syntax>

    <see>BinExp</see>
    <see>EvalBinExp</see>

    <type>integer</type>
    <type>polynomial</type>

    <key>bin</key>
    <key>binomial expansion</key>
    <key>macaulay expansion</key> 
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>BinExp</title>
    <short_description>binomial expansion</short_description>

    <description>
This function computes the K-binomial expansion of N, i.e., the
unique expression
<verbatim>
  N = Bin(N(K),K) + Bin(N(K-1),K-1) + ... + Bin(N(I),I)
</verbatim>
where <formula>N(K) &gt; ... &gt; N(I) &gt;= 1</formula>, for some I.  The value returned is
tagged for pretty printing.

<par/>
It can also compute the sum of the binomial coefficients
appearing in the K-binomial expansion of N after replacing each
summand Bin(N(J),J) by Bin(N(J)+Up,J+Down).  It is useful in
generalizations of Macaulay&apos;s theorem characterizing Hilbert
functions.

        
<example>
BE := BinExp(13,4);
BE;
Bin(5,4) + Bin(4,3) + Bin(3,2) + Bin(1,1)
-------------------------------
BinExp(13,4,1,1);
16
------------------------------- 
</example>
    </description>

    <syntax>
BinExp(N:INT,K:INT):TAGGED(<coc-quotes>$binrepr.BinExp</coc-quotes>)
BinExp(N:INT,K:INT,Up:INT,Down:INT):INT

where N and K are positive integers, and Up and Down are integers.
</syntax>

    <see>Bin</see>
    <see>EvalBinExp</see>

    <type>integer</type>

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

    <description>
The <code>Block</code> 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 <code>C_i</code>.  Thus, <code>Block</code> 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 <code>Block</code> clear:

        
<example>
Print <coc-quotes>hello </coc-quotes>; Print <coc-quotes>world</coc-quotes>;
hello
-------------------------------
world
-------------------------------
Block Print <coc-quotes>hello </coc-quotes>; Print <coc-quotes>world</coc-quotes> 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>

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

where each C_i is a command.
</syntax>

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

    <key>block</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>BlockMatrix</title>
    <short_description>create a block matrix</short_description>

    <description>
This function creates a block matrix.  Each entry of the input list L
has the form <code>[M_1,...,M_k]</code> where each <code>M_i</code> is either: (i) a matrix (or
list cast-able to a matrix) or (ii) the number 0, representing a zero
matrix of arbitrary size.  The entry represents a row of a block
matrix.  For instance, if A, B, C, and D are matrices, then
BlockMatrix([A,B,0],[C,0,D]] will return a matrix of the form
<verbatim>
                | A B 0 |
                | C 0 D |.
</verbatim>
The obvious restrictions on the sizes of the matrices apply.  In the
above example, we would need the number of rows in A and B to be the
same.  Similarly for C and D.  The number of columns in A and C would
need to be the same. 

        
<example>
A := [[1,2,3], [4,5,6]];
B := [[1,2], [3,4]];
C := [[1,1,1], [2,2,2], [3,3,3]];
D := [[4,4], [5,5], [6,6]];
BlockMatrix([[A,B,0], [C,0,D]]);
Mat([
  [1, 2, 3, 1, 2, 0, 0],
  [4, 5, 6, 3, 4, 0, 0],
  [1, 1, 1, 0, 0, 4, 4],
  [2, 2, 2, 0, 0, 5, 5],
  [3, 3, 3, 0, 0, 6, 6]
])
------------------------------- 
</example>
    </description>

    <syntax>
BlockMatrix(L:LIST):MAT

where L is a list representing a block matrix.
</syntax>

    <type>list</type>
    <type>matrix</type>

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

    <description>
This command must be used inside a loop statement (<code>For</code>, <code>Foreach</code>,
<code>Repeat</code>, or <code>While</code>).  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 <code>Break</code> does *not* break
out of all loops back to the <em>top level</em>
(see <code>Return</code>).

        
<example>
For I := 5 To 1 Step -1 Do
  For J := 1 To 100 Do
    Print J, <coc-quotes> </coc-quotes>;
    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>

    <syntax>
Break
</syntax>

    <see>Return</see>

    <type>loops</type>

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

    <description>
This function maps a polynomial or rational function (or a list,
matrix, or vector of these) into the current ring, preserving the
names of the indeterminates.  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).

<par/>
If the two polynomial rings differ only in characteristic then it
is faster to use the function QZP or ZPQ.

        
<example>
RR ::= Q[x[1..4],z,y];
SS ::= Z/(101)[z,y,x[1..2]];
Use RR;
F := (x[1]-y-z)^2;
F;
x[1]^2 - 2x[1]z + z^2 - 2x[1]y + 2zy + y^2
-------------------------------
Use SS;
B := BringIn(F);
B;
z^2 + 2zy + y^2 - 2zx[1] - 2yx[1] + x[1]^2
-------------------------------

Use R::=Q[x,y,z];
F := 1/2*x^3 + 34/567*x*y*z - 890;   -- a poly with rational coefficients
Use S::=Z/(101)[x,y,z];
QZP(F) = BringIn(F);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
BringIn(E:OBJECT):OBJECT

where E
 is a polynomial, a rational function, or a list/matrix/vector of
these.
</syntax>

    <see>Image</see>

    <type>list</type>
    <type>matrix</type>
    <type>polynomial</type>
    <type>ratfun</type>
    <type>vector</type>

    <key>bringin</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>C</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Call</title>
    <short_description>apply a function to given arguments</short_description>

    <description>
This function applies the function F to the arguments <code>X_1,...X_n</code>.

        
<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 Call(LessThan,X,Y) Then Return Y Else Return X EndIf
EndDefine;

Let&apos;s use MyMax by giving two different orderings. 

Define LT_Standard(X,Y)
  Return X &lt; Y;
EndDefine;
Define LT_First(X,Y)
  Return TRUE;
End;

MyMax(Function(<coc-quotes>LT_Standard</coc-quotes>),3,5);
5
-------------------------------
MyMax(Function(<coc-quotes>LT_First</coc-quotes>),5,3);
3
-------------------------------
MyMax(Function(<coc-quotes>LT_First</coc-quotes>),3,5);
5
-------------------------------
MyMax(Function(<coc-quotes>LT_First</coc-quotes>),5,3);
3
------------------------------- 
</example>
    </description>

    <syntax>
Call(F:FUNCTION,X_1,...,X_n):OBJECT

where X_1,...,X_n are the arguments for the function F.
</syntax>

    <see>Function</see>

    <type>function</type>

    <key>call</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Cast</title>
    <short_description>type conversion</short_description>

    <description>
This function returns the value of the expression E after converting
it to type T.  If S and T are types with S &lt; T, then casting from S to
T is usually possible. 

        
<example>
L := [[1,2],[3,4]];
Type(L);
LIST
-------------------------------
Cast(L,MAT);
Mat([
  [1, 2],
  [3, 4]
])
-------------------------------
L;  -- L is unchanged; it is still a list.
[[1, 2], [3, 4]]
-------------------------------
Use Z/(5)[t];
A := 8;
A;  -- A has type INT
8
-------------------------------
Cast(A,POLY);  -- cast as a polynomial, A = -2 since the coefficient
               -- ring is Z/5Z
-2
------------------------------- 
</example>
    </description>

    <syntax>
Cast(E:OBJECT,T:TYPE):TYPE
</syntax>

    <see>Data Types</see>
    <see>Shape</see>
    <see>Type</see>
    <see>Types</see>

    <type>type</type>

    <key>cast</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Catch</title>
    <short_description>catch an error</short_description>

    <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 <code>Catch</code>.

<par/>
If an error occurs during the execution of C, then it is captured by
the command <code>Catch</code> and (in the second form) assigned to the variable
E.  If no error occurs, then E will contain the value <code>Null</code>.  Note
the use of the function <coderef>GetErrMesg</coderef> in the example below.

<par/>
IMPORTANT NOTE: There is a bug in <code>Catch</code>.  Any <code>Return</code> command used
inside <code>Catch</code> must return some value.  If not, the <code>Return</code> command
will just return from the Catch-EndCatch statement; it will not return from
the function within which the statement is embedded.  There is an
example below.

        
<example>
Define Test(N)
  Catch
    PrintLn(1/N);
  In E EndCatch;
  If Type(E) = ERROR Then Print(<coc-quotes>An error occurred: </coc-quotes>, GetErrMesg(E)) EndIf;
EndDefine;
Test(3);
1/3

-------------------------------
Test(0);

An error occurred: Division by zero
-------------------------------

         --Illustration of the BUG --
Define Test2()
  Catch
    Print(<coc-quotes>Hello </coc-quotes>);
    Return;  -- incorrect: no value is returned
  EndCatch;
  PrintLn(<coc-quotes>world.</coc-quotes>);
EndDefine;
Test2();
Hello world.

-------------------------------
Define Test3()
  Catch
    Print(<coc-quotes>Hello </coc-quotes>);
    Return 3;  -- correct a value is returned
  EndCatch;
  PrintLn(<coc-quotes>world.</coc-quotes>);
EndDefine;
Test3();
Hello 3
------------------------------- 
</example>
    </description>

    <syntax>
Catch C EndCatch;
Catch C In E EndCatch;

where C is a sequence of commands and E is a variable identifier.
</syntax>

    <see>Error</see>
    <see>GetErrMesg</see>

    <type>error</type>

    <key>catch</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Characteristic</title>
    <short_description>the characteristic of a ring</short_description>

    <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 ::= Z/(3)[t];
S ::= Q[x,y];
Characteristic(); -- characteristic of the current ring, R
3
-------------------------------
Characteristic(S);
0
------------------------------- 
</example>
    </description>

    <syntax>
Characteristic():INT
Characteristic(R:RING):INT
</syntax>

    <type>ring</type>

    <key>characteristic</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Ciao</title>
    <short_description>quit CoCoA</short_description>

    <description>
This command is used to quit CoCoA.  Note, it is issued as follows:

<code>Ciao;</code>

without parentheses.
    </description>

    <syntax>
Ciao
</syntax>

    <see>Quit</see>

    <type>system</type>

    <key>ciao</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Clear</title>
    <short_description>clear the working memory or a ring-bound memory</short_description>

    <description>
The first form clears the working memory, i.e, all non-global
variables.  In the second form, the command clears the global
variables bound to the rings <code>R_1,...,R_n</code>, i.e., the <em>ring-bound</em>
memory for these rings.  For more information on memory in CoCoA, see
the chapter entitled <ref>Memory Management</ref>.

<par/>
The contents of the working memory are listed by the command
<code>Memory()</code>, and the global variables bound to the ring R are listed by
the command <code>Memory(R)</code>.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x,y);  -- I is added to the working memory
MEMORY.X := 3;  -- a global variable
ENV.R.X := Ideal(x);  -- a global variable bound to the ring R
                    -- note that <coc-quotes>ENV</coc-quotes> is equivalent to <coc-quotes>MEMORY.ENV</coc-quotes>
Use S ::= Q[a,b];
ENV.S.Y := Ideal(a^2);  -- global variable bound to S
J := Ideal(a,b);  -- J is added to the working memory
Z := 4;  -- Z is added to the working memory
Memory();  -- the contents of the working memory
[<coc-quotes>I</coc-quotes>, <coc-quotes>J</coc-quotes>, <coc-quotes>UserInitFile</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Memory(R);  -- the global variables bound to R
[<coc-quotes>X</coc-quotes>]
-------------------------------
Memory(S);  -- the global variables bound to S
[<coc-quotes>Y</coc-quotes>]
-------------------------------
Clear;  -- clear the working memory
Memory();
[ ]
-------------------------------
Clear R;  -- clear the global variables bound to R
Memory(R);
[ ]
-------------------------------
Memory(S);  
[<coc-quotes>Y</coc-quotes>]
-------------------------------
ENV.S.Y;  -- this variable was never cleared
Ideal(a^2)
------------------------------- 
</example>
    </description>

    <syntax>
Clear
Clear R_1,...,R_n

where the R_i are identifiers for rings.
</syntax>

    <see>Delete</see>
    <see>Destroy</see>
    <see>Memory</see>
    <see>Memory Management</see>

    <type>ring</type>
    <type>memory</type>

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

    <description>
This function clears the denominators of the coefficients in a
polynomial over Q.  It simply multiplies by the least common multiple of
the denominators.

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

    <syntax>
ClearDenom(F:POLY):POLY
</syntax>

    <type>poly</type>

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

    <description>
This function closes the device D.

        
<example>
D := OpenOFile(<coc-quotes>my-test</coc-quotes>); -- open file for output from CoCoA
Print <coc-quotes>test</coc-quotes> 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>

    <syntax>
Close(D:DEVICE)
</syntax>

    <see>Introduction to IO</see>

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

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

    <description>
This function <coderef>OpenLog</coderef> opens the output device D and
starts to record the output from a CoCoA session on D.  

This function closes the device D and stops recording the CoCoA session on D.
    </description>

    <syntax>
CloseLog(D:DEVICE):NULL
</syntax>

    <see>OpenLog</see>

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

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

    <description>
This function returns the path name of the directory containing the CoCoA
libraries. It is platform dependent.

        
<example>
CocoaPackagePath();  
/usr/local/lib/cocoa-<coc_version/>/packages
------------------------------- 
</example>
    </description>

    <syntax>
CocoaPackagePath():STRING
</syntax>

    <type>system</type>

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

    <description>
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>

    <syntax>
CocoaLimits():RECORD
</syntax>

    <type>system</type>

    <key>cocoalimits</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Coefficients</title>
    <short_description>list of coefficients of a polynomial or vector</short_description>

    <description>
This function returns the coefficients of F.  In the first form, a
list of the (non-zero) coefficients is returned; the order being
decreasing on the terms in F as determined by the term-ordering of the
ring to which F belongs.

<par/>
In the second form, the function views F as a polynomial in X, and
returns a list of coefficients which are polynomials in the remaining
variables; their order is decreasing in powers of X, and a zero value
is given for those powers of X absent from F.  

<par/>
In the third form, the coefficients of the specified terms are
returned; their order is determined by the list S.

        
<example>
Use R ::= Q[x,y,z];
F := 3x^2y+5y^3-xy^5;
Coefficients(F);
[-1, 3, 5]
-------------------------------
ScalarProduct(Coefficients(F),Support(F)) = F;
TRUE
-------------------------------
V:=Vector(3x^2+y,x-5z^3);
Coefficients(V);
[-5, 3, 1, 1]
-------------------------------
ScalarProduct(Coefficients(V),Support(V))=V;
TRUE
-------------------------------
Coefficients(x^3z+xy+xz+y+2z,x);
[z, 0, y + z, y + 2z]
-------------------------------
F := (1+2*x+3*y^4+5*z^6)^7;
Skeleton := [1,x^3,y^12,z^19,x^2*y^8*z^12];
Coefficients(F, Skeleton);
[1, 280, 945, 0, 567000]
------------------------------- 
</example>
    </description>

    <syntax>
Coefficients(F:POLY or VECTOR):LIST
Coefficients(F:POLY,X:INDET):LIST
Coefficients(F:POLY,S:LIST):LIST
</syntax>

    <see>Coefficient Rings</see>
    <see>LC</see>
    <see>Monomials</see>
    <see>Support</see>

    <type>polynomial</type>

    <key>coefficients</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>CoeffOfTerm</title>
    <short_description>coefficient of a term of a polynomial or vector</short_description>

    <description>
This function returns the coefficient of the term T occurring in F. 

        
<example>
Use R ::= Q[x,y,z];
F := 5xy^2-3z^3;
CoeffOfTerm(xy^2,F);
5
-------------------------------
CoeffOfTerm(x^3,F);
0
-------------------------------
CoeffOfTerm(z^3,F);
-3
-------------------------------
CoeffOfTerm(Vector(0,x^3,0),Vector(x+3,6xy-5x^3,x-z^2));
-5
------------------------------- 
</example>
    </description>

    <syntax>
CoeffOfTerm(T:POLY,F:POLY):C
CoeffOfTerm(T:VECTOR,F:VECTOR):C

where T is a term (no coefficient) and C is one of INT, RAT, or ZMOD.
</syntax>

    <see>Coefficients</see>
    <see>LC</see>
    <see>Log</see>
    <see>LogToTerm</see>
    <see>Monomials</see>
    <see>Support</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>coeffofterm</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Colon</title>
    <short_description>ideal or module quotient</short_description>

    <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 
<code>M : N</code> is a shortcut for <code>Colon(M,N)</code>.

See also  <coderef>HColon</coderef> for non-homogeneous input.

        
<example>
Use R ::= Q[x,y];
Ideal(xy,x^2) : Ideal(x);
Ideal(y, x)
-------------------------------
Colon(Ideal(x^2,xy), Ideal(x,x-y^2));
Ideal(x)
------------------------------- 
</example>
    </description>

    <syntax>
Colon(M:IDEAL,N:IDEAL):IDEAL
Colon(M:MODULE,N:MODULE):IDEAL
</syntax>

    <see>Saturation</see>
    <see>HSaturation</see>
    <see>:</see>
    <see>HColon</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>colon</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ColumnVectors</title>
    <short_description>the list of column vectors of a matrix</short_description>

    <description>
This function returns the list of column vectors of the matrix M.

        
<example>
Use R ::= Q[x,y];
M := Mat([[1,1],[x,y],[x^2,y^2]]);
M;
Mat([
  [1, 1],
  [x, y],
  [x^2, y^2]
])
-------------------------------
ColumnVectors(M);
[Vector(1, x, x^2), Vector(1, y, y^2)]
------------------------------- 
</example>
    </description>

    <syntax>
ColumnVectors(M:LIST or MAT):LIST of VECTOR

where if M is a list, is must be cast-able as a matrix.
</syntax>

    <type>matrix</type>
    <type>vector</type>

    <key>columnvectors</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Comp</title>
    <short_description>the N-th component of a list</short_description>

    <description>
This function returns <code>E[X_1,...,X_k]</code> except in the case where there
are no additional arguments <code>X_1,...,X_k</code>, in which case E, itself, is
returned (in other words <code>Comp(E)</code> returns E).  Since the square
bracket notation works only for variables and indeterminates, this
function must be used in all other situations (e.g. directly indexing
into, or selecting from, the result of a function call).

        
<example>
Use R ::= Q[x,y,z];
L := [4,5,[6,7],8];
Comp(L,1);
4
-------------------------------
Comp(L,3);
[6, 7]
-------------------------------
Comp(L,3,2);
7
-------------------------------
F(X):=[X,X^2];  -- the following usage of <coc-quotes>Comp</coc-quotes> is useful for
                -- programming 
F(2);
[2, 4]
-------------------------------
Comp(F(2),2);
4
-------------------------------
Struct := Record[L := [x,y,z], S := <coc-quotes>string</coc-quotes>];
Struct[<coc-quotes>L</coc-quotes>,3];       -- <coc-quotes>Comp</coc-quotes> works for records also
z
-------------------------------
Comp(Struct,<coc-quotes>L</coc-quotes>,3);
z
-------------------------------
Comp(<coc-quotes>this is a string</coc-quotes>,3);  -- use of <coc-quotes>Comp</coc-quotes> with strings
i
------------------------------- 
</example>
    </description>

    <syntax>
Comp(E:LIST, RECORD, STRING, or VECTOR,X_1:INT,...,X_k:INT):OBJECT
</syntax>

    <type>list</type>
    <type>record</type>
    <type>string</type>
    <type>vector</type>

    <key>comp</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Comps</title>
    <short_description>list of components of a vector</short_description>

    <description>
This function returns the list of components of V.  It is the same as
Cast(V,LIST).

        
<example>
Use R ::= Q[x,y];
Comps(Vector(x,x+y,x+y^2));
[x, x + y, y^2 + x]
------------------------------- 
</example>
    </description>

    <syntax>
Comps(V:VECTOR):LIST
</syntax>

    <see>Comp</see>
    <see>NumComps</see>

    <type>vector</type>

    <key>comps</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Concat</title>
    <short_description>concatenate lists</short_description>

    <description>
This function returns the list obtained by concatenating lists
<code>L_1,...,L_n</code>.

        
<example>
Concat([1,2,3],[4,5],[],[6]);
[1, 2, 3, 4, 5, 6] 
</example>
    </description>

    <syntax>
Concat(L_1:LIST,...,L_n:LIST):LIST
</syntax>

    <see>Concatenation</see>
    <see>ConcatLists</see>

    <type>list</type>

    <key>concat</key>
    <key>concatlists</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ConcatLists</title>
    <short_description>concatenate a list of lists</short_description>

    <description>
This function takes a list whose components are lists and
returns the concatenation of these components.

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

    <syntax>
ConcatLists([L_1:LIST,...,L_n:LIST]):LIST
</syntax>

    <see>Concatenation</see>
    <see>Concat</see>

    <type>list</type>

    <key>concat</key>
    <key>concatlists</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Cond</title>
    <short_description>conditional expression</short_description>

    <description>
If <formula>B_n</formula> is the first in the sequence of <formula>B_i</formula>&apos;s to evaluate to TRUE,
then <formula>E_n</formula> is returned.  If none of the <formula>B_i</formula>&apos;s evaluates to TRUE, then
Null is returned.  The construct, <code>Elsif B Then E</code> can be repeated any
number of times.  Note: be careful not to type <code>Elseif</code> by mistake (it
has an extraneous <code>e</code>).

<par/>
The difference between <code>Cond</code> and <code>If</code> is that <code>Cond</code> is an expression
which may be assigned to a variable; each of the <formula>E_i</formula>&apos;s is an
expression, not a general sequence of commands (as their analogues in
<code>If</code> might be).

        
<example>
Define Sign(A) 
 Return Cond A&gt;0 Then 1 Elsif A=0 Then 0 Else -1 EndCond;
EndDefine;
Sign(3);
1
-------------------------------
Define PrintSign(A) 
  Return Cond(A&gt;0,<coc-quotes>positive</coc-quotes>,A=0,<coc-quotes>zero</coc-quotes>,<coc-quotes>negative</coc-quotes>);
End;
PrintSign(3);
positive
------------------------------- 
</example>
    </description>

    <syntax>
Cond B_1 Then E_1 EndCond
Cond B_1 Then E_1 Elsif B_2 Then E_2 Elsif ... EndCond
Cond B_1 Then E_1 Elsif B_2 Then E_2 Elsif ... Else E_r EndCond
Cond(B_1,E_1,B_2,E_2,...,E_r)

where the B_i&apos;s are boolean expressions and the <formula>E_i</formula>&apos;s are expressions.
</syntax>

    <see>If</see>

    <type>programming</type>
    <type>branching</type>

    <key>cond</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>CFApprox</title>
    <short_description>continued fractions</short_description>

    <description>
CFApprox       finds the <em>simplest</em> rational approximation within a
               maximum specified relative error.

        
<example>
CFApprox(1.414213, 10^(-2));
17/12
------------------------------- 
</example>
    </description>

    <syntax>
CFApprox(X:RAT, Prec:RAT): RAT
</syntax>

    <see>CFApproximants</see>
    <see>ContFrac</see>

    <type>rat</type>

    <key>cfapprox</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>CFApproximants</title>
    <short_description>continued fractions</short_description>

    <description>
CFApproximants returns a list of all continued fraction approximants
               to a specified rational

        
<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>

    <syntax>
CFApproximants(X:RAT): LIST of INT and RAT
</syntax>

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

    <type>rat</type>

    <key>cfapproximants</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ContFrac</title>
    <short_description>continued fractions</short_description>

    <description>
ContFrac       returns a list of the continued fraction <em>denominators</em>
               for a given rational number.

        
<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>

    <syntax>
ContFrac(X:RAT):LIST of INT
</syntax>

    <see>CFApprox</see>
    <see>CFApproximants</see>

    <type>rat</type>

    <key>contfrac</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Contrib</title>
    <short_description>list of contributors to CoCoA</short_description>

    <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
<code>http://cocoa.dima.unige.it</code> or one of its mirrors.
    </description>

    <syntax>
Contrib():NULL
</syntax>

    <type>misc</type>
    <type>system</type>

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

    <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,<coc-quotes>a</coc-quotes>);
0
------------------------------- 
</example>
    </description>

    <syntax>
Count(L:LIST,E:OBJECT):INT
</syntax>

    <see>Distrib</see>
    <see>Len</see>

    <type>list</type>

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

    <description>
This function returns the current ring.  The related command,
<coderef>RingEnv</coderef> returns the name of the current ring.

        
<example>
Use R ::= Q[x,y];
Use S ::= Z/(3)[t];
CurrentRing();
Z/(3)[t]
-------------------------------
Use R;
CurrentRing();
Q[x,y]
------------------------------- 
</example>
    </description>

    <syntax>
CurrentRing()
</syntax>

    <see>Ring</see>
    <see>RingEnv</see>
    <see>RingEnvs</see>

    <type>ring</type>

    <key>currentring</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Dashes</title>
    <short_description>returns string of dashes</short_description>

    <description>
This function returns a string of dashes:

        
<example>
Dashes(); 1+1;
Dashes(); 1+1;
-------------------------------
-------------------------------
2
------------------------------- 
</example>
    </description>

    <syntax>
Dashes()
</syntax>

    <see>Equals</see>

    <type>miscellaneous</type>

    <key>dashes</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Date</title>
    <short_description>the date</short_description>

    <description>
This function returns the date.

        
<example>
Date();
Fri Jan 30 20:47:18 1998
------------------------------- 
</example>
    </description>

    <syntax>
Date()
</syntax>

    <type>miscellaneous</type>

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

    <description>
This function computes a decimal approximation with NumDigits
decimal digits of a rational number (default value is 3) and converts
it into a string for printing.  If the returned string presents less
than NumDigits decimal digits, then the string represents the exact
value of the input.

        
<example>
DecimalStr(1/3);
0.333
-------------------------------
DecimalStr(1/3, 60);
0.333333333333333333333333333333333333333333333333333333333333
-------------------------------
DecimalStr(121/10);
12.1
------------------------------- 
</example>
    </description>

    <syntax>
DecimalStr(X:RAT):STRING
DecimalStr(X:RAT, NumDigits:INT):STRING
</syntax>

    <see>FloatStr</see>
    <see>MantissaAndExponent</see>

    <type>rat</type>
    <type>string</type>

    <key>decimalstr</key>
    <key>decimal</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Define</title>
    <short_description>define a function</short_description>

    <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 <code>E_i</code>&apos;s are expressions.  The result of the evaluation of each
expression <code>E_i</code> is assigned to the respective formal parameter <code>X_i</code>, and
the command sequence C is executed.  If, during the execution of C, a
statement <code>Return E</code> is executed, then the result of the evaluation of
E is the return-value of the function F. If no <code>Return</code> command is
executed, or <code>Return</code> is executed without argument, then the
return-value is <code>Null</code>.

        
<example>
Define Square(X)
  Return X^2;
EndDefine;

Square(5);
25
------------------------------- 
</example>
 
2. SCOPE.  Every variable defined or modified by the command sequence
C is considered local to the function unless the variable is global or
relative to a <code>Var</code> parameter.  For the use of global variables, see
<ref>Global Memory</ref> or the example below.  See <code>Var</code> 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
-------------------------------
Define Example_2(L)  -- Example using a global variable.
  MEMORY.X := L + 3;
EndDefine;
Example_2(10);
MEMORY.X;
13
------------------------------- 
</example>

3. VARIABLE NUMBER OF PARAMETERS.  It is also possible to have a
variable number of parameters using the syntax
<verbatim>
    Define F(...) Help S:STRING; C EndDefine;
</verbatim>
In this case the special variable ARGV will contain the list of
the arguments passed to the function.  (The statement, <code>Help S;</code> is
optional.) 

        
<example>
Define Sum(...)
  If Len(ARGV) = 0 Then Return Null;  -- empty sum
  Else
    Sum := 0;
    Foreach N In ARGV Do Sum := Sum+N EndForeach;
  EndIf;
  Return Sum; 
EndDefine;
Sum(1,2,3,4,5);
15
-------------------------------
Sum();
Null
------------------------------- 
</example>

4. SHORTCUT.  The form <code>F(X_1,...,X_n) := E</code> is discouraged and may be
discontinued in later versions of CoCoA. If is shorthand for 
<code>Define F(X_1,...X_n) Return E EndDefine;</code>

        
<example>
F(X) := X^2;
F(5);
25
------------------------------- 
</example>

5. HELP.  Inside a user-defined function, one may add the command:
<verbatim>
  Help S;
</verbatim>
where S is a string.  Then, when a user enters <code>Help(<coc-quotes>F</coc-quotes>)</code> where F is
the identifier for the function, the string, S, is printed.

        
<example>
Define Test(N)
  Help <coc-quotes>Usage: Test(N:INT):INT</coc-quotes>;
  Return N;
EndDefine;
Help <coc-quotes>Test</coc-quotes>;
Usage: Test(N:INT):INT
------------------------------- 
</example>

6. DEFINING RINGS INSIDE FUNCTIONS.  For information on this topic,
please see the section of the tutorial entitled, <ref>Rings Inside
User-Defined Functions</ref>
    </description>

    <syntax>
Define F(X_1,...,X_n) Help S:STRING; C EndDefine
F(X_1,...,X_n) := E
Define F(...) Help S:STRING; C EndDefine

where F is an identifier, C is a sequence of commands, the X_i&apos;s are
formal parameters and E is an expression.  The third form, which
literally includes the string <code>...</code> is used for a variable number of
parameters.  The optional <code>Help S</code>, where S is a string, may be added
to provide help for the user.
</syntax>

    <see>An Overview of CoCoA Programming</see>
    <see>Introduction to User-Defined Functions</see>
    <see>Memory Management</see>
    <see>Return</see>
    <see>Rings Inside User-Defined Functions</see>
    <see>Var</see>

    <type>function</type>
    <type>programming</type>

    <key>define</key>
    <key>argv</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Deg</title>
    <short_description>the degree of a polynomial or vector</short_description>

    <description>
The first form of this function returns the (weighted) degree of F.
The second form returns the (un-weighted) degree of the indeterminate
X in F.  In either case, if F is a vector, the maximum of the degrees
of its components is returned.  (For the degree of a ring or quotient
object, see <coderef>Multiplicity</coderef>.)

        
<example>
Use R ::= Q[x,y];
Deg(xy^2+y);
3
-------------------------------
Deg(xy^2+y,x);
1
-------------------------------
Use R ::= Q[x,y], Weights(2,3);
Deg(xy^2+y);
8
-------------------------------
Deg(xy^2+y,x);
1
-------------------------------
Deg(Vector(x^2,xy^3+y,x^2-y^5));
5
-------------------------------
Deg(Vector(x^2,xy^3+y,x^2-y^5),x);
2
------------------------------ 
</example>
    </description>

    <syntax>
Deg(F:POLY or VECTOR):INT
Deg(F:POLY or VECTOR,X:INDET):INT
</syntax>

    <see>MDeg</see>
    <see>Weights Modifier</see>

    <type>polynomial</type>
    <type>ring</type>
    <type>vector</type>

    <key>deg</key>
    <key>degree</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>DegLexMat</title>
    <short_description>matrices for std. term-orderings</short_description>

    <description>
This function return the matrix defining a standard term-ordering.

        
<example>
DegLexMat(3);
Mat([
  [1, 1, 1],
  [1, 0, 0],
  [0, 1, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
DegLexMat(N:INTEGER):MAT
</syntax>

    <see>Ord</see>
    <see>Orderings</see>
    <see>DegRevLexMat</see>
    <see>LexMat</see>
    <see>RevLexMat</see>
    <see>XelMat</see>

    <type>matrix</type>

    <key>deglexmat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>DegRevLexMat</title>
    <short_description>matrices for std. term-orderings</short_description>

    <description>
This function return the matrix defining a standard term-ordering.

        
<example>
DegRevLexMat(3);
Mat([
  [1, 1, 1],
  [0, 0, -1],
  [0, -1, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
DegRevLexMat(N:INTEGER):MAT
</syntax>

    <see>Ord</see>
    <see>Orderings</see>
    <see>DegLexMat</see>
    <see>LexMat</see>
    <see>RevLexMat</see>
    <see>XelMat</see>

    <type>matrix</type>

    <key>degrevlexmat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Delete</title>
    <short_description>delete variables from the working memory</short_description>

    <description>
This function removes variables from the working memory.  It will not
delete global variables.  For more information about memory in CoCoA,
see the chapter entitled <ref>Memory Management</ref>.  The command
<code>Memory()</code> lists the contents of the working memory.

        
<example>
Use R ::= Q[x,y,z];
X := Ideal(x,y);
Y := 3;
Use S ::= Q[a,b];
Z := a^2+b^2;
Memory();  -- the contents of the working memory
[<coc-quotes>X</coc-quotes>, <coc-quotes>Y</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Delete X;
Memory();  -- X has been deleted from the working memory
[<coc-quotes>It</coc-quotes>, <coc-quotes>Y</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Delete V_1, ..., V_n

where each V_i is the identifier of a variable in the working
memory.
</syntax>

    <see>Clear</see>
    <see>Destroy</see>
    <see>Memory</see>
    <see>Memory Management</see>

    <type>ring</type>
    <type>memory</type>

    <key>delete</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Den</title>
    <short_description>denominator</short_description>

    <description>
These functions return the numerator and denominator of N.  The
numerator and denominator can also be found using <code>.Num</code>
and <code>.Den</code> (fragile).

        
<example>
Den(3);
1
-------------------------------
Den(x/(x+y));
x + y
-------------------------------
X := 2/3;
X.Num; X.Den;
2
-------------------------------
3
------------------------------- 
</example>
    </description>

    <syntax>
Den(N:INT or RAT):INT
Den(N:POLY or RATFUN):POLY
</syntax>

    <see>Numerators and Denominators for Rational Functions</see>
    <see>Numerators and Denominators for Rational Numbers</see>
    <see>Num</see>

    <type>integer</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>

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

    <description>
This function returns the sum of all power-products of degree N.

        
<example>
Use R ::= Q[x,y];
DensePoly(3);
x^3 + x^2y + xy^2 + y^3
-------------------------------
Use R::=Q[x,y],Weights(2,3); --  &lt;--- NOTE
DensePoly(1);
0
-------------------------------
DensePoly(6);
x^3 + y^2
------------------------------- 
</example>
    </description>

    <syntax>
DensePoly(N:INT):POLY
</syntax>

    <see>Randomize</see>
    <see>Randomized</see>

    <type>polynomial</type>

    <key>densepoly</key>
  </command>
<!--  ===  COMMAND  =============================================== --> 
<command>
  <title>Depth</title> 
  <short_description>Depth of a module</short_description> 
<description>
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. <code>Ideal(Indets())</code>. 
<par /> 
Note that if M is homogeneous and I is the maximal ideal, then it uses
the Auslander-Buchsbaum formula <verbatim>depth_I(M) = N - pd(M)</verbatim> 
where N is the number of indeterminates and pd is the projective
dimension, otherwise it returns <code>min{N | Ext^N(R/I,M)&lt;>0}</code> 
using the function <coderef>Ext</coderef>. 
<example>
  Use R::=Q[x,y,z];
  Depth(Ideal(1)); --  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);
  Depth(R/I);
0
-------------------------------
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::=Q[x,y,z,t,u,v];
  N:=Module([x,y],[-y,x],[z,t],[-t,z],[u,v],[-v,u]);
  -- Cauchy-Riemann system in three complex vars!
  --- is it CM?
  Depth(R^2/N);
  Dim(R^2/N);
3
-------------------------------
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>
  <syntax>
Depth(I: IDEAL, M: Tagged("Quotient")): INT
Depth(M: Tagged("Quotient"): INT
</syntax> 

  <see>Res</see> 
  <see>Ext</see> 
  <type>ideal</type> 
  <type>module</type> 
  <key>depth</key> 

</command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Der</title>
    <short_description>the derivative of a rational function</short_description>

    <description>
This function returns the derivative of F with respect to the
indeterminate X.

        
<example>
Use R ::= Q[x,y];
Der(xy^2,x);
y^2
-------------------------------
Define Jac(F)  --&gt; The Jacobian matrix for a polynomial.
  Return Mat([[Der(F,X) | X In Indets()]]);
EndDefine;
Jac(xy^2);
Mat([
  [y^2, 2xy]
])
-------------------------------
Der(x/(x+y),x);
y/(x^2 + 2xy + y^2)
------------------------------- 
</example>
    </description>

    <syntax>
Der(F,X:INDET):POLY

where F is a polynomial or a rational function.
</syntax>

    <see>Jacobian</see>

    <type>ratfun</type>
    <type>polynomial</type>

    <key>der</key>
    <key>derivative</key>
    <key>differentiate</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Describe</title>
    <short_description>information about an expression</short_description>

    <description>
This command gives information about the expression E.

        
<example>
Use R ::= Z/(32003)[t,x,y];
I := Ideal(t^3-x,t^4-y);
G := SyzOfGens(I);
Print I;
Ideal(t^3 - x, t^4 - y)
-------------------------------
Describe I;
Record[Type = IDEAL, Value = Record[Gens = [t^3 - x, t^4 - y],
SyzOfGens = Module([-t^4 + y, t^3 - x], [t^4x - xy, -t^3x + x^2])]]
-------------------------------
Describe Function(<coc-quotes>$mat.Transposed</coc-quotes>);
Define Transposed(M)
  If NOT(Type(M) = MAT) Then 
    Error(<coc-quotes>Transposed: argument must be a matrix</coc-quotes>); 
  EndIf; 
  Return(Mat([
    J,
    1..Len(M[1]),
    TRUE,
    [M[I][J]|I In 1..Len(M)]
  ])); 
EndDefine;
------------------------------- 
</example>
    </description>

    <syntax>
Describe(E:OBJECT)
Describe E:OBJECT
</syntax>

    <see>Other Help</see>

    <type>help</type>
    <type>miscellaneous</type>

    <key>describe</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Destroy</title>
    <short_description>delete rings</short_description>

    <description>
This command clears all global variables bound to the listed rings.
Moreover, if R is a ring in the list and there are no variables in the
current memory dependent upon R, then the ring identified by R is
deleted; otherwise R is renamed with a name of the form <code>R#N</code> where N
is an integer.  This renamed ring is automatically removed as soon as
the last variable dependent upon it is deleted.

<par/>
The command will not work if one of the listed rings is the current
ring.

<par/>
For more information about memory in CoCoA, see the chapter entitled
<ref>Memory Management</ref>.

        
<example>
Use R ::= Q[x,y,z];
X := 3;
I := Ideal(x,y);  -- dependent on R
ENV.R.Y := 5;  -- in global memory bound to R
Use S ::= Q[a,b];
Destroy R;
RingEnvs();  -- R#1 created to hold because of the ideal I
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R#1</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Memory();  -- ENV.R.Y was destroyed along with R
[<coc-quotes>I</coc-quotes>, <coc-quotes>It</coc-quotes>, <coc-quotes>X</coc-quotes>]
-------------------------------
I;  -- I was not destroyed
R#1 :: Ideal(x, y)
-------------------------------
I := 3;  -- overwrite I; it is no longer dependent on a CoCoA ring
Describe Memory();
------------[Memory]-----------
I = 3
It = R#1 :: Ideal(x, y)
X = 3
-------------------------------
RingEnvs();  -- subtle point here: the variable <coc-quotes>It</coc-quotes> is still dependent
             -- on R#1
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R#1</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
RingEnvs();  -- However, the previous command caused It to become a
             -- string; hence, R#1 disappears.
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Destroy R_1, ... , R_n

where each R_i is the identifier of a ring.
</syntax>

    <see>Clear</see>
    <see>Delete</see>
    <see>Memory Management</see>

    <type>ring</type>
    <type>memory</type>

    <key>destroy</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Det</title>
    <short_description>the determinant of a matrix</short_description>

    <description>
This function returns the determinant of the matrix M.  The resulting
type depends on the types of the entries of the matrix.

        
<example>
Use R ::= Q[x];
M := Mat([[x,x^2],[x,x^3]]);
Det(M);
x^4 - x^3
-------------------------------
Det(Mat([[1,2],[0,5]]));
5
------------------------------- 
</example>
    </description>

    <syntax>
Det(M:MAT)

the resulting type depends on the entries of the matrix.
</syntax>

    <see>Minors</see>

    <type>matrix</type>

    <key>det</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Diff</title>
    <short_description>returns the difference between two lists</short_description>

    <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>

    <syntax>
Diff(L:LIST,M:LIST):LIST
</syntax>

    <see>Insert</see>
    <see>Remove</see>

    <type>list</type>

    <key>diff</key>
    <key>difference</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Dim</title>
    <short_description>the dimension of a ring or quotient object</short_description>

    <description>
This function computes the dimension of R.  The weights of the
indeterminates of the current ring must all be 1.

<par/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[x,y,z];
Dim(R/Ideal(0));
3
-------------------------------
Dim(R/Ideal(y^2-x,xz-y^3));
1
------------------------------- 
</example>
    </description>

    <syntax>
Dim(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):INT
</syntax>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>dim</key>
    <key>dimension</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Discriminant</title>
    <short_description>the discriminant of a polynomial</short_description>

    <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 to be the resultant of F and its derivative
with respect to X.


        
<example>
Use R ::= Q[x,y];
Discriminant(x^2+3y^2, x);
12y^2
-------------------------------
Discriminant(x^2+3y^2, y);
36x^2
-------------------------------
Discriminant((x+1)^20+2);
54975581388800000000000000000000
------------------------------- 
</example>
    </description>

    <syntax>
Discriminant(F:POLY):POLY
Discriminant(F:POLY, X:INDET):POLY
</syntax>

    <see>Resultant</see>

    <type>polynomial</type>

    <key>discriminant</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Distrib</title>
    <short_description>the distribution of objects in a list</short_description>

    <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([<coc-quotes>b</coc-quotes>,<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>,4,4,[1,2]]);
[[<coc-quotes>b</coc-quotes>, 2], [<coc-quotes>a</coc-quotes>, 1], [4, 2], [[1, 2], 1]]
------------------------------- 
</example>
    </description>

    <syntax>
Distrib(L:LIST):LIST
</syntax>

    <see>Count</see>

    <type>list</type>

    <key>distrib</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Div</title>
    <short_description>quotient for integers</short_description>

    <description>
If N = Q*D + R, and <formula>0 <less_eq/> R &lt; |D|</formula>, then <code>Div(N,D)</code> returns Q and
<code>Mod(N,D)</code> returns R.

<par/>
NOTE: To perform the division algorithm on a polynomial or vector, use
<coderef>NR</coderef> (normal remainder) to find the remainder, or <coderef>DivAlg</coderef> to get both
the quotients and the remainder.  To determine if a polynomial is in a
given ideal or a vector is in a given module, use <coderef>NF</coderef> or <coderef>IsIn</coderef>, and
to find a representation in terms of the generators use <coderef>GenRepr</coderef>.

        
<example>
Div(10,3);
3
-------------------------------
Mod(10,3);
1
------------------------------- 
</example>
    </description>

    <syntax>
Div(N:INT,D:INT):INT
</syntax>

    <see>DivAlg</see>
    <see>GenRepr</see>
    <see>NF</see>
    <see>NR</see>
    <see>Mod</see>

    <type>integer</type>

    <key>div</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>DivAlg</title>
    <short_description>division algorithm</short_description>

    <description>
This function performs the division algorithm on X with respect to L.
It returns a record with two fields: <code>Quotients</code> holding a list of
polynomials, and <code>Remainder</code> holding the remainder of X upon division
by L.

        
<example>
Use R::= Q[x,y,z];
F := x^2y+xy^2+y^2;
L := [xy-1,y^2-1];
DivAlg(F,[xy-1,y^2-1]);
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
-------------------------------
V := Vector(x^2+y^2+z^2,xyz);
L := [Vector(x,y),Vector(y,z),Vector(z,x)];
DivAlg(V,L);
Record[Quotients = [0, -z^2, yz], Remainder = Vector(x^2 + y^2 + z^2, z^3)]
------------------------------- 
</example>
    </description>

    <syntax>
DivAlg(X:POLY,L:LIST of POLY):RECORD
DivAlg(X:VECTOR,L:LIST of VECTOR):RECORD
</syntax>

    <see>Div</see>
    <see>Mod</see>
    <see>GenRepr</see>
    <see>NF</see>
    <see>NR</see>

    <type>polynomial</type>
    <type>record</type>
    <type>vector</type>

    <key>divalg</key>
    <key>division algorithm</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>E</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>E<_/></title>
    <short_description>canonical vector</short_description>

    <description>
If N is an integer, this function returns the K-th canonical vector
of the free module of rank N over the current ring.  If N is a module,
it returns the K-th canonical vector of N.

        
<example>
Use R ::= Q[x,y];
E_(4,7);
Vector(0, 0, 0, 1, 0, 0, 0)
-------------------------------
M := Module([x^2,0,y^2],[x^3,x+y,y^3]);
E_(2,M);
Vector(0, 1, 0)
------------------------------- 
</example>
    </description>

    <syntax>
E_(K:INT,N:INT or MODULE):VECTOR
</syntax>

    <type>vector</type>
    <type>module</type>

    <key>e</key>
    <key>e_</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Elim</title>
    <short_description>eliminate variables</short_description>

    <description>
This function returns the ideal or module obtained by eliminating the
indeterminates X from M.  The coefficient ring needs to be a field.

<par/>
As opposed to this function, there is also the *modifier*, <code>Elim</code>,
used when constructing a ring (see <coderef>Orderings</coderef> and 
<ref>Predefined Term-Orderings</ref>).

        
<example>
Use R ::= Q[t,x,y,z];
Set Indentation;
Elim(t,Ideal(t^15+t^6+t-x,t^5-y,t^3-z));
Ideal(
  -z^5 + y^3,
  -y^4 - yz^2 + xy - z^2,
  -xy^3z - y^2z^3 - xz^3 + x^2z - y^2 - y,
  -y^2z^4 - x^2y^3 - xy^2z^2 - yz^4 - x^2z^2 + x^3 - y^2z - 2yz - z,
  -y^3z^3 + xz^3 - y^3 - y^2)
-------------------------------
Use R ::= Q[t,s,x,y,z,w];
t..x;
[t, s, x]
-------------------------------
Elim(t..x,Ideal(t-x^2zw,x^2-t,y^2t-w)); -- Note the use of t..x.
Ideal(-zw^2 + w)
-------------------------------
Use R ::= Q[t[1..2],x[1..4]];
I := Ideal(x[1]-t[1]^4,x[2]-t[1]^2t[2],x[3]-t[1]t[2]^3,x[4]-t[2]^4);
t;
[t[1], t[2]]
-------------------------------
Elim(t,I);                         -- Note the use t.
Ideal(x[3]^4 - x[1]x[4]^3, x[2]^4 - x[1]^2x[4])
------------------------------- 
</example>
    </description>

    <syntax>
Elim(X:INDETS,M:IDEAL):IDEAL
Elim(X:INDETS,M:MODULE):MODULE

where X is an indeterminate or a list of indeterminates.
</syntax>

    <see>Orderings</see>
    <see>Predefined Term-Orderings</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>

    <key>elim</key>
    <key>elimination</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>EqSet</title>
    <short_description>checks if the set of elements in two lists are equal</short_description>

    <description>
This function returns TRUE if Set(L) equals Set(M), otherwise it
returns FALSE.

        
<example>
L := [1,2,2];
M := [2,1];
EqSet(L,M);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
EqSet(L:LIST,M:LIST):BOOL
</syntax>

    <see>Intersection</see>
    <see>IntersectionList</see>
    <see>IsSubset</see>

    <type>boolean</type>
    <type>list</type>

    <key>eqset</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Equals</title>
    <short_description>returns a string of equal signs</short_description>

    <description>
This function returns a string of equal signs:

        
<example>
Equals();
===============================
------------------------------- 
</example>
    </description>

    <syntax>
Equals()
</syntax>

    <see>Dashes</see>

    <type>miscellaneous</type>

    <key>equals</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>EquiIsoDec</title>
    <short_description>equidimensional isoradical decomposition</short_description>

    <description>
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::=Q[x,y,z];
I := Intersection(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>

    <syntax>
EquiIsoDec(I:IDEAL):LIST of IDEAL
</syntax>

    <see>PrimaryDecomposition</see>
    <see>Radical</see>
    <see>RadicalOfUnmixed</see>

    <type>groebner</type>
    <type>ideal</type>

    <key>equidimensional</key>
    <key>equiisodec</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Error</title>
    <short_description>return an error message</short_description>

    <description>
This function returns an error labeled with the string S.

        
<example>
Define T(N)
  If Type(N) &lt;&gt; INT Then Error(<coc-quotes>Argument must be an integer.</coc-quotes>) EndIf;
  Return Mod(N,5);
EndDefine;
T(1/3);

-------------------------------
ERROR: Argument must be an integer.
CONTEXT: Error(<coc-quotes>Argument must be an integer.</coc-quotes>)
-------------------------------
T(7);
2
------------------------------- 
</example>
    </description>

    <syntax>
Error(S:STRING):ERROR
</syntax>

    <see>Catch</see>
    <see>GetErrMesg</see>

    <type>error</type>

    <key>error</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Eval</title>
    <short_description>substitute numbers or polynomials for indeterminates</short_description>

    <description>
This function substitutes the N-th element of L for the N-th
indeterminate of the current ring for all N less than or equal to the
minimum of the number of indeterminates of the current ring and the
number of components of L.

        
<example>
Use Q[xy];
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]);
[2y, 0]
------------------------------- 
</example>
    </description>

    <syntax>
Eval(E:OBJECT,L:LIST):OBJECT
</syntax>

    <see>Evaluation of Polynomials</see>
    <see>Image</see>
    <see>Subst</see>
    <see>Substitutions</see>

    <type>polynomial</type>

    <key>eval</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>EvalBinExp</title>
    <short_description>binomial expansion functions</short_description>

    <description>
The function <coderef>BinExp</coderef> computes the K-binomial
expansion of N, i.e., the unique expression
<verbatim>
  N = Bin(N(K),K) + Bin(N(K-1),K-1) + ... + Bin(N(I),I)
</verbatim>
where <formula>N(K) &gt; ... &gt; N(I) &gt;= 1</formula>, for some I.

<par/>
This function computes the sum of the binomial coefficients
appearing in the K-binomial expansion of N after replacing each
summand Bin(N(J),J) by Bin(N(J)+Up,J+Down).  It is useful in
generalizations of Macaulay&apos;s theorem characterizing Hilbert
functions.

<par/>
It is the same as <coderef>BinExp</coderef> with 4 arguments except it
takes a precomputed binomial expansion as an argument rather than N and K.

        
<example>
BE := BinExp(13,4);
BE;
Bin(5,4) + Bin(4,3) + Bin(3,2) + Bin(1,1)
-------------------------------
EvalBinExp(BE,1,1);
16
-------------------------------
BinExp(13,4,1,1);
16
------------------------------- 
</example>
    </description>

    <syntax>
EvalBinExp(B:TAGGED(<coc-quotes>$binrepr.BinExp</coc-quotes>),Up:INT,Down:INT):INT

where N and K are positive integers, and Up and Down are integers.
</syntax>

    <see>Bin</see>
    <see>BinExp</see>

    <type>integer</type>

    <key>evalbinexp</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
 <title>Ext</title> 
  <short_description>presentation Ext modules as quotients of free modules</short_description> 
 <description>
  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 Tagged("Shifted") has been
  removed. Ext will just be a Tagged("Quotient")
  <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 <code>Ext</code> 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 <code>Tagged("$ext.ExtList")</code> 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 />

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.
  <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 />
<code>Ext(I, M, Ideal(1));</code>
  <par />
or
  <par />
<code>Ext(I, M, R^1);</code>
  <par />
or
  <par />
<code>Ext(I, M, R/Ideal(0));</code>
  

<example>
  Use R ::= Q[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^8/Module([0, 0, 0, -1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [1, x - z, 0, 0, 0, 0, 0, 0], [0, 0, y, x - z, 1, 0, 0, 0], [0, 0, y, x - z, 0, 0, 0, 0], [0, x^3, 0, 0, 0, x + z, 0, 0], [y^2, 0, -z^2, 0, 0, 0, 0, 0], [0, x^4 - x^3z, 0, 0, 0, -z^2, -1, 0], [-y^3z, x^2y^3 - xy^3z + y^3z^2, 0, -x^4 + x^3z - x^2z^2, 0, y^3, 0, 0], [0, x^4 - x^3z, 0, 0, 0, -z^2, 0, 0], [0, 0, 0, 0, 0, 0, 0, -1], [-y^2z^3, -x^4y^2 + x^3y^2z, x^5 + z^5, 0, 0, y^2z^2, 0, 0])

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

Ext^4 = Module([0])

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

As you can see the <formula>Ext^2</formula> is not  presented
minimally. The minimal presentation will be available on a next
version of CoCoA.
  </description>
  <syntax>
Ext(I:INT, M:TAGGED("Quotient"), Q:TAGGED("Quotient")): TAGGED("Quotient") 
Ext(I:LIST, M:TAGGED("Quotient"), Q:TAGGED("Quotient")): TAGGED("$ext.ExtList")
</syntax> 
  <see>Res</see>
  <see>Depth</see>

  <type>ideal</type> 
  <type>module</type> 
  <type>quotient</type> 

  <key>ext</key> 
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>EvalHilbertFn</title>
    <short_description>evaluate the Hilbert function</short_description>

    <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 <code>Hilbert(R/I,N)</code> but time is saved since the
Hilbert function does not need to be recalculated at each call.

        
<example>
Use R ::= Q[w,x,y,z];
I := Ideal(z^2-xy,xz^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>

    <syntax>
EvalHilbertFn(H:TAGGED(<coc-quotes>$hp.Hilbert</coc-quotes>),N:INT):INT
</syntax>

    <see>Hilbert</see>
    <see>HilbertFn</see>
    <see>HilbertPoly</see>

    <type>hilbert</type>
    <type>integer</type>

    <key>evalhilbertfn</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Fact</title>
    <short_description>factorial function</short_description>

    <description>
This function returns N factorial.

        
<example>
Fact(5);
120
-------------------------------
Fact(100);
9332621544394415268169923885626670049071596826438162146859
2963895217599993229915608941463976156518286253697920827223
758251185210916864000000000000000000000000
------------------------------- 
</example>
    </description>

    <syntax>
Fact(N:INT):INT

where N is a non-negative integer.
</syntax>

    <see>Bin</see>

    <type>integer</type>

    <key>fact</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Factor</title>
    <short_description>factor a polynomial</short_description>

    <description>
This function factors a polynomial in its ring of definition.
Multivariate factorization is not yet supported over finite fields.
(For information about the algorithm, consult <ref>Pointers to the
Literature</ref>.)

<par/>
The function returns a list of the form <code>[[F_1,N_1],...,[F_r,N_r]]</code>
where <code>F_1^N_1 ... F_r^N_r = F</code> and the <code>F_i</code> are irreducible in the
current ring.

        
<example>
Use R ::= Q[x,y];
F := x^12 - 37x^11 + 608x^10 - 5852x^9 + 36642x^8 - 156786x^7 + 468752x^6
    - 984128x^5 + 1437157x^4 - 1422337x^3 + 905880x^2 - 333900x + 54000;
Factor(F);
[[x - 2, 1], [x - 4, 1], [x - 6, 1], [x - 3, 2], [x - 5, 3], [x - 1, 4]]
---------------------------------
G := Product([W[1]^W[2] | W In It]);  -- check solution
F = G;
TRUE
---------------------------------
Factor((8x^2+16x+8)/27); -- the <coc-quotes>content</coc-quotes> appears as a factor of degree 0;
                         -- it is not factorized into prime factors.
[[x + 1, 2], [8/27, 1]]
---------------------------------
F := (x+y)^2*(x^2y+y^2x+3);
F;
x^4y + 3x^3y^2 + 3x^2y^3 + xy^4 + 3x^2 + 6xy + 3y^2
-------------------------------
Factor(F);  -- multivariate factorization
[[x^2y + xy^2 + 3, 1], [x + y, 2]]
-------------------------------
Use Z/(37)[x]; 
Factor(x^6-1);
[[x - 1, 1], [x + 1, 1], [x + 10, 1], [x + 11, 1], [x - 11, 1], [x - 10, 1]]
---------------------------------
Factor(2x^2-4); -- over a finite field the factors are made monic;
                -- leading coeff appears as <coc-quotes>content</coc-quotes> if it is not 1.
[[x^2 - 2, 1], [2, 1]]
--------------------------------- 
</example>
    </description>

    <syntax>
Factor(F:POLY):LIST
</syntax>

    <type>polynomial</type>

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

    <description>
This function counts how many times a give 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>

    <syntax>
FactorMultiplicity(N:INT, Fac:INT):INT
</syntax>

    <type>int</type>

    <key>factormultiplicity</key>
    <key>integer factor order</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Fields</title>
    <short_description>list the fields of a record</short_description>

    <description>
This function returns a list of all of the fields of the record P.

        
<example>
P := Record[ Name = <coc-quotes>David</coc-quotes>, Number = 3728852, Data = [<coc-quotes>X</coc-quotes>,<coc-quotes>Y</coc-quotes>] ];
Fields(P);
[<coc-quotes>Data</coc-quotes>, <coc-quotes>Name</coc-quotes>, <coc-quotes>Number</coc-quotes>]
-------------------------------
P.Data;
[<coc-quotes>X</coc-quotes>, <coc-quotes>Y</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Fields(P:RECORD):LIST
</syntax>

    <see>Introduction to Records</see>
    <see>Record</see>

    <type>record</type>

    <key>fields</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>First</title>
    <short_description>the first N elements of a list</short_description>

    <description>
In the first form, the function is the same as the function <coderef>Head</coderef>;
it returns the first element of the list L.  In the second form, it
returns the list of the first N elements of L.

        
<example>
L := [1,2,3,4,5];
First(L);
1
-------------------------------
First(L,3);
[1, 2, 3]
------------------------------- 
</example>
    </description>

    <syntax>
First(L:LIST):OBJECT
First(L:LIST,N:INT):OBJECT
</syntax>

    <see>Head</see>
    <see>Last</see>

    <type>list</type>

    <key>first</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>FirstNonZero</title>
    <short_description>the first non-zero entry in a vector</short_description>

    <description>
This function returns the first non-zero entry of V.  If it
is handed a zero vector then an error is signalled.

        
<example>
Use R ::= Q[x,y,z];
V := Vector(0,0,x^2+yz,0,z^2);
FirstNonZero(V);
x^2 + yz
------------------------------- 
</example>
    </description>

    <syntax>
FirstNonZero(V:VECTOR):POLY
</syntax>

    <see>NonZero</see>
    <see>FirstNonZeroPos</see>

    <type>vector</type>

    <key>firstnonzero</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>FirstNonZeroPos</title>
    <short_description>the first non-zero entry in a vector</short_description>

    <description>
This function returns the index of the first non-zero entry of V.  If it
is handed a zero vector then an error is signalled.

        
<example>
Use R ::= Q[x,y,z];
V := Vector(0,0,x^2+yz,0,z^2);
FirstNonZero(V);
x^2 + yz
-------------------------------
FirstNonZeroPos(V);
3
-------------------------------
V[FirstNonZeroPos(V)];
x^2 + yz
------------------------------- 
</example>
    </description>

    <syntax>
FirstNonZero(V:VECTOR):POLY
</syntax>

    <see>NonZero</see>
    <see>FirstNonZero</see>

    <type>vector</type>

    <key>firstnonzeropos</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Flatten</title>
    <short_description>flatten a list</short_description>

    <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 L by removing all nesting, bringing all elements <em>to
the top level</em>.  With the optional second argument, N, nesting is
removed down N levels.  Thus, the elements of M := Flatten(L,1) are
formed as follows: go through the elements of L one at a time; if an
elements is not a list, add it to M; if an element is a list, add all
of its elements to M.  Recursively, Flatten(L,N) = 
Flatten(Flatten(L,N-1),1).  For N large, depending on L, Flatten(L,N)
gives the same result as Flatten(L).

        
<example>
Flatten([1,[<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>,[2,3,4],<coc-quotes>c</coc-quotes>,<coc-quotes>d</coc-quotes>],5,6]);
[1, <coc-quotes>a</coc-quotes>, <coc-quotes>b</coc-quotes>, 2, 3, 4, <coc-quotes>c</coc-quotes>, <coc-quotes>d</coc-quotes>, 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 in the previous line
[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>

    <syntax>
Flatten(L:LIST):LIST
Flatten(L:LIST,N:INT):LIST
</syntax>

    <type>list</type>

    <key>flatten</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>FloatApprox</title>
    <short_description>approx. of rational number of the form <formula>M*10^E</formula></short_description>

    <description>
This function computes an approximation of the form <formula>M*10^E</formula> to 
a rational number X and to within a maximum specified relative error.
RelErr says indirectly how many decimal digits to include in the
mantissa.  Compare with <coderef>MantissaAndExponent</coderef>.

        
<example>
FloatApprox(1/3, 10^(-2));
333/1000
-------------------------------
FloatApprox(1000000/3, 10^(-2));
333000
-------------------------------
FloatApprox(1/3, 10^(-9));
3333333333/10000000000
------------------------------- 
</example>
    </description>

    <syntax>
FloatApprox(X:RAT, RelErr:RAT):RAT
</syntax>

    <see>DecimalStr</see>
    <see>FloatStr</see>
    <see>MantissaAndExponent</see>

    <type>rat</type>

    <key>floatapprox</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>FloatStr</title>
    <short_description>convert rational number to a float string</short_description>

    <description>
These two functions convert a rational number X into a (decimal)
floating point string.  The optional second argument Prec says how many
decimal digits to include in the mantissa; the default value is 10.
Note that an exponent is always included; the only exception being the
number zero which is converted to the string <code>0</code>.

        
<example>
FloatStr(2/3);         -- last printed digit is rounded
6.666666667*10^(-1)
-------------------------------
FloatStr(7^510);       -- no arbitrary limit on exponent range
1.000000938*10^431
-------------------------------
FloatStr(1/81, 50);    -- precision of mantissa specified by user
1.2345679012345679012345679012345679012345679012346*10^(-2)
-------------------------------
FloatStr(1/2);         -- trailing zeroes are not suppressed
5.000000000*10^(-1)
------------------------------- 
</example>
    </description>

    <syntax>
FloatStr(X:RAT):STRING
FloatStr(X:RAT, Prec:INT):STRING
</syntax>

    <see>DecimalStr</see>
    <see>FloatApprox</see>
    <key>mantissaandexponent</key>

    <type>rat</type>
    <type>string</type>

    <key>floatstr</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>For</title>
    <short_description>loop command</short_description>

    <description>
In the first form, the variable I is assigned the values 
<code>N_1, N_1+1, ..., N_2</code> 
in succession.  After each assignment, the command sequence C
is executed.  The second form is the same, except that I is assigned
the values <code>N_1, N_1+D, N_1+2D</code>, etc. until the greatest value less than
or equal to <code>N_2</code> is reached.  If <code>N_2 &lt; N_1</code>, then C is not executed. 

<par/>
Note: Large values for <code>N_1, N_2</code>, 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 <code>To</code>.

        
<example>
For N := 1 To 5 Do Print(2^N, <coc-quotes> </coc-quotes>) EndFor;
2 4 8 16 32 
-------------------------------
For N := 1 To 20 Step 3 Do Print(N, <coc-quotes> </coc-quotes>) EndFor;
1 4 7 10 13 16 19 
-------------------------------
For N := 10 To 1 Step -2 Do Print(N, <coc-quotes> </coc-quotes>) EndFor;
10 8 6 4 2 
-------------------------------
For N := 5 To 3 Do Print(N, <coc-quotes> </coc-quotes>) EndFor;  -- no output 
</example>

Loops can be nested.

        
<example>
Define Sort(Var(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];
Sort(M);
M;
[1, 2, 3, 4, 5]
------------------------------- 
</example>

(Note that <code>Var(L)</code> is used so that the function can change the value
of the variable referenced by L.  See <code>Var</code>.)
    </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>

    <see>Foreach</see>
    <see>Repeat</see>
    <see>While</see>

    <type>programming</type>
    <type>loops</type>

    <key>for</key>
    <key>step</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Foreach</title>
    <short_description>loop command</short_description>

    <description>
The dummy variable X is assigned the value of each component of L in
turn.  After each assignment the command sequence C is executed.
Note: don&apos;t forget to capitalize <code>In</code>.

        
<example>
Foreach N In 1..10 Do  -- Note: 1..10 gives the list [1,...,10].
  Print(N^2, <coc-quotes> </coc-quotes>);
EndForeach;
1 4 9 16 25 36 49 64 81 100 
-------------------------------
Use R ::= Q[x,y,z];
F := x^2y + 3y^2z - z^3;
J := [Der(F,X) | X In Indets()];  -- the Jacobian for F
J;
[2xy, x^2 + 6yz, 3y^2 - 3z^2]
-------------------------------
Foreach X In J Do -- square each component of the Jacobian
  PrintLn(X^2);
EndForeach;
4x^2y^2
x^4 + 12x^2yz + 36y^2z^2
9y^4 - 18y^2z^2 + 9z^4

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

    <syntax>
Foreach X In L Do C EndForeach

where X is a dummy variable, L is a list, and C is a sequence of commands.
</syntax>

    <see>For</see>
    <see>Repeat</see>
    <see>While</see>

    <type>programming</type>
    <type>loops</type>

    <key>foreach</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Format</title>
    <short_description>convert object to formatted string</short_description>

    <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 := [1,2,3];
M := Format(L,20);
M;
           [1, 2, 3]
-------------------------------
Type(L);
LIST
-------------------------------
Type(M);
STRING
-------------------------------
Format(L,2);  -- <coc-quotes>Format</coc-quotes> does not truncate
[1, 2, 3]
------------------------------- 
</example>
    </description>

    <syntax>
Format(E:OBJECT,N:INT):STRING
</syntax>

    <see>IO.SprintTrunc</see>
    <see>Latex</see>
    <see>Sprint</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>format</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Fraction</title>
    <short_description>returns the quotient of its arguments</short_description>

    <description>
This function returns E/F provided the quotient is defined (see
<ref>Algebraic Operators</ref>).

        
<example>
Use R ::= Q[x,y];
Fraction(2,3);
2/3
-------------------------------
Fraction(2,4);
1/2
-------------------------------
Fraction(x,x+y);
x/(x + y)
-------------------------------
Fraction(5%11,6%11);
10 % 11
------------------------------- 
</example>
    </description>

    <syntax>
Fraction(E:OBJECT,F:OBJECT)
</syntax>

    <see>Algebraic Operators</see>

    <type>integer</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>
    <type>zmod</type>

    <key>fraction</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Function</title>
    <short_description>return a function</short_description>

    <description>
This function returns the function---user-defined or built
in---identified by the string S.  In the second form, one first
provides the name of the package, then the name of the function. (An
alternative is the syntax <code>Function(P.S)</code>.

<par/>
One may use <code>Function</code> to assign a function to a variable which can
then be executed via the function <coderef>Call</coderef>:

        
<example>
F := Function(<coc-quotes>Deg</coc-quotes>);
F;
Deg(...)
-------------------------------
Type(F);
FUNCTION
-------------------------------
Call(F,x+y^2);
2
-------------------------------
-- the Call-statement here is equivalent to:
Deg(x+y^2);
2
-------------------------------
Function(<coc-quotes>Insert</coc-quotes>);
Insert(L,I,O)
-------------------------------
Function(<coc-quotes>$list</coc-quotes>,<coc-quotes>Insert</coc-quotes>); -- or <coc-quotes>Function(<coc-quotes>$list.Insert</coc-quotes>)</coc-quotes> 
Insert(L,I,O)
------------------------------- 
</example>
    </description>

    <syntax>
Function(S:STRING):FUNCTION
Function(P:STRING,S:STRING):FUNCTION
</syntax>

    <see>Call</see>
    <see>Functions</see>

    <type>function</type>

    <key>function</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Functions</title>
    <short_description>list the functions of a package</short_description>

    <description>
This function returns a list of functions defined in the package
identified by S. (The function <coderef>Packages</coderef> lists the packages currently
loaded into memory.)

        
<example>
Functions(<coc-quotes>$binrepr</coc-quotes>);
[About(), Man(), Initialize(), PolyBinRepr_xi(P), PolyBinRepr_xii(P),
BinExp(...), EvalBinExp(BE,Up,Down), Aux_BinExp(H,N), Tagged(X,T),
Print_Bin(B), Print_BinExp(BE), Print_BinRepr(BR), PkgName()] 
-------------------------------
L:= It; 
Describe L[5];
DEFINE BinExp(...)
  IF Shape(ARGV) = [
    INT,
    INT] THEN 
    Return($binrepr.Aux_BinExp(ARGV[1],ARGV[2]))
  ELSIF Shape(ARGV) = [
    INT,
    INT,
    INT,
    INT] THEN 
    Return(EvalBinExp($binrepr.Aux_BinExp(ARGV[1],ARGV[2]),ARGV[3],ARGV[4]))
  ELSE 
    Error(ERR.BAD_PARAMS,<coc-quotes>(BinExp arguments must be 2 or 4 INT)</coc-quotes>)
  END; 
END
------------------------------- 
</example>
    </description>

    <syntax>
Functions(S:STRING):LIST of FUNCTION
</syntax>

    <type>help</type>
    <type>function</type>
    <type>packages</type>

    <key>functions</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Complete</title>
    <short_description>Complete an interactive Groebner-type calculation</short_description>

    <description>
This function completes a calculation started in the Interactive
Groebner Framework.  For explanations and examples, see 
<ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Complete(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>

    <key>gb.complete</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.GetBettiMatrix</title>
    <short_description>returns the Betti matrix computed so far</short_description>

    <description>
This function, if used after executing <code>Res(M)</code>, prints the Betti
matrix for M.  Within the Interactive Groebner Framework, in which
resolutions may be computed one step at a time, the function returns
the Betti matrix for the part of the resolution computed so far.  See
<code>GB.GetRes</code> for an example.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(x^2-yt,xy-zt,xy);
Res(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
-------------------------------
GB.GetBettiMatrix(I);
--------------
               
--------------
   0    0    0 
   0    0    3 
   0    0    0 
   0    4    0 
   2    0    0 
--------------

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

    <syntax>
GB.GetBettiMatrix(M:IDEAL or MODULE):TAGGED(<coc-quotes>$io.Matrix</coc-quotes>)
</syntax>

    <see>GB.GetRes</see>
    <see>GB.GetResLen</see>
    <see>Res</see>
    <see>The Interactive Groebner Framework</see>
    <see>BettiDiagram</see>
    <see>BettiMatrix</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.getbettimatrix</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.GetNthSyz</title>
    <short_description>returns the part of the Nth syzygy module computed so far</short_description>

    <description>
This function, if used after executing <code>Res(M)</code>, returns the Nth
syzygy module for M.  Within the Interactive Groebner Framework, in
which resolutions may be computed one step at a time, the function
returns the part of the Nth syzygy module computed so far.  In
contrast, the function <coderef>Syz</coderef> always determines the complete syzygy
module even from within the Interactive Groebner Framework.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(x^2-yt,xy-zt,xy);
GB.Start_Res(I);
GB.Step(I);
GB.GetNthSyz(I,1); GB.GetNthSyz(I,2);
Module([0])
-------------------------------
Module([0])
-------------------------------
GB.Step(I);
GB.GetNthSyz(I,1); GB.GetNthSyz(I,2);
Module([0, 0])
-------------------------------
Module([0])
-------------------------------
GB.Steps(I,5);
GB.GetNthSyz(I,1); GB.GetNthSyz(I,2);
Module([-xz, -y^2, yz])
-------------------------------
Module([0])
-------------------------------
GB.Complete(I);
GB.GetNthSyz(I,1); GB.GetNthSyz(I,2);
Module([-xz, -y^2, yz], [tz, xy, 0], [0, -x^2 + ty, -tz], [-x^2 + ty, 0, xy])
-------------------------------
Module([-x, -y, 0, z], [-t, -x, -y, 0])
------------------------------- 
</example>
    </description>

    <syntax>
GB.GetNthSyz(M:IDEAL or MODULE,N:INT):MODULE
</syntax>

    <see>GB.GetNthSyzShifts</see>
    <see>GB.GetRes</see>
    <see>Res</see>
    <see>Syz</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.getnthsyz</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.GetNthSyzShifts</title>
    <short_description>shifts of the Nth syzygy module computed so far</short_description>

    <description>
This function, if used after executing <code>Res(M)</code>, returns the shifts
for the Nth syzygy module for M.  Within the Interactive Groebner
Framework, in which resolutions may be computed one step at a time,
the function returns shifts of the part of the Nth syzygy module
computed so far.  

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(x^2-yt,xy-zt,xy);
GB.Start_Res(I);
GB.Steps(I,6);
GB.GetNthSyzShifts(I,2);
Shifts([x^2yz])
-------------------------------
GB.Complete(I);
GB.GetNthSyzShifts(I,2);
Shifts([x^2yz, txyz, tx^2z, x^3y])
-------------------------------
J := Ideal(t,x)^3;
Res(J);
0 --&gt; R^3(-4) --&gt; R^4(-3)
-------------------------------
GB.GetNthSyzShifts(J,1);
Shifts([x^3, tx^2, t^2x, t^3])
-------------------------------
GB.GetNthSyzShifts(J,2);
Shifts([tx^3, t^2x^2, t^3x])
-------------------------------
SS := It;
SS[1];
tx^3
------------------------------- 
</example>
    </description>

    <syntax>
GB.GetNthSyzShifts(M:IDEAL or MODULE,N:INT):TAGGED(<coc-quotes>shifts</coc-quotes>)
</syntax>

    <see>GB.GetNthSyz</see>
    <see>GB.GetRes</see>
    <see>Res</see>
    <see>Shifts</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.getnthsyzshifts</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.GetRes</title>
    <short_description>returns the resolution computed so far</short_description>

    <description>
This function returns the part of the resolution of M computed so
far.  It does not compute the resolution of M as does <coderef>Res</coderef>, rather,
<code>GB.GetRes</code> is intended primarily to be used within the Interactive
Groebner Framework.  Thus, for example, <code>GB.GetRes</code> may be used to
examine the resolution as it is computed, one step at a time.

        
<example>
Use R ::= Q[txyz];
I := Ideal(x^2-yt,xy-zt,xy);
GB.Start_Res(I); -- start Interactive Groebner Framework
GB.Step(I); -- take one step in calculation of resolution
GB.GetRes(I);  -- the resolution so far
0 --&gt; R(-2)
-------------------------------
GB.Step(I);  -- one more step
GB.GetResLen(I);  -- the computed resolution still has length 1
1
-------------------------------
GB.GetBettiMatrix(I);  -- the Betti Matrix so far
----
     
----
   0 
   2 
----

-------------------------------
GB.GetRes(I);
0 --&gt; R^2(-2)
-------------------------------
GB.Steps(I,5); -- five more steps
GB.GetRes(I);
0 --&gt; R(-4) --&gt; R^3(-2)
-------------------------------
GB.Complete(I); -- complete the calculation
GB.GetResLen(I);
3
-------------------------------
GB.GetBettiMatrix(I);
--------------
               
--------------
   0    0    0 
   0    0    3 
   0    0    0 
   0    4    0 
   2    0    0 
--------------

-------------------------------
GB.GetRes(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
------------------------------- 
</example>
    </description>

    <syntax>
GB.GetRes(M:IDEAL or MODULE):TAGGED(<coc-quotes><code>$gb.Res</code></coc-quotes>)
</syntax>

    <see>GB.GetBettiMatrix</see>
    <see>GB.GetResLen</see>
    <see>Res</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.getres</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.GetResLen</title>
    <short_description>returns the length of the resolution computed so far</short_description>

    <description>
This function, if used after executing <code>Res(M)</code>, prints the length of
the resolution for M.  Within the Interactive Groebner Framework, in
which resolutions may be computed one step at a time, the function
returns the length of the part of the resolution computed so far.  See
<code>GB.GetRes</code> for an example.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(x^2-yt,xy-zt,xy);
Res(I);
0 --&gt; R^2(-5) --&gt; R^4(-4) --&gt; R^3(-2)
-------------------------------
GB.GetResLen(I);
3
------------------------------- 
</example>
    </description>

    <syntax>
GB.GetResLen(M:IDEAL or MODULE):INT
</syntax>

    <see>GB.GetBettiMatrix</see>
    <see>GB.GetRes</see>
    <see>Res</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.getreslen</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.ResReport</title>
    <short_description>status of an interactive resolution calculation</short_description>

    <description>
This function reports statistics about the current status of a
resolution computation begun in the Interactive Groebner Framework.
For explanations and examples, see <ref>The Interactive Groebner
Framework</ref>.
    </description>

    <syntax>
GB.ResReport(M:IDEAL or MODULE):NULL
</syntax>

    <see>GB.Stats</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>

    <key>gb.resreport</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>GBasis</title>
    <short_description>start interactive Groebner basis computation</short_description>

    <description>
This command starts the Interactive Groebner Framework for
calculating a Groebner basis for M.  For explanations and examples,
see <ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Start_GBasis(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_gbasis</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>MinGens</title>
    <short_description>start interactive minimal generator calculation </short_description>

    <description>
This command starts the Interactive Groebner Framework for
calculating minimal generators for M.  For explanations and examples,
see <ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Start_MinGens(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_mingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>MinSyzMinGens</title>
    <short_description>start interactive calc., min. syzs. of min. gens.</short_description>

    <description>

The <code>GB.Start_MinSyzMinGens</code> command has been removed.

    </description>

    <syntax>
GB.Start_MinSyzMinGens:  COMMAND ELIMINATED
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_minsyzmingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>Res</title>
    <short_description>start interactive resolution computation</short_description>

    <description>
This command starts the Interactive Groebner Framework for
calculating a resolution for M.  For explanations and examples, see 
<ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Start_Res(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_res</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>Syz</title>
    <short_description>start interactive syzygy computation</short_description>

    <description>
This command starts the Interactive Groebner Framework for
calculating syzygies for M.  For explanations and examples, see 
<ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Start_Syz(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_syz</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Start<_/>SyzMinGens</title>
    <short_description>start interactive calc. of syzygies of min. gens.</short_description>

    <description>

The <code>GB.Start_SyzMinGens</code> command has been removed.

    </description>

    <syntax>
GB.Start_SyzMinGens:  COMMAND ELIMINATED
</syntax>

    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-start</type>

    <key>gb.start_syzmingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Stats</title>
    <short_description>status of an interactive Groebner-type calculation</short_description>

    <description>
This function displays information about the current status of a
calculation started in the Interactive Groebner Framework.  For
explanations and examples, see <ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Stats(M:IDEAL or MODULE):NULL
</syntax>

    <see>GB.ResReport</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>

    <key>gb.stats</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Step</title>
    <short_description>take one step in an interactive Groebner-type calculation</short_description>

    <description>
This function performs one step in a calculation started in the
Interactive Groebner Framework.  
For explanations and examples, see <ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Step(M:IDEAL or MODULE):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>
    <see>GB.Steps</see>

    <type>groebner</type>
    <type>groebner-interactive</type>

    <key>gb.step</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GB.Steps</title>
    <short_description>take steps in an interactive Groebner-type calculation</short_description>

    <description>
This function performs N steps in a calculation started in the
Interactive Groebner Framework.
For explanations and examples, see <ref>The Interactive Groebner Framework</ref>.
    </description>

    <syntax>
GB.Steps(M:IDEAL or MODULE, N:INT):NULL
</syntax>

    <see>The Interactive Groebner Framework</see>
    <see>GB.Steps</see>

    <type>groebner</type>
    <type>groebner-interactive</type>

    <key>gb.steps</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GBasis</title>
    <short_description>calculate a Groebner basis</short_description>

    <description>
If M is an ideal or module, this function returns a list whose
components form a Groebner basis for M with respect to the
term-ordering of the current ring.  If M is a quotient of the current
ring by an ideal I or of a free module by a submodule N, then the
Groebner basis for M is defined to be that of I or N, respectively.

<par/>
If M is a variable, then the result is stored in M for
later use.  It can be retrieved as M.GBasis and can also be seen using
the command <ref>Describe</ref>.

<par/>
For a reduced Groebner basis, use the command <ref>ReducedGBasis</ref>.

<par/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[t,x,y];
I := Ideal(t^3-x,t^4-y);
Describe I;
Record[Type = IDEAL, Value = Record[Gens = [t^3 - x, t^4 - y]]]
-------------------------------
GBasis(I);
[t^3 - x, -tx + y, t^2y - x^2, x^3 - ty^2]
-------------------------------
Describe(I);  -- the Groebner basis has been stored in I
Record[Type = IDEAL, Value = Record[Gens = [t^3 - x, t^4 - y], GBasis
= [t^3 - x, -tx + y, t^2y - x^2, x^3 - ty^2]]]
-------------------------------
I.GBasis;
[t^3 - x, -tx + y, t^2y - x^2, x^3 - ty^2]
------------------------------- 
</example>

For fine control and monitoring of Groebner basis calculations, see
<ref>The Interactive Groebner Framework</ref> and <ref>Introduction to Panels</ref>.
    </description>

    <syntax>
GBasis(M:IDEAL, MODULE, or TAGGED(<coc-quotes>Quotient</coc-quotes>)):LIST
</syntax>

    <see>Introduction to Groebner Bases in CoCoA</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>gbasis</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GBasis5, Intersection5, Elim5</title>
    <short_description>calculations using the CoCoAServer</short_description>

    <description>
Same as <coderef>GBasis</coderef>, <coderef>Intersection</coderef>, <coderef>Elim</coderef>,
 but computed using the CoCoAServer.

<par/>
[Instructions for text/Emacs versions]
First you need to start the server by calling <code>server</code> from
a shell or, under
Emacs cocoa-mode, choosing <code>(re)start CoCoAServer</code> from the CoCoA
menu.  You may leave the CoCoAServer running all the time: it will take no
cpu time while waiting for requests.
It will respond to any other
request from you and from other CoCoA-4 processes connected to the same
machine on the same port (See <coderef>OpenSocket</coderef>).

<par/>
All the <code>5</code> functions behave like the corresponding
function in CoCoA-4, i.e. should give the same output!  
<par/>
All the <code>5x</code> functions allows extra options to be set, such
as (twin)floating point computations, parameters, shifts, different
orderings, gradings...
<par/>
NB these extra options might give an output which is incompatible with
<code>CurrentRing</code>!

        
<example>
----[  parameters ]-----------------------------------------------
M := $cocoa5.AddParamOrdMat(DegRevLexMat(3), 1);
Use Z/(32003)[a, x,y,z], Ord(M);

I := Ideal((a-1)x+(a^2+a)y,(a+1)x + y);
GBasis5(I);
GBasis5x(I, Record(NumParams=1));

----[  Twin floats  ]--------------------------------------------------
Use Q[x[0..5]];
L := [Randomized(DensePoly(4)) | I In 1..2];
Time LT(Ideal(L));
LT5x(Ideal(L), Record(FloatPrecision=128));

----[  Elimination  ]----------------
Use Q[x,y,z,w[3..5]], Weights([7, 4, 3, 1, 1, 1]);

I := Ideal(
	   x - 7413431 w[4]^7 - 9162341 w[3]*w[4]*w[5]^5,
	   y - 6521443 w[4]^4 - 2312257 w[3]^2*w[4]*w[5],
	   z - 5329421 w[4]^3 - 2122414 w[3]*w[5]^2
	   );

Time E := Elim([w[3],w[4]], I);
E5 := Elim5([w[3],w[4]], I);
E = E5;

----[  Intersection  ]-------------------------------
Use Q[x,y,z], Weights(1,2,1);
I := Ideal(xy, z^2);
J := Ideal(yz, x-z);
Intersection5(I, J);
// with parameters
M := CoCoA5.AddParamOrdMat(DegRevLexMat(3), 1);
Use Z/(32003)[a, x,y,z], Ord(M);
II := Ideal(x-y);
I := (a-1) * x * II;
J := (a+1) * y * II;
Intersection5x(I,J, Record(NumParams=1));

----[  Syzygies  ]--------------------------------------
Use Z/(101)[x,y,z], Weights(1,2,4);
L := [Vector(x^2,x^2),Vector(xy,xy)];
S5 := Syz5(L);

----[  Modules  ]---------------------------------------------------------
Use Q[x,y,z], PosTo;
M := Module([x,z], [z,y]);
ReducedGBasis(M);
ReducedGBasis5(M);
ReducedGBasis5x(M, Record(IsPosTo=False));

Use Q[x,y,z], PosTo;
M := Module([x,2y,3z], [1,0,1]);
// Change the ordering of the module components
// N..1 gives the first component as the biggest
ReducedGBasis5x(M, Record(ModuleCompOrd=[3,2,1]));
ReducedGBasis5x(M, Record(ModuleCompOrd=[1,3,2]));

Use Q[x,y,z], Weights([1,2,4]);
M := Module([x^2-y,1],[x^4-z,y^2]);
Info5 := Record();
Info5.ModuleShifts := Mat([[0,2]]);
GBasis5x(M, Info5);

// Grading given via OrdMat and Grading Dim
OrdMat := Mat([[1,1,1],[2,1,1],[1,1,0]]); // Ring Grading (first 2 Rows) 
                                          // Plus order (last row)
Use Z/(101)[x,y,z], Ord(OrdMat), ToPos;
M := Module([y-x,0,0], [x,0,z], [0,y^2-z^2,0]);
X := ReducedGBasis5(Module(Gens(M)));
// GBasis on a module with shifts
Info5 := Record();
Info5.OrdMat := OrdMat;
Info5.GradingDim := 2;
Info5.ModuleShifts := Mat([[3,1,2],[2,2,5]]); // GrDim rows!!
ReducedGBasis5x(M, Info5);

----[  ElimComponents5x ]---------------------------------------
Use Q[x,y,z];
M := Module([y,x,x],[z,x,x]);
X := $idealop5.ElimComponents5x([2,3], M, Record());

----[  ModuleCounterImage5x  ]------------------------
Use Z/(101)[x,y,z];
M := Module([x,0],[x,x]);
Phi := Mat([
	   [x,1],
	   [0,y]]);
$idealop5.ModuleCounterImage5x(M, Phi, Record());

----[  SolveSystem5x  ]-----------------------------------
// Solve HOMOGENEOUS systems as AX=B with A,B matrix with entries in k[x1..xn]
Use Z/(101)[x,y],PosTo;

B := Mat([[2x^2+2xy]]);
A := Mat([[x-y, x+y]]);

$idealop5.SolveSystem5x(A, B, Record());
</example>

    </description>

    <syntax>
GBasis5(M:IDEAL, MODULE):LIST
GBasis5x(M:IDEAL, MODULE,  Info5: RECORD):LIST
</syntax>

    <see>Introduction to Groebner Bases in CoCoA</see>
    <see>OpenSocket</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>gbasis5x</key>
    <key>reducedgbasis5x</key>
    <key>lt5x</key>
    <key>elim5x</key>
    <key>cocoa5x</key>
    <key>syz5x</key>
    <key>intersection5x</key>
    <key></key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GBM</title>
    <short_description>intersection of ideals for zero-dimensional schemes</short_description>

    <description>
This function computes the intersection of ideals corresponding to
zero-dimensional schemes: GBM is for affine schemes, and <coderef>HGBM</coderef> for
projective schemes.  The list L must be a list of ideals.  The function
<coderef>IntersectionList</coderef> 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 Q[x,y,z];
I1:=IdealOfPoints([[1,2,1], [0,1,0]]);     -- a simple affine scheme
I2:=IdealOfPoints([[1,1,1], [2,0,1]])^2;   -- another affine scheme
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>

    <syntax>
GBM(L:LIST):IDEAL
</syntax>

    <see>Finite Point Sets: Buchberger-Moeller</see>
    <see>IdealAndSeparatorsOfPoints</see>
    <see>IdealAndSeparatorsOfProjectivePoints</see>
    <see>IdealOfPoints</see>
    <see>IdealOfProjectivePoints</see>
    <see>HGBM</see>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>

    <key>fat</key>
    <key>gbm</key>
    <key>point</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GCD</title>
    <short_description>greatest common divisor</short_description>

    <description>
This function returns the greatest common divisor of <code>F_1,...,F_n</code>
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 ::= Q[x,y];
F := x^2-y^2;
G := (x+y)^3;
GCD(F,G);
x + y
-------------------------------
GCD(3*4,3*8,6*16);
12
-------------------------------
GCD([3*4,3*8,6*16]);
12
------------------------------- 
</example>
    </description>

    <syntax>
GCD(F_1:INT,...,F_n:INT):INT
GCD(L:LIST of INT):INT

GCD(F_1:POLY,...,F_n:POLY):POLY
GCD (L:LIST of POLY):POLY
</syntax>

    <see>Div</see>
    <see>Mod</see>
    <see>LCM</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>integer</type>
    <type>polynomial</type>

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

    <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([Fact(20),Fact(10)]);
[46189, 4, 14175]
-------------------------------

</example>
    </description>

    <syntax>
GCDFreeBasis(L:LIST of INT):LIST of INT
    
</syntax>

    <see>GCD</see>

    <type>integer</type>

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

    <description>
<code>GenericPoints</code> 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 ::= Q[x,y];GenericPoints(7);
[[1, 0], [0, 1], [1, 1], [12, 59], [6, 63], [12, 80], [17, 63]]
-------------------------------
GenericPoints(7,500);
[[1, 0], [0, 1], [1, 1], [220, 162], [206, 452], [98, 106], [403, 449]]
-------------------------------
Use R ::= Z/(5)[x,y,z];
GenericPoints(7);
[[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [2, 1, 1], [2, 2, 4], [3, 1, 3]]
-------------------------------
GenericPoints(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>

    <syntax>
GenericPoints(NumPoints:INT):LIST 
GenericPoints(NumPoints:INT,RandomRange:INT):LIST
</syntax>

    <type>integer</type>
    <type>list</type>
    <type>points</type>

    <key>genericpoints</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GenRepr</title>
    <short_description>representation in terms of generators</short_description>

    <description>
This function returns a list giving a representation of X in terms of
generators for I. Let the generators for I be <code>[G_1,...,G_t]</code>.  If X is
in I, then <code>GenRepr</code> will return a list <code>[F_1,...,F_t]</code> such that
<verbatim>
             X = F_1*G_1 + ... + F_t*G_t.
</verbatim>
If X is not in I, then <code>GenRepr</code> returns the empty list, [].

        
<example>
Use R ::= Q[xy];
I := Ideal(x+y^2,x^2-xy);
GenRepr(x^3-x^2y-y^3-xy,I);
[-y, x]
-------------------------------
-y I.Gens[1] + x I.Gens[2];
x^3 - x^2y - y^3 - xy
-------------------------------
GenRepr(x+y,I);  
[ ]
-------------------------------
x+y IsIn I;  -- the empty list was returned above since x+y is not in I
FALSE
-------------------------------
V1:= Vector(x,y,y^2); V2:= Vector(x-y,0,x^2);
X := x^2 V1 - y^2 V2;
M := Module(V1,V2);
GenRepr(X,M);
[x^2, -y^2]
------------------------------- 
</example>
    </description>

    <syntax>
GenRepr(X:POLY,I:IDEAL):LIST of POLY
GenRepr(X:VECTOR,I:MODULE):LIST of POLY
</syntax>

    <see>DivAlg</see>
    <see>IsIn</see>
    <see>NF</see>

    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>genrepr</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Gens</title>
    <short_description>list of generators of an ideal</short_description>

    <description>
This function returns a list of polynomials which generate the ideal
I or the module M.  The list is not necessarily minimal.  Note that
I.Gens and M.Gens will give the same lists of generators.  The
advantage of <code>Gens</code> is that its argument can be any expression
evaluating to an ideal or module.

        
<example>
Use R ::= Q[x,y];
I := Ideal(y^2-x^3,xy);
Gens(I);
[-x^3 + y^2, xy]
-------------------------------
I.Gens;
[-x^3 + y^2, xy]
-------------------------------
Gens(I^2);
[x^6 - 2x^3y^2 + y^4, -x^4y + xy^3, x^2y^2]
------------------------------- 
</example>
    </description>

    <syntax>
Gens(I:IDEAL):LIST
Gens(M:MODULE):LIST
</syntax>

    <see>Minimalize</see>
    <see>Minimalized</see>

    <type>ideal</type>
    <type>module</type>

    <key>gens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Get</title>
    <short_description>read characters from a device</short_description>

    <description>
This function reads N characters from D and returns the list of
their ascii codes.

        
<example>
D := OpenIFile(<coc-quotes>io.cpkg</coc-quotes>);  -- open the file <coc-quotes>io.cpkg</coc-quotes>
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>

<code>Get(DEV.STDIN,3)</code>, 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>

    <syntax>
Get(D:DEVICE,N:INT):LIST of INT
</syntax>

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

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

    <key>get</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GetErrMesg</title>
    <short_description>returns the message associated with an error</short_description>

    <description>
This function returns the error message associated with an error.

        
<example>
Str := GetErrMesg(1/0);
PrintLn(Str);
Division by zero

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

    <syntax>
GetErrMesg(E:ERROR):STRING
</syntax>

    <see>Catch</see>
    <see>Error</see>

    <type>error</type>

    <key>geterrmesg</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Gin</title>
    <short_description>generic initial ideal</short_description>

    <description>
This function returns the [probabilistic] gin (generic initial ideal)
of the ideal I.  It is attained by computing the leading term ideal of
g(I), where g is a random change of coordinates with integer
coefficients in [-Range, Range], the default is [-100, 100].
This process is repeated until 4 consecutive change of coordinates
give the same leading term ideal.

        
<example>
Use R ::= Q[x,y,z];  -- the default term-ordering is DegRevLex
Gin(Ideal(y^2-xz, x^2z-yz^2));
Ideal(x^2, xy^2, y^4)
-------------------------------
Use R ::= Q[x,y,z], Lex;
Gin(Ideal(y^2-xz, x^2z-yz^2), 20);
Ideal(x^2, xy^2, xyz^2, xz^4, y^6)
------------------------------- 
</example>
    </description>

    <syntax>
Gin(I: IDEAL): IDEAL
Gin(I: IDEAL, Range: INT): IDEAL
</syntax>

    <type>ideal</type>

    <key>gin</key>
    <key>generic initial ideal</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>GlobalMemory</title>
    <short_description>contents of global memory</short_description>

    <description>
This function prints the contents of the global memory which are not
bound to rings: variables prefixed by <code>MEMORY</code> but not by
<code>MEMORY.ENV</code>.  Untagging the value returned by <code>GlobalMemory</code> gives a
list of strings which are identifiers for the global variables.  The
command <code>Fields(MEMORY)</code> gives the same set of strings.

<par/>
For more information about memory in CoCoA, see the chapter entitled
<ref>Memory Management</ref>.

        
<example>
Use R ::= Q[x,y,z];
A := 3;
ENV.R.B := 7;
MEMORY.C := 6;
GlobalMemory();
[<coc-quotes>C</coc-quotes>, <coc-quotes>DEV</coc-quotes>, <coc-quotes>ENV</coc-quotes>, <coc-quotes>ERR</coc-quotes>, <coc-quotes>PKG</coc-quotes>]
-------------------------------
MEMORY.ENV;  -- the record holding the rings defined during the
             -- CoCoA session
Record[Q = Q, Qt = Q[t], R = Q[x,y,z], Z = Z]
-------------------------------
Memory();  -- the working memory
[<coc-quotes>A</coc-quotes>, <coc-quotes>It</coc-quotes>]
------------------------------- 
Memory(R);  -- the global variables bound to the ring R
[<coc-quotes>B</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
GlobalMemory():TAGGED(<coc-quotes>Memory</coc-quotes>)
</syntax>

    <see>Memory</see>
    <see>Memory Management</see>

    <type>memory</type>
    <type>system</type>

    <key>globalmemory</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Browse</title>
    <short_description>browse the online help system</short_description>

    <description>
This function browses the online help system.  Without an argument,
it displays the next section of the online manual or the next
command.  With integer argument N, it skips ahead (or skips back, if N
is negative) N sections of the manual or N commands.
    </description>

    <syntax>
H.Browse():NULL;
H.Browse(N:INT):NULL
</syntax>

    <see>H.Commands</see>
    <see>?</see>
    <see>Man</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.browse</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Commands</title>
    <short_description>list commands according to type</short_description>

    <description>
This function prints a list of commands associated with the string S.
For example, <code>H.Commands(<coc-quotes>poly</coc-quotes>)</code> will list all documented commands
having to do with polynomials.  Unlike <code>?</code>, this function searches
only the list of commands (not both the list of commands and online
manual, both of which are a part of the online help system).  Also,
unlike <code>?</code>, this function does not try to use the string S to
identify a unique function. Instead it looks for all functions whose
<em>type</em> is S, i.e., that are somehow related with the search string
S.  The types are often the names of data types in CoCoA.  A complete
list of these types, along with additional information, can be found
by entering <code>H.Commands()</code>, without any argument.

<par/>
After a command name is found, complete information on the command can
be obtained using <code>?</code>.  The function <code>H.Syntax</code> prints just the
syntax for the command.

<par/>
Note: entering <code>H.Commands(<coc-quotes></coc-quotes>)</code> will produce a complete list of the
documented commands.
    </description>

    <syntax>
H.Commands():NULL;
H.Commands(S:STRING):NULL
</syntax>

    <see>?</see>
    <see>Man</see>
    <see>H.Syntax</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.commands</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Man</title>
    <short_description>search online help system</short_description>

    <description>
This function is synonymous with <coderef>Man</coderef>, which performs the same task
as <code>?</code>.  See <coderef>?</coderef>, <coderef>Man</coderef> for more information.
    </description>

    <syntax>
H.Man():NULL
H.Man(S:STRING):NULL
H.Man(S:STRING,N:INT):NULL

where N = 0 or 1.
</syntax>

    <see>H.Commands</see>
    <see>H.Syntax</see>
    <see>?</see>
    <see>Man</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.man</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.OutCommands</title>
    <short_description>print command descriptions to a file</short_description>

    <description>
The function prints the online descriptions of commands to the text
file named S.  Warning: if a file named S already exists, it is
appended to.  The first form prints all of the command descriptions,
the second prints only the command with number A, and the last prints
commands with numbers A to B.  The total number of commands is given
by Len(MEMORY.Doc.Commands).  The name of the command with number I is
MEMORY.Doc.Commands[I].Title.  Entering <code>H.Commands(<coc-quotes></coc-quotes>)</code> will list the
documented commands, in order.

        
<example>
H.OutCommands(<coc-quotes>CommandFile</coc-quotes>,1,10); 
</example>

To print sections of the online manual, use the function <coderef>H.OutManual</coderef>.
    </description>

    <syntax>
H.OutCommands(S:STRING):NULL
H.OutCommands(S:STRING,A:INT):NULL
H.OutCommands(S:STRING,A:INT,B:INT):NULL
</syntax>

    <see>H.OutManual</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.outcommands</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.OutManual</title>
    <short_description>print the online manual to a file</short_description>

    <description>
This function prints sections of the manual to a text file named S.
Warning: if a file named S already exists, it is appended to.  The
first form prints the entire manual to a file.  The others are used to
print part P, chapter C, section S.  Recall that the online help
consists of a manual *and* a list of commands.  To print out the
commands, use <coderef>H.OutCommands</coderef>.

        
<example>
H.OutManual(<coc-quotes>part1.chp2</coc-quotes>,1,2); 
</example>
    </description>

    <syntax>
H.OutManual(S:STRING):NULL
H.OutManual(S:STRING,P:INT):NULL
H.OutManual(S:STRING,P:INT,C:INT):NULL
H.OutManual(S:STRING,P:INT,C:INT,S:INT):NULL
</syntax>

    <see>H.OutCommands</see>
    <see>H.Toc</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.outmanual</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.SetMore</title>
    <short_description>more-device for online help</short_description>

    <description>
The purpose of these functions is to turn on and off filtering of the
online help system through the function <code>More</code>.  When the online help
system filters through <code>More</code> any output from online help is stored in
a <code>MoreDevice</code> then printed to the screen, N lines at a time.  The
number N is stored in the global variable MEMORY.MoreCount and may be
set directly by the user with the command <code>MEMORY.MoreCount := X</code>
where X is an integer.  The idea is to keep the output from scrolling
off of the screen.  See <coderef>More</coderef> for more information.

<par/>
The function <code>H.SetMore</code> turns on filtering through <code>More</code>; and if the
optional argument N is supplied, it sets MEMORY.MoreCount to N.

<par/>
The function <code>H.UnSetMore</code> turns off filtering through <code>More</code>, without
affecting MEMORY.MoreCount.
    </description>

    <syntax>
H.SetMore(N:INT):NULL
H.SetMore():NULL
</syntax>

    <see>More</see>
    <see>H.UnSetMore</see>

    <type>help</type>
    <type>online-help</type>

    <key>io</key>
    <key>h.setmore</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Syntax</title>
    <short_description>display the syntax of a command</short_description>

    <description>
The first form of the command, with no arguments, just prints this
message.  The second form looks for a command with associated keywords
containing S as a substring.  If S is exactly the keyword of a
command or if S is the substring of a keyword of only one command,
then the syntax for that command is displayed.  (The command <ref>H.Browse</ref>
can then be called to display additional information.)  Otherwise,
H.Syntax(S) lists the names all commands with associated keywords
containing S as a substring.  Note: the search is case insensitive.

        
<example>
H.Syntax(<coc-quotes>dense</coc-quotes>);
DensePoly(N:INT):POLY

Description: the sum of all power-products of a given degree

--&gt; <coc-quotes>H.Browse();</coc-quotes> for more information. &lt;--

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

    <syntax>
H.Syntax():NULL
H.Syntax(S:STRING):NULL
</syntax>

    <type>help</type>
    <type>online-help</type>

    <key>h.syntax</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Tips</title>
    <short_description>quick tips for using online help</short_description>

    <description>
This function prints advice on using CoCoA&apos;s online help system
effectively. 

        
<example>
H.Tips();

============ Quick Tips for Using Online Help =============

Here are some tips for using the online help system:

1. Searches are case insensitive and your search string need only be a
substring of a keyword to make a match.  Thus, for instance, to find
the section of the manual entitled <coc-quotes>Commands and Functions for
Polynomials</coc-quotes>, it is enough to type: <coc-quotes>?for poly</coc-quotes>.

             ---&gt; Output suppressed &lt;--- 
</example>
    </description>

    <syntax>
H.Tips():NULL
</syntax>

    <see>Online Help</see>

    <type>online-help</type>

    <key>h.tips</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Toc</title>
    <short_description>display the Table Of Contents of the online manual</short_description>

    <description>
The first form of this function, with no arguments, lists the titles
of the parts and chapters of the manual.  The second prints the table
of contents for part P.  The third prints the table of contents for
part P, chapter C.  The last form, with the string <em>all</em> as argument,
prints the entire table of contents.

<par/>
The contents of each section can be read online by giving enough of
its title as an argument to <code>?</code>.
    </description>

    <syntax>
H.Toc():NULL;
H.Toc(P:INT):NULL
H.Toc(P:INT,C:INT):NULL
H.Toc(<coc-quotes>all</coc-quotes>):NULL
</syntax>

    <see>?</see>
    <see>Man</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.toc</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.Tutorial</title>
    <short_description>run the CoCoA tutorial</short_description>

    <description>
The CoCoA tutorial is part of the online manual.  This function
displays the first section of the tutorial.  The following sections
can then be browsed using <coderef>H.Browse</coderef>.
    </description>

    <syntax>
H.Tutorial():NULL
</syntax>

    <see>H.Browse</see>

    <type>help</type>
    <type>online-help</type>

    <key>h.tutorial</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>H.UnSetMore</title>
    <short_description>more-device for online help</short_description>

    <description>
The purpose of these functions is to turn on and off filtering of the
online help system through the function <code>More</code>.  When the online help
system filters through <code>More</code> any output from online help is stored in
a <code>MoreDevice</code> then printed to the screen, N lines at a time.  The
number N is stored in the global variable MEMORY.MoreCount and may be
set directly by the user with the command <code>MEMORY.MoreCount := X</code>
where X is an integer.  The idea is to keep the output from scrolling
off of the screen.  See <coderef>More</coderef> for more information.

<par/>
The function <code>H.UnSetMore</code> turns off filtering through <code>More</code>, without
affecting MEMORY.MoreCount.  (see <coderef>H.SetMore</coderef>)
    </description>

    <syntax>
H.UnSetMore():NULL
</syntax>

    <see>More</see>
    <see>H.SetMore</see>

    <type>help</type>
    <type>online-help</type>

    <key>io</key>
    <key>h.unsetmore</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Head</title>
    <short_description>the first element of a list</short_description>

    <description>
This function returns the first element of the list L.

        
<example>
Head([3,2,1]);
3
------------------------------- 
</example>
    </description>

    <syntax>
Head(L:LIST):OBJECT
</syntax>

    <see>First</see>
    <see>Last</see>
    <see>Tail</see>

    <type>list</type>

    <key>head</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HColon</title>
    <short_description>ideal or module quotient</short_description>

    <description>
The function <coderef>Colon</coderef> 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 <coderef>Colon</coderef> only when the input 
is non-homogeneous, in which case, <code>HColon</code> may be faster.

        
<example>
Use R ::= Q[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>

    <syntax>
HColon(M:IDEAL,N:IDEAL):IDEAL
</syntax>

    <see>HSaturation</see>
    <see>Saturation</see>
    <see>:</see>
    <see>HColon</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>hcolon</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Help</title>
    <short_description>extend online help for user-defined functions</short_description>

    <description>
This command is used for extending the online help to include
information about user-defined functions.  It is *not* the main
command for getting information about CoCoA online. For information
about online help in general, enter <code>?</code> or <code>?online help</code>.

<par/>
There are two ways to let <code>Help</code> know about a help string associated
with a user-defined function.  First, one may use the line <code>Help S</code>
where S is the help string, as the first line of the function definition.

        
<example>
Define AddThree(X)
  Help <coc-quotes>adds 3 to its argument</coc-quotes>;
  Return X+3;
EndDefine;
Help(<coc-quotes>AddThree</coc-quotes>);
adds 3 to its argument
-------------------------------
F(0);
3
------------------------------- 
</example>

The second way to provide a help string for <code>Help</code> is to define a
function <code>Help_F</code> where F is the function identifier.

        
<example>
Define AddFive(X)
  Return X+5;
EndDefine;
Define Help_AddFive()
  Return <coc-quotes>adds 5 to its argument</coc-quotes>;
EndDefine;
Help(<coc-quotes>AddFive</coc-quotes>);
adds 5 to its argument
-------------------------------
AddFive(0); 
5
------------------------------- 
</example>
    </description>

    <syntax>
Help(S:STRING):NULL
</syntax>

    <see>Define</see>
    <see>Online Help</see>

    <type>help</type>

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

    <description>
This function computes the intersection of ideals corresponding to
zero-dimensional schemes: <coderef>GBM</coderef> is for affine schemes, and HGBM for
projective schemes.  The list L must be a list of ideals.  The function
<coderef>IntersectionList</coderef> 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 Q[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>

    <syntax>
HGBM(L:LIST):IDEAL
</syntax>

    <see>Finite Point Sets: Buchberger-Moeller</see>
    <see>IdealAndSeparatorsOfPoints</see>
    <see>IdealAndSeparatorsOfProjectivePoints</see>
    <see>IdealOfPoints</see>
    <see>IdealOfProjectivePoints</see>
    <see>GBM</see>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>

    <key>fat</key>
    <key>hgbm</key>
    <key>point</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Hilbert</title>
    <short_description>the Hilbert function</short_description>

    <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 <coderef>EvalHilbertFn</coderef> instead of <code>Hilbert(R,N)</code> in
order to speed up execution.
<par/>
This function is the same as <coderef>HilbertFn</coderef>.
<par/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[t,x,y,z];
Hilbert(R/Ideal(z^2-xy,xz^2+t^3));
H(0) = 1
H(1) = 4
H(t) = 6t-3   for t &gt;= 2
-------------------------------
M := R^2/Module([x^2-t,xy-z^3],[zy,tz-x^3y+3]);
Hilbert(M);
H(0) = 2
H(1) = 8
H(2) = 20
H(3) = 39
H(t) = 3t^2 + 6t-7   for t &gt;= 4
-------------------------------
Hilbert(M,3)
39
-------------------------------
Hilbert(M,5);
98
------------------------------- 
</example>
    </description>

    <syntax>
Hilbert(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes><code>$hp.Hilbert</code></coc-quotes>)
Hilbert(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>),N:INT):INT
</syntax>

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

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbert</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertFn</title>
    <short_description>the Hilbert function</short_description>

    <description>
Same as <coderef>Hilbert</coderef>.        
    </description>

    <syntax>
HilbertFn(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes><code>$hp.Hilbert</code></coc-quotes>)
HilbertFn(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>),N:INT):INT
</syntax>

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

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertfn</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertBasis</title>
    <short_description>Hilbert basis for a monoid</short_description>

    <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]]);
HilbertBasis(M);
[[0, 3, 2, 0], [1, 4, 1, 1], [2, 5, 0, 2]]
-------------------------------
M * Transposed(Mat(It));
Mat([
  [0, 0, 0],
  [0, 0, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
HilbertBasis(M:MAT): LIST

where M is a matrix over Z.
</syntax>

    <type>matrix</type>

    <key>hilbertbasis</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertPoly</title>
    <short_description>the Hilbert polynomial</short_description>

    <description>
This function returns the Hilbert polynomial for R as a polynomial in
the standard CoCoA ring Qt (= Q[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 <coderef>Hilbert</coderef>.

        
<example>
Use R ::= Q[w,x,y,z];
I := Ideal(z^2-xy,xz^2+w^3);
Hilbert(R/I);
H(0) = 1
H(1) = 4
H(t) = 6t-3   for t &gt;= 2
-------------------------------
F := HilbertPoly(R/I);
F;  -- a polynomial in the ring Qt
Qt :: 6t-3
-------------------------------
Subst(F,Qt::t,3);
Qt :: 15
------------------------------- 
</example>
    </description>

    <syntax>
Hilbert(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):POLY in the ring Qt.
</syntax>

    <see>EvalHilbertFn</see>
    <see>Hilbert</see>
    <see>HVector</see>
    <see>HilbertSeries</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertpoly</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertSeries</title>
    <short_description>the Hilbert-Poincare series</short_description>

    <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/>
The function <coderef>Poincare</coderef> is exacly the same as <coderef>HilbertSeries</coderef>.

<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 more information, see the article: A.M. Bigatti, <em>Computations of
Hilbert-Poincare Series,</em> J. Pure Appl. Algebra, 119/3 (1997),
237--253.
        
<example>
Use R ::= Q[t,x,y,z];
HilbertSeries(R/Ideal(0));
(1) / (1-t)^4
-------------------------------
Q := R/Ideal(t^2,x,y^3);  Poincare(Q);
(1 + 2t + 2t^2 + t^3) / (1-t)
-------------------------------
Poincare(R^2/Module([x^2,y],[z,y]));
(2 + t) / (1-t)^3
-------------------------------
Use R ::= Q[t,x,y,z], Weights([1,2,3,4]);
Poincare(R/Ideal(t^2,x,y^3));
---  Non Simplified Pseries  ---
(1-2t^2 + t^4 - t^9 + 2t^11 - t^13) / ( (1-t) (1-t^2) (1-t^3) (1-t^4) )
-------------------------------
Use R ::= Q[t,x,y,z], Weights(Mat([[1,2,3,4],[0,0,5,8]]));
Poincare(R/Ideal(t^2,x,y^3));
---  Non Simplified Pseries  ---
( - t^13x^15 + 2t^11x^15 - t^9x^15 + t^4-2t^2 + 1) / ( (1-t) (1-t^2) (1-t^3x^5) (1-t^4x^8) )
-------------------------------
</example>
    </description>

    <syntax>
HilbertSeries(M:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>Dim</see>
    <see>Hilbert</see>
    <see>HVector</see>
    <see>Multiplicity</see>
    <see>HilbertSeriesShifts</see>
    <see>HilbertSeriesMultiDeg</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertseries</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertSeriesMultiDeg</title>
    <short_description>the Hilbert-Poincare series wrt a multigrading</short_description>

    <description>
This function computes the Hilbert-Poincare series of M.
The input, M, must be homogeneous with respect to the grading defined
by the second argument.
<par/>
The function <coderef>PoincareMultiDeg</coderef> is exacly the same as <coderef>HilbertSeriesMultiDeg</coderef>.

<par/>
NOTES:
CoCoA-4 has an intrinsic limitation on multigradings (<coderef>Weights Modifier</coderef>)
which does not allow zero-entries in the first row of the defining
matrix.  
This function performs all the appropriate conversions for computing the
HilbertSeries wrt any positive grading (<coderef>IsPositiveGrading</coderef>).
<example>
Use R ::= Q[x,y,z];

WM := Mat([[1,0,0],[1,-1,0]]);
HilbertSeriesMultiDeg(R/Ideal(Indets())^2, WM);
</example>
    </description>

    <syntax>
HilbertSeriesMultiDeg(TAGGED(<coc-quotes>Quotient</coc-quotes>),WM:MAT):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>HilbertSeries</see>
    <see>Weights Modifier</see>
    <see>IsPositiveGrading</see>
    <see>PositiveGrading4</see>
    <see>PoincareMultiDeg</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertseriesmultideg</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HilbertSeriesShifts</title>
    <short_description>the Hilbert-Poincare series</short_description>

    <description>
This function computes the Hilbert-Poincare series of a
(single-graded) module M with shifts. 
The input, M, must be homogeneous (with respect the weights list).
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/>
The function <coderef>PoincareShifts</coderef> is exacly the same as
<coderef>HilbertSeriesShifts</coderef>.

<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 more information, see the article: A.M. Bigatti, <em>Computations of
Hilbert-Poincare Series,</em> J. Pure Appl. Algebra, 119/3 (1997),
237--253.
        
<example>
Use P ::= Q[x,y,z];
M := Module([x,y^3], [x-z,0]);
HilbertSeriesShifts(M, [2,0]);  -- HilbertPoincare series of a shifted module
(2x^3) / (1-x)^3
-------------------------------
PoincareShifts(P^2/M, [3,1]);   -- HP series of a shifted quotient module
(x + x^2 + 2x^3) / (1-x)^2
------------------------------- 
</example>
    </description>

    <syntax>
HilbertSeriesShifts(M: Module, ShiftsList: LIST):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
HilbertSeriesShifts(M: TAGGED(<coc-quotes>Quotient</coc-quotes>), ShiftsList: LIST)
                                           :TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>Dim</see>
    <see>Hilbert</see>
    <see>HVector</see>
    <see>Multiplicity</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hilbertseriesshifts</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HIntersection</title>
    <short_description>intersection of ideals</short_description>

    <description>
The function <code>HIntersection</code> returns the intersection of <code>I_1,...,I_n</code>
using a Hilbert-driven algorithm.  It differs from <coderef>Intersection</coderef> only
when the input is non-homogeneous, in which case, <code>HIntersection</code>
may be faster.

<par/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[x,y,z];
HIntersection(Ideal(x-z,y-2z),Ideal(x-2z,y-z));
Ideal(x + y - 3z, y^2 - 3yz + 2z^2)
------------------------------- 
</example>
    </description>

    <syntax>
HIntersection(I_1:IDEAL,...,I_n:IDEAL):IDEAL
HIntersectionList(L:LIST of IDEAL):IDEAL
</syntax>

    <see>Intersection</see>
    <see>IntersectionList</see>
    <see>HIntersectionList</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>list</type>

    <key>hintersection</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HIntersectionList</title>
    <short_description>intersection of ideals</short_description>

    <description>
The function <code>HIntersectionList</code> applies the function <code>HIntersection</code>
to the elements of a list, i.e., <code>HIntersectionList([I_1,...,I_n])</code> is
the same as <code>HIntersection(I_1,...,I_n)</code>.

<par/>
The coefficient ring must be a field.

        
<example>
L := [Ideal(x-z,y-2z),Ideal(x-2z,y-z)];
HIntersectionList(L);
Ideal(x + y - 3z, y^2 - 3yz + 2z^2)
------------------------------- 
</example>
    </description>

    <syntax>
HIntersectionList(L:LIST of IDEAL):IDEAL
</syntax>

    <see>Intersection</see>
    <see>IntersectionList</see>
    <see>HIntersection</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>list</type>

    <key>hintersectionlist</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Homogenized</title>
    <short_description>homogenize with respect to an indeterminate</short_description>

    <description>
This function returns the homogenization of E with respect to the
indeterminate X, which must have weight 1.  Note that in the case
where E is an ideal, <code>Homogenized</code> returns the ideal generated by the
homogenizations of all the elements of E, not just the homogenization
of the generators of E (see the example, below).  The coefficient ring
must be a field for this function to work reliably.

        
<example>
Use R ::= Q[x,y,z,w];
Homogenized(w,x^3-y);
x^3 - yw^2
-------------------------------
Homogenized(w,[x^3-y,x^4-z]);
[x^3 - yw^2, x^4 - zw^3]
-------------------------------
I := Ideal(x^3-y,x^4-z); 
Homogenized(w,I);  -- don&apos;t just get the homogenizations of
                   -- the generators of I
Ideal(x^3 - yw^2, -xy + zw, x^2z - y^2w, y^3 - xz^2)
-------------------------------
Homogenized(w,[[I,y-z^2],z-y^4]);
[[Ideal(x^3 - yw^2, -xy + zw, x^2z - y^2w, y^3 - xz^2), -z^2 + yw], -y^4 + zw^3]
------------------------------- 
</example>
    </description>

    <syntax>
Homogenized(X:INDET,E:T):T

where T is of type IDEAL or POLY, or T is a LIST recursively
constructed of types IDEAL, POLY, and LIST.
</syntax>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>polynomial</type>

    <key>homogenized</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HSaturation</title>
    <short_description>saturation of ideals</short_description>

    <description>
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 <coderef>Saturation</coderef> only when the
input is inhomogeneous, in which case, <code>HSaturation</code> may be faster.

<par/>
The coefficient ring must be a field.
        
<example>
Use R ::= Q[x,y];
I := Ideal(x^4-x, yx-2x);
Saturation(I, Ideal(x));
HSaturation(I, Ideal(x));
</example>
    </description>

    <syntax>
Saturation(I:IDEAL,J:IDEAL):IDEAL
HSaturation(I:IDEAL,J:IDEAL):IDEAL
</syntax>

    <see>Colon</see>
    <see>HColon</see>
    <see>Saturation</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>

    <key>hsaturation</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>HVector</title>
    <short_description>the h-vector of a ring or quotient object</short_description>

    <description>
This function returns the h-vector of the ring R, i.e., the
coefficients of the numerator of the simplified Poincare series for R.

<par/>
The weights of the indeterminates of the current ring 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 ::= Q[t,x,y,z];
HVector(R/Ideal(x,y,z)^5);
[1, 3, 6, 10, 15]
-------------------------------
Poincare(R/Ideal(x,y,z)^5);
(1 + 3t + 6t^2 + 10t^3 + 15t^4) / (1-t)
------------------------------- 
</example>
    </description>

    <syntax>
HVector(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):LIST
</syntax>

    <see>Hilbert</see>
    <see>HilbertSeries</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>hvector</key>
  </command>

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

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Ideal</title>
    <short_description>convert an expression into an ideal</short_description>

    <description>
The first form returns the ideal generated by <code>P_1,...P_n</code>.  The second
form returns the ideal generated by the polynomials in L.  The third
form returns the ideal generated by the polynomials in M; it is the
same as <code>Cast(M,IDEAL)</code>, and requires that the module be a submodule of
the free module of rank 1.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x-y^2,xy-z);
I;
Ideal(-y^2 + x, xy - z)
-------------------------------
L := [xy-z,x-y^2];
J := Ideal(L);
I = J;
TRUE
-------------------------------
M := Module([y^3-z],[x-y^2]);
Ideal(M) = I;
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
Ideal(P_1:POLY,...,P_n:POLY):IDEAL
Ideal(L:LIST):IDEAL
Ideal(M:MODULE):IDEAL

where L is a list of polynomials and M is contained in a free module
of rank 1.
</syntax>

    <type>cast</type>
    <type>ideal</type>

    <key>ideal</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IdealAndSeparatorsOfPoints</title>
    <short_description>ideal and separators for affine points</short_description>

    <description>
This function computes the results of <coderef>IdealOfPoints</coderef> and
<coderef>SeparatorsOfPoints</coderef> 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; and 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
<coderef>IdealAndSeparatorsOfProjectivePoints</coderef>. 

        
<example>
Use R ::= Q[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>

    <syntax>
IdealAndSeparatorsOfPoints(Points:LIST):RECORD

where Points is a list of lists of coefficients representing a set of
*distinct* points in affine space.
</syntax>

    <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>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>
    <type>record</type>

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

    <description>
This function computes the results of <coderef>IdealOfProjectivePoints</coderef> and
<coderef>SeparatorsOfProjectivePoints</coderef> 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; and 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
<coderef>IdealAndSeparatorsOfPoints</coderef>. 

        
<example>
Use R ::= Q[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]
------------------------------- 
</example>
    </description>

    <syntax>
IdealAndSeparatorsOfProjectivePoints(Points:LIST):RECORD

where Points is a list of lists of coefficients representing a set of
*distinct* points in projective space.
</syntax>

    <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>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>
    <type>record</type>

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

    <description>
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(Pts); 
     Foreach Element In Gens(I) Do
       PrintLn Element;
     EndForeach;
</verbatim>
For ideals of points in projective space, see
<coderef>IdealOfProjectivePoints</coderef>. 

        
<example>
Use R ::= Q[x,y];
Points := [[1, 2], [3, 4], [5, 6]];
I := IdealOfPoints(Points);
I;
Ideal(x - y + 1, y^3 - 12y^2 + 44y - 48)
-------------------------------
I.Gens;  -- the reduced Groebner basis
[x - y + 1, y^3 - 12y^2 + 44y - 48]
------------------------------- 
</example>
    </description>

    <syntax>
IdealOfPoints(Points:LIST):IDEAL

where Points is a list of lists of coefficients representing a set of
*distinct* points in affine space.
</syntax>

    <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>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>

    <key>idealofpoints</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IdealOfProjectivePoints</title>
    <short_description>ideal of a set of projective points</short_description>

    <description>
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 <coderef>IdealOfPoints</coderef>. 

        
<example>
Use R ::= Q[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>

    <syntax>
IdealOfProjectivePoints(Points:LIST):IDEAL

where Points is a list of lists of coefficients representing a set of
*distinct* points in projective space.
</syntax>

    <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>

    <type>groebner</type>
    <type>ideal</type>
    <type>list</type>
    <type>points</type>

    <key>idealofprojectivepoints</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Identity</title>
    <short_description>the identity matrix</short_description>

    <description>
This function returns the NxN identity matrix.

        
<example>
Identity(3);
Mat([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
------------------------------- 
</example>
    </description>

    <syntax>
Identity(N:INT):MAT
</syntax>

    <type>matrix</type>

    <key>identity</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>If</title>
    <short_description>conditional statement</short_description>

    <description>
If <code>B_n</code> is the first in the sequence of <code>B_i</code>&apos;s to evaluate to TRUE,
then <code>C_n</code> is executed.  If none of the <code>B_i</code>&apos;s evaluates to TRUE, nothing
is done.  The construct, <code>Elsif B Then C</code> can be repeated any number
of times.  Note: be careful not to type <code>Elseif</code> by mistake (it has an
extraneous <code>e</code>).

<par/>
In the last form, the single command D is performed if B evaluates to
TRUE.  NOTE: the use of this form is discouraged.  It will probably
disappear from future versions of CoCoA.

<par/>
For a conditional <code>expression</code>, assignable to a variable, see
<coderef>Cond</coderef>.

        
<example>
Define Sign(A)
  If A &gt; 0 Then Return 1
  Elsif A = 0 Then Return 0
  Else Return -1
  EndIf
End;

Sign(3);
1
------------------------------- 
</example>
    </description>

    <syntax>
If B Then C EndIf
If B_1 Then C_1 Else C_2 EndIf
If B_1 Then C_1 Elsif B_2 Then C_2 Elsif ... EndIf
If B_1 Then C_1 Elsif B_2 Then C_2 Elsif ... Else C_r EndIf

D If B

where the B&apos;s are boolean expressions, the C&apos;s are command
sequences, and D is a single command.
</syntax>

    <see>Cond</see>

    <type>programming</type>
    <type>branching</type>

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

    <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>

    <syntax>
ILogBase(X:RAT, Base:INT):INT
</syntax>

    <type>integer</type>
    <type>rat</type>

    <key>ilogbase</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Image</title>
    <short_description>ring homomorphism</short_description>

    <description>
This function maps the object E from one ring to another as
determined by F.  Suppose the current ring is S, and E is an object
dependent on a ring R; then
<verbatim>
               Image(R::E,F) 
</verbatim>
returns the object in S obtained by substituting <code>F_i</code> for the i-th
indeterminate of R in E.  Effectively, we get the image of E under
the ring homomorphism,
<verbatim>
               F: R   ---&gt;  S
                  x_i |--&gt; F_i,
</verbatim>
where <code>x_i</code> denotes the i-th indeterminate of R.

<par/>
Notes:
<par/>
1. The coefficient rings for the domain and codomain must be the same.
<par/>
2. If R = S, one may use <code>Image(E,F)</code> but in this case it may be
   easier to use <coderef>Eval</coderef> or <coderef>Subst</coderef>.
<par/>
3. The exact domain is never specified by the mapping F.  It is only
   necessary that the domain have the same number of indeterminates as F
   has components. Thus, we are abusing terminology somewhat in
   calling F a map.
<par/>
4. The second form of the function does not require the prefix <code>R::</code>
   since the prefix is associated automatically.
<par/>
5. If the object E in R is a polynomial or rational function (or list,
   matrix, or vector of these) which involves only indeterminates that are
   already in S, the object E can be mapped over to S without change
   using the command <ref>BringIn</ref>.
        
<example>
Use C ::= Q[u,v];   -- domain
Use B ::= Q[x,y];   -- another possible domain
I := Ideal(x^2-y);  -- an ideal in B
Use A ::= Q[a,b,c]; -- codomain
F := RMap(a,c^2-ab);  
Image(B::xy, F);    -- the image of xy under F:B --&gt; A
-a^2b + ac^2
-------------------------------
Image(C::uv,F);     -- the image of uv under F:C --&gt; A
-a^2b + ac^2 
-------------------------------
Image(I,F);         -- the image of the ideal I under F: B --&gt; A
Ideal(a^2 + ab - c^2)
-------------------------------
I;  -- the prefix <coc-quotes>B::</coc-quotes> was not needed in the previous example since
    -- I is already labeled by B
B :: Ideal(x^2 - y)
-------------------------------
Image(B::Module([x+y,xy^2],[x,y]),F); -- the image of a module
Module([-ab + c^2 + a, a^3b^2 - 2a^2bc^2 + ac^4], [a, -ab + c^2])
-------------------------------
X := C:: u+v;  -- X is a variable in the current ring (the codomain), A,
X;             -- whose value is an expression in the ring C.
C :: u + v
-------------------------------
Image(X,F);    -- map X to get a value in C
-ab + c^2 + a
------------------------------- 
</example>
    </description>

    <syntax>
Image(R::E:OBJECT,F:TAGGED(<coc-quotes>RMap</coc-quotes>)):OBJECT
Image(V:OBJECT,F:TAGGED(<coc-quotes>RMap</coc-quotes>)):OBJECT

where R is the identifier for a ring and F has the form
RMap(F_1:POLY,...,F_n:POLY) or the form RMap([F_1:POLY,...,F_n:POLY]).
The number n is the number of indeterminates of the ring R. In the
second form, V is a variable containing a CoCoA object dependent on R
or not dependent on any ring.
</syntax>

    <see>Accessing Other Rings</see>
    <see>BringIn</see>
    <see>QZP, ZPQ</see>
    <see>Ring Mappings: the Image Function</see>
    <see>Subst</see>
    <see>Using</see>

    <type>ring</type>

    <key>image</key>
    <key>rmap</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>In</title>
    <short_description>create a list satisfying given conditions</short_description>

    <description>
In the first form, E is an arbitrary CoCoA expression and B is a
boolean expression, both of which are functions of the variable
X. Write E(X) for E and B(X) for B.  The first listed command then
returns the list of all E(X) such that X is in the list L and B(X)
evaluates to TRUE.

        
<example>
[[X^2,X^3] | X In [-2,-1,0,1,2] And X &lt;&gt; 0];
[[4, -8], [1, -1], [1, 1], [4, 8]]
-------------------------------
[X In [1,2] &gt;&lt; [2,3,4] | X[1]+X[2]=4];
[[1, 3], [2, 2]]
------------------------------- 
</example>

(Note: the <formula>&gt;&lt;</formula> operator is used to form Cartesian products; it is not
the same as the <em>not equal</em> operator, <formula>&lt;&gt;</formula>.)

<par/>
The second form of the command is the same as the first with E = X. 

        
<example>
[X In [1,2,3] | X &gt; 1];
[2, 3]
------------------------------- 
</example>

The third form is the same as the first with B = TRUE.

        
<example>
[X^2 | X In [1,2,3]];
[1, 4, 9]
------------------------------- 
</example>
    </description>

    <syntax>
[E:OBJECT | X In L:LIST And B:BOOL]:LIST
[X In L:LIST | B:BOOL]:LIST
[E:OBJECT | X In L]

where X is a variable identifier which may occur in B or E.
</syntax>

    <see>IsIn</see>
    <see>NewList</see>
    <see>Comp</see>

    <type>list</type>

    <key>in</key>
    <key>|</key>
    <key>[</key>
    <key>[]</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Indet</title>
    <short_description>individual indeterminates</short_description>

    <description>
This function returns the N-th indeterminate of the current ring.

        
<example>
Use R ::= Q[x,y,z];
Indet(2);
y
------------------------------- 
</example>
    </description>

    <syntax>
Indet(N:INT):POLY
</syntax>

    <see>IndetInd</see>
    <see>IndetIndex</see>
    <see>IndetName</see>
    <see>Indets</see>
    <see>NumIndets</see>

    <type>ring</type>

    <key>indet</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IndetInd</title>
    <short_description>the index of an indeterminate</short_description>

    <description>
This function returns the index of the indeterminate X.

        
<example>
Use R ::= Q[x[1..3,1..2],y,z];
IndetInd(x[3,2]);
[3, 2]
-------------------------------
IndetInd(y);
[ ]
------------------------------- 
</example>
    </description>

    <syntax>
IndetInd(X:INDET):LIST
</syntax>

    <see>Indet</see>
    <see>IndetIndex</see>
    <see>IndetName</see>
    <see>Indets</see>
    <see>NumIndets</see>

    <type>ring</type>

    <key>indetind</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IndetIndex</title>
    <short_description>index of an indeterminate</short_description>

    <description>
This function returns the index of the named determinate.  The index
is determined by the order in which the indeterminate is listed when
the corresponding ring was created.

        
<example>
Use R ::= Q[x,y,z]
IndetIndex(y);
2
-------------------------------
Use R ::= Q[x[1..2,1..2],y[1..2]];
Indets();
[x[1,1], x[1,2], x[2,1], x[2,2], y[1], y[2]]
-------------------------------
IndetIndex(x[2,1]);
3
-------------------------------
S ::= Q[a,b,c];
IndetIndex(S::b);
2
------------------------------- 
</example>
    </description>

    <syntax>
IndetIndex(X:INDET):INT
</syntax>

    <see>Indet</see>
    <see>IndetInd</see>
    <see>IndetName</see>
    <see>Indets</see>
    <see>NumIndets</see>
    <see>UnivariateIndetIndex</see>

    <type>ring</type>

    <key>indetindex</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Indets</title>
    <short_description>list of current indeterminates</short_description>

    <description>
This function returns the list of indeterminates of the current ring.

        
<example>
Use R ::= Q[x,y,z];
Indets();
[x, y, z]
------------------------------- 
</example>
    </description>

    <syntax>
Indets():LIST
</syntax>

    <see>Indet</see>
    <see>IndetInd</see>
    <see>IndetIndex</see>
    <see>IndetName</see>
    <see>NumIndets</see>

    <type>ring</type>

    <key>indets</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IndetName</title>
    <short_description>the name of an indeterminate</short_description>

    <description>
This function returns the name of the indeterminate X as a string.

        
<example>
Use R ::= Q[x,y,z];
IndetName(Indet(2));
y
-------------------------------
Type(It);
STRING
------------------------------- 
</example>
    </description>

    <syntax>
IndetName(X:INDET):STRING
</syntax>

    <see>Indet</see>
    <see>IndetInd</see>
    <see>IndetIndex</see>
    <see>NumIndets</see>

    <type>ring</type>

    <key>indetname</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Insert</title>
    <short_description>insert an object in a list</short_description>

    <description>
This function inserts E into the list L as the N-th component.

        
<example>
L := [<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>,<coc-quotes>d</coc-quotes>,<coc-quotes>e</coc-quotes>];
Insert(L,3,<coc-quotes>c</coc-quotes>);
L;
[<coc-quotes>a</coc-quotes>, <coc-quotes>b</coc-quotes>, <coc-quotes>c</coc-quotes>, <coc-quotes>d</coc-quotes>, <coc-quotes>e</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Insert(V:LIST,N:INT,E:OBJECT):NULL

where V is a variable containing a list.
</syntax>

    <see>Append</see>
    <see>Remove</see>

    <type>list</type>

    <key>insert</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Interpolate</title>
    <short_description>interpolating polynomial</short_description>

    <description>
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 Q[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>

    <syntax>
Interpolate(Points:LIST,Values:LIST):POLY

where Points is a list of lists of coefficients representing a set of
*distinct* points and Values is a list of the same size containing
numbers from the coefficient ring.
</syntax>

    <type>list</type>
    <type>points</type>
    <type>polynomial</type>

    <key>interpolate</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Interreduce, Interreduced</title>
    <short_description>interreduce a list of polynomials or vectors</short_description>

    <description>
These functions reduce each polynomial (resp., vector) using the other
polynomials (resp., vectors) as reduction rules. The process
terminates when each is in normal form with respect to the
others.  The function <code>Interreduce</code> takes a variable containing a list
and overwrites that variable with the interreduced list.  The second
returns an interreduced list without affecting its arguments.

<par/>
Note that the definition of normal form depends on the current
value of the option FullRed of the panel GROEBNER.  If FullRed is FALSE
it means that a polynomial (resp., vector) is in normal form when its
leading term with respect to the current term ordering cannot be
reduced. If FullRed is TRUE it means that a polynomial (resp., vector)
is in normal form if and only if each monomial cannot be reduced.

        
<example>
UnSet FullRed;  -- FullRed = FALSE
Use R ::= Q[x,y,z];
Interreduced([x^3-xy^2+yz,xy,z]);
[x^3 - xy^2 + yz, xy, z]
-------------------------------
Set FullRed;  -- FullRed = TRUE (the default value)
Interreduced([x^3-xy^2+yz,xy,z]);
[xy, z, x^3]
-------------------------------
L := [x^3-xy^2+yz,xy,z];
Interreduce(L);
L;
[xy, z, x^3]
------------------------------- 
</example>
    </description>

    <syntax>
Interreduce(V:LIST of POLY):NULL
Interreduce(V:LIST of VECTOR):NULL

Interreduced(L:LIST of POLY):LIST of POLY
Interreduced(L:LIST of VECTOR):LIST of VECTOR

where V is a variable containing a list.
</syntax>

    <see>FullRed</see>

    <type>ideal</type>
    <type>module</type>
    <type>list</type>

    <key>interreduce</key>
    <key>interreduced</key>
    <key>interreduce, interreduced</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Intersection</title>
    <short_description>intersect lists, ideals, or modules</short_description>

    <description>
The function <code>Intersection</code> returns the intersection of <code>E_1,...,E_n</code>.
In the case where the <code>E_i</code>&apos;s are lists, it returns the elements common
to all of the lists.

<par/>
The coefficient ring must be a field.

<par/>
NOTE: In order to compute the intersection of inhomogeneous ideals, it
may be faster to use the function <code>HIntersection</code>.  To compute the
intersection of ideals corresponding to zero-dimensional schemes, see
the commands <coderef>GBM</coderef> and <coderef>HGBM</coderef>.

        
<example>
Use R ::= Q[x,y,z];
Points := [[0,0],[1,0],[0,1],[1,1]]; -- a list of points in the plane
I := Ideal(x,y); -- the ideal for the first point
Foreach P In Points Do
  I := Intersection(I,Ideal(x-P[1]z,y-P[2]z));
EndForeach;
I;  -- the ideal for (the projective closure of) Points
Ideal(y^2 - yz, x^2 - xz)
-------------------------------
Intersection([<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>,<coc-quotes>c</coc-quotes>],[<coc-quotes>b</coc-quotes>,<coc-quotes>c</coc-quotes>,<coc-quotes>d</coc-quotes>]);
[<coc-quotes>b</coc-quotes>, <coc-quotes>c</coc-quotes>]
-------------------------------
It = Intersection(Ideal(x,y),Ideal(y^2,z));
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
Intersection(E_1:LIST,....,E_n:LIST):LIST
Intersection(E_1:IDEAL,...,E_n:IDEAL):IDEAL
Intersection(E_1:MODULE,....,E_n:MODULE):MODULE
</syntax>

    <see>GBM</see>
    <see>HGBM</see>
    <see>IntersectionList</see>
    <see>HIntersection</see>
    <see>HIntersectionList</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>list</type>
    <type>module</type>

    <key>intersection</key>
    <key>intersectionlist</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IntersectionList</title>
    <short_description>intersect lists, ideals, or modules</short_description>

    <description>
The function <code>IntersectionList</code> applies the function <code>Intersection</code> to
the elements of a list, i.e., <code>IntersectionList([X_1,...,X_n])</code> is the
same as <code>Intersection(X_1,...,X_n)</code>.

<par/>
The coefficient ring must be a field.

<par/>
NOTE: In order to compute the intersection of inhomogeneous ideals, it
may be faster to use the function <code>HIntersectionList</code>.  

To compute the intersection of ideals corresponding to
zero-dimensional schemes, see the commands <coderef>GBM</coderef> and <coderef>HGBM</coderef>.

        
<example>
Use R ::= Q[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 - yz, x^2 - xz)
-------------------------------
Intersection([<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>,<coc-quotes>c</coc-quotes>],[<coc-quotes>b</coc-quotes>,<coc-quotes>c</coc-quotes>,<coc-quotes>d</coc-quotes>]);
[<coc-quotes>b</coc-quotes>, <coc-quotes>c</coc-quotes>]
-------------------------------
IntersectionList([Ideal(x,y),Ideal(y^2,z)]);
Ideal(yz, xz, y^2)
-------------------------------
It = Intersection(Ideal(x,y),Ideal(y^2,z));
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IntersectionList(L:LIST of LIST):LIST
IntersectionList(L:LIST of IDEAL):IDEAL
IntersectionList(L:LIST of MODULE):MODULE
</syntax>

    <see>IdealOfProjectivePoints</see>
    <see>IdealOfPoints</see>
    <see>HGBM</see>
    <see>HIntersection</see>
    <see>HIntersectionList</see>
    <see>Intersection</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>list</type>
    <type>module</type>

    <key>intersection</key>
    <key>intersectionlist</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Inverse</title>
    <short_description>multiplicative inverse</short_description>

    <description>
This function computes the multiplicative inverse of its argument.
It is included for use when writing Inverse(X) comes more naturally
than writing <code>X^(-1)</code>, though both notations are functionally equivalent.

        
<example>
Inverse(Mat([[1,2], [3,4]]));
Mat([
  [-2, 1],
  [3/2, -1/2]
])
------------------------------- 
</example>
    </description>

    <syntax>
Inverse(X:OBJECT):OBJECT
</syntax>

    <type>integer</type>
    <type>matrix</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>
    <type>zmod</type>

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

    <description>
This function works like <coderef>Sprint</coderef>, 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 <code>...</code> is concatenated.  This
function is useful in formatting reports of results.

        
<example>
Use R ::= Q[xy];
I := Ideal(x,y);
IO.SprintTrunc(I,4);
Idea...
------------------------------- 
</example>
    </description>

    <syntax>
IO.SprintTrunc(E:OBJECT,N:INT):STRING
</syntax>

    <see>Format</see>
    <see>Sprint</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>io.sprinttrunc</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Iroot</title>
    <short_description>integer part of r-th root of an integer</short_description>

    <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>

    <syntax>
Iroot(N:INT, R: INT):INT
</syntax>

    <see>ILogBase</see>

    <type>integer</type>

    <key>iroot</key>
  </command>

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

    <description>
This function returns TRUE if E is defined, otherwise it returns
false.  Typically, it is used to check if a name has already been
assigned.

NOTE: this function used to be named <code>Defined</code>.

        
<example>
IsDefined(MyVariable);
FALSE
-------------------------------
MyVariable := 3;
IsDefined(MyVariable);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsDefined(E)

where E is a CoCoA expression.
</syntax>

    <type>memory</type>
    <type>boolean</type>

    <key>isdefined</key>
  </command>

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

    <description>
These functions test whether an integer is even or odd. 

        
<example>
IsEven(3);
FALSE
-------------------------------
IsOdd(3);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsEven(N:INT):BOOL
IsOdd(N:INT):BOOL
</syntax>

    <see>IsZero</see>

    <type>boolean</type>
    <type>integer</type>

    <key>iseven</key>
    <key>isodd</key>
    <key>iseven, isodd</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsHomog</title>
    <short_description>test whether given polynomials are homogeneous</short_description>

    <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.

        
<example>
Use R ::= Q[x,y];
IsHomog(x^2-xy);
TRUE
-------------------------------
IsHomog(x-y^2);
FALSE
-------------------------------
IsHomog([x^2-xy,x-y^2]);
FALSE
------------------------------
Use R ::= Q[x,y],Weights(Mat([[2,3],[1,2]]));
IsHomog(x^3y^2+y^4);
TRUE
-------------------------------
Use R ::= Q[x,y];
IsHomog(Ideal(x^2+y,y));
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsHomog(F:POLY or VECTOR):BOOL
IsHomog(L:LIST):BOOL
IsHomog(I:IDEAL or MODULE):BOOL
</syntax>

    <see>Deg</see>
    <see>MDeg</see>
    <see>Weights Modifier</see>

    <type>boolean</type>
    <type>polynomial</type>

    <key>ishomog</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsIn</title>
    <short_description>check if one object is contained in another</short_description>

    <description>
The semantics of IsIn is explained in the following table:
<verbatim>
    ----------------------------------------------------------------
   | POLY   IsIn  IDEAL   checks for ideal membership.              |
   | VECTOR IsIn  MODULE  checks for module membership.             |
   | OBJECT IsIn  LIST    checks if the list contains the object.   |
   | STRING IsIn  STRING  checks if the first string is a substring |
   |                      of the second one.                        |
    ----------------------------------------------------------------
                       IsIn operator
</verbatim>
    </description>

    <syntax>
E IsIn F

where E and F are CoCoA objects.  For a precise description of
allowable objects, see the full online help entry.
</syntax>

    <type>boolean</type>
    <type>ideal</type>
    <type>list</type>
    <type>module</type>
    <type>polynomial</type>
    <type>string</type>
    <type>vector</type>

    <key>isin</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsNumber</title>
    <short_description>checks if the argument is a number</short_description>

    <description>
This function returns TRUE if E has type INT, RAT, or ZMOD.
Otherwise, it returns FALSE.

        
<example>
Use R ::= Q[x,y];
IsNumber(x+y);
FALSE
-------------------------------
IsNumber(3);
TRUE
-------------------------------
IsNumber(3%5);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsNumber(E:OBJECT):BOOL
</syntax>

    <type>boolean</type>
    <type>integer</type>
    <type>rat</type>
    <type>zmod</type>

    <key>isnumber</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsPositiveGrading</title>
    <short_description>check if a matrix defines a positive grading</short_description>

    <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(Mat([[0,2,3], [1, -1, 0]]));
TRUE
-------------------------------
IsPositiveGrading(Mat([[1,1], [0,-1], [-1, 0]]));
TRUE
-------------------------------
</example>
    </description>

    <syntax>
IsPositiveGrading(M:MAT):BOOL
</syntax>

    <see>HilbertSeriesMultiDeg</see>
    <see>PositiveGrading4</see>

    <type>matrix</type>
    <type>boolean</type>

    <key>ispositivegrading</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsPPrime</title>
    <short_description>checks if an integer is a probable prime</short_description>

    <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>
IsPPrime(2);
TRUE
-------------------------------
IsPPrime(1111111111111111111);
TRUE
-------------------------------
[N In 1..1111 | IsPPrime((10^N-1)/9)]; -- only five values are known
[2, 19, 23, 317, 1031]                 -- next might be 49081
-------------------------------
</example>
    </description>

    <syntax>
IsPPrime(N:INT):BOOL 
</syntax>

    <see>IsPrime</see>
    <see>NextPPrime</see>

    <type>boolean</type>
    <type>integer</type>

    <key>ispprime</key>
    <key>primality test</key>
    <key>compositeness test</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsPrime</title>
    <short_description>prime integer test</short_description>

    <description>
This function determines whether a small integer is prime.
The range of permitted values for N is the same the range
of permitted values for the NextPrime function: on most
platforms <formula>N <less_eq/> 45000</formula> should work fine, on some platforms
considerably larger values will work.
For N greater than the limit an error is raised.


        
<example>
IsPrime(32003);
TRUE
-------------------------------
IsPrime(10^100);
ERROR: IsPrime: number too large
CONTEXT: Return(Error(<coc-quotes>IsPrime: number too large</coc-quotes>))
------------------------------- 
</example>
    </description>

    <syntax>
IsPrime(N:INT):BOOL
</syntax>

    <see>IsPPrime</see>
    <see>NextPrime</see>

    <type>integer</type>
    <type>boolean</type>

    <key>isprime</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsTermOrdering</title>
    <short_description>check if a matrix defines a term-ordering</short_description>

    <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(DegRevLexMat(5));
TRUE
-------------------------------
IsTermOrdering(RevLexMat(5));
FALSE
-------------------------------
</example>
    </description>

    <syntax>
IsTermOrdering(M:MAT):BOOL
</syntax>

    <see>Custom Term-Orderings</see>

    <type>matrix</type>
    <type>boolean</type>

    <key>istermordering</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Isqrt</title>
    <short_description>computes the (truncated) square root of an integer</short_description>

    <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: Expected non-negative INT
CONTEXT: Isqrt(-1)
------------------------------- 
</example>
    </description>

    <syntax>
Isqrt(N:INT):INT
</syntax>

    <type>integer</type>
    <type>boolean</type>

    <key>isqrt</key>
    <key>square root</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsStable, IsStronglyStable, IsLexSegment</title>
    <short_description>checks if an ideal is stable (resp. strongly stable or a lex-segment)</short_description>

    <description>
These functions return whether the monomial ideal I is stable,
strongly stable (Borel-fixed in characteristic 0), or a lex-segment
ideal.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(xy^3, y^4, x^3, x^2y, x^2z);
IsStable(I);
TRUE
-------------------------------
IsStronglyStable(I);
TRUE
-------------------------------
IsLexSegment(I);
FALSE
------------------------------- 
</example>
    </description>

    <syntax>
IsStable(I: MONOMIAL IDEAL): BOOL
IsStronglyStable(I: MONOMIAL IDEAL): BOOL
IsLexSegment(I: MONOMIAL IDEAL): BOOL
</syntax>

    <type>ideal</type>
    <type>boolean</type>

    <key>isstable</key>
    <key>isstronglystable</key>
    <key>islexsegment</key>
    <key>borel</key>
    <key>isstable, isstronglystable, islexsegment</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsSubset</title>
    <short_description>checks if the elements of one list are a subset of another</short_description>

    <description>
This function returns TRUE is Set(L) is contained in Set(M);
otherwise it returns FALSE.

<par/>
NOTE: The obsolete function SubSet used to have the same behaviour.

        
<example>
IsSubset([1,1,2],[1,2,3,<coc-quotes>a</coc-quotes>]);
TRUE
-------------------------------
IsSubset([1,2],[<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>]);
FALSE
-------------------------------
IsSubset([],[1,2]);
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsSubset(L:LIST,M:LIST):BOOL
</syntax>

    <see>EqSet</see>
    <see>Set</see>
    <see>Subsets</see>

    <type>boolean</type>
    <type>list</type>

    <key>issubset</key>
    <key>subset</key>
    <key>subset, issubset</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsTerm</title>
    <short_description>checks if the argument is a term</short_description>

    <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>xy^2z</formula> is a term, while <formula>4xy^2z</formula> and <formula>xy+2z^3</formula> are not.  For a vector, a
term is a power-product times a standard basis vector, e.g.,
<formula>(0,xy^2z,0)</formula>.

        
<example>
Use R ::= Q[x,y,z];
IsTerm(x+y^2);
FALSE
-------------------------------
IsTerm(x^3yz^2);
TRUE
-------------------------------
IsTerm(5x^3yz^2);
FALSE
-------------------------------
IsTerm(Vector(0,0,xyz));
TRUE
-------------------------------
IsTerm(Vector(x^2,y^2));
FALSE
-------------------------------
IsTerm(5x^2);
FALSE
------------------------------- 
</example>
    </description>

    <syntax>
IsTerm(X:POLY or VECTOR):BOOL
</syntax>

    <type>polynomial</type>
    <type>vector</type>
    <type>boolean</type>

    <key>isterm</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>IsZero</title>
    <short_description>test whether an object is zero</short_description>

    <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 ::= Q[x,y];
IsZero(x^2+3y-1);
FALSE
-------------------------------
IsZero(Ideal(x^2,xy^3));
FALSE
-------------------------------
IsZero(Vector(0,0,0));
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
IsZero(X:OBJECT):BOOL
</syntax>

    <see>IsEven, IsOdd</see>

    <type>boolean</type>
    <type>ideal</type>
    <type>integer</type>
    <type>matrix</type>
    <type>module</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>
    <type>vector</type>
    <type>zmod</type>

    <key>iszero</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>J</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Jacobian</title>
    <short_description>the Jacobian of a list of polynomials</short_description>

    <description>
This function returns the Jacobian matrix of the polynomials in L
with respect to all the indeterminates of the current ring.

        
<example>
Use R ::= Q[x,y];
L := [x-y,x^2-y,x^3-y^2];
Jacobian(L);
Mat([
  [1, -1],
  [2x, -1],
  [3x^2, -2y]
])
------------------------------- 
</example>
    </description>

    <syntax>
Jacobian(L:LIST):MAT

where L is a list of polynomials.
</syntax>

    <type>polynomial</type>
    <type>matrix</type>

    <key>jacobian</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>K</chapter_name>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>L</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Last</title>
    <short_description>the last N elements of a list</short_description>

    <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.

        
<example>
L := [1,2,3,4,5];
Last(L);
5
-------------------------------
Last(L,3);
[3, 4, 5]
------------------------------- 
</example>
    </description>

    <syntax>
Last(L:LIST):OBJECT
Last(L:LIST,N:INT):OBJECT
</syntax>

    <see>First</see>
    <see>Head</see>
    <see>Tail</see>

    <type>list</type>

    <key>last</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Latex</title>
    <short_description>LaTeX formatting</short_description>

    <description>
This function returns its argument in a format suitable for inclusion
in a LaTeX document.

        
<example>
Use R ::= Q[x,y,z];
F := x^3+2y^2z;
Latex(F);
x^{3} + 2y^{2}z
-------------------------------
M := Mat([[1,2],[3,4]]);
Latex(M);
 \left( \begin{array}{ll} 
1 &amp; 2 \\ 
3 &amp; 4 \end{array}\right) 

-------------------------------
F := (x+y)/(1-z)^3;
Latex(F);
\frac{ - x - y}{z^{3}-3z^{2} + 3z-1}
-------------------------------
Latex(Ideal(x^2,y+z));
( \ x^{2}, 
y + z\ )
------------------------------- 
</example>
    </description>

    <syntax>
Latex(X:OBJECT):TAGGED(<coc-quotes><code>$latex.Latex</code></coc-quotes>)
</syntax>

    <see>Format</see>
    <see>Sprint</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>latex</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LC</title>
    <short_description>the leading coefficient of a polynomial or vector</short_description>

    <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 ::= Q[x,y];
LC(x+3x^2-5y^2);
3
-------------------------------
LC(Vector(0,5y+6x^2,y^2));
6
------------------------------- 
</example>
    </description>

    <syntax>
LC(F:POLY or VECTOR):C

where C is one of INT, RAT, or ZMOD.
</syntax>

    <see>Coefficients</see>
    <see>CoeffOfTerm</see>
    <see>LT</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>lc</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LCM</title>
    <short_description>least common multiple</short_description>

    <description>
This function returns the least common multiple of <code>F_1,...,F_n</code>
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 ::= Q[x,y];
F := x^2-y^2;
G := (x+y)^3;
LCM(F,G);
1/4x^4 + 1/2x^3y - 1/2xy^3 - 1/4y^4
-------------------------------
4 * It = G * (x-y);
TRUE
-------------------------------
LCM(3*4,3*8,6*16);
96
-------------------------------
LCM([3*4,3*8,6*16]);
96
------------------------------- 
</example>
    </description>

    <syntax>
LCM(F_1:INT,...,F_n:INT):INT
LCM(L:LIST of INT):INT

LCM(F_1:POLY,...,F_n:POLY):POLY
LCM(L:LIST of POLY):POLY
</syntax>

    <see>Div</see>
    <see>Mod</see>
    <see>GCD</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>integer</type>
    <type>polynomial</type>

    <key>lcm</key>
    <key>least common multiple</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Len</title>
    <short_description>the length of an object</short_description>

    <description>
This function returns the <em>length</em> of an object, as summarized in
the table below:
<verbatim>
      ----------------------------------------------
     | type   | length                              |
     -----------------------------------------------| 
     | IDEAL  | length of Gens(E)                   |
     | INT    | 1                                   |
     | LIST   | number of items in the list         |
     | MAT    | number of rows of the matrix        |
     | MODULE | length of Gens(E)                   |
     | POLY   | number of monomials                 |
     | RATFUN | if E=F/G, then Len(E)=Len(F)+Len(G) |
     | VECTOR | number of components                |
      ----------------------------------------------
               The operator <code>Len</code>
</verbatim>

        
<example>
Use R ::= Q[x,y];
L := [<coc-quotes>a</coc-quotes>,2,3,[4,5]];
Len(L);
4
-------------------------------
Len(L[1]);
1
-------------------------------
Len(L[4]);
2
-------------------------------
Len(x^2 + xy + y^2 + xy^4);
4
-------------------------------
Len((x^2+y^2)/(x+y+y^2));
5
-------------------------------
Len((x+y) - (xy/x));
1
-------------------------------
Len(Ideal(x,x^2));
2
------------------------------- 
</example>
The function <coderef>Size</coderef> returns the amount of memory used by the object.
    </description>

    <syntax>
Len(E:OBJECT):INT
</syntax>

    <see>Count</see>
    <see>Size</see>

    <type>ideal</type>
    <type>integer</type>
    <type>list</type>
    <type>matrix</type>
    <type>module</type>
    <type>polynomial</type>
    <type>ratfun</type>
    <type>vector</type>

    <key>len</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LexMat</title>
    <short_description>matrices for std. term-orderings</short_description>

    <description>
This function return the matrix defining a standard term-ordering.
These functions return matrices defining standard term-orderings.

        
<example>
LexMat(3);
Mat([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
------------------------------- 
</example>
    </description>

    <syntax>
LexMat(N:INTEGER):MAT
</syntax>

    <see>Ord</see>
    <see>Orderings</see>
    <see>DegLexMat</see>
    <see>DegRevLexMat</see>
    <see>RevLexMat</see>
    <see>XelMat</see>

    <type>matrix</type>

    <key>lexmat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LinearSimplify</title>
    <short_description>find simplifying substitution for a univariate polynomial over Q</short_description>

    <description>
This function returns a list of two polynomials [G,L] where L is linear
and G is simple (in a heuristic sense).  The composition G(L) is equal
the univariate polynomial given to LinearSimplify.

        
<example>
Use Q[x];
LinearSimplify((123*x-456)^9-1);
[x^9 - 1, 123x - 456]
-------------------------------
LinearSimplify(x^9-1); -- the heuristic finds no useful simplification
[x^9 - 1, x]
-------------------------------

</example>
    </description>

    <syntax>
LinearSimplify(F:POLY):[POLY,POLY]
</syntax>

    <type>poly</type>

    <key>linearsimplify</key>
    <key>linear simplify</key>
    <key>simplification</key>
    <key>simplifying substitution</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LinKer</title>
    <short_description>find the kernel of a matrix</short_description>

    <description>
The first function returns a list whose components are lists
representing a Z-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/>
The second 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]]);
LinKer(M);
[[1, -1, -1, 1], [0, 1, -2, 1]]
-------------------------------
M*Transposed(Mat(It));
Mat([
  [0, 0],
  [0, 0],
  [0, 0]
])
-------------------------------
Use Z/(3)[x];
LinKerModP(M);
[[1, 1, 1, 0], [0, -1, -1, -1]]
-------------------------------
M*Transposed(Mat(It));

Mat([
  [0, 0],
  [0, 0],
  [0, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
LinKer(M:MAT):LIST
LinKerModP(M:MAT):LIST

where M is a matrix over Q or Z.
</syntax>

    <see>LinSol</see>

    <type>matrix</type>

    <key>linear kernel</key>
    <key>linker</key>
    <key>nullspace</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LinSol</title>
    <short_description>find a solution to a linear system</short_description>

    <description>
This function finds a solution to the inhomogeneous system of
equations represented by M and L.  Specifically, it returns a list, X,
of length n with entries in Z or Q, such that M*Transposed(Mat(X)) =
Transposed(Mat([L])), if such X exists; otherwise, it returns the
empty list.  Once a solution is found, all solutions may be found
using the function <code>LinKer</code>.

<par/>
NOTE: <coderef>LinSol</coderef> can solve several inhomogeneous systems at once.  If L
has the form <formula>[L_1,...,L_k]</formula> where each <formula>L_i</formula> is a list of length m with
entries in Z or Q, then LinSol(M,L) returns a list <formula>[X_1,...,X_k]</formula> where
<formula>X_i</formula> is a solution to the system of linear equations represented by M
and <formula>L_i</formula>.

        
<example>
M := Mat([[3,1,4],[1,5,9],[2,6,5]]);
L := [123,456,789];
LinSol(M,L);
[199/5, 742/5, -181/5]
-------------------------------
M*Transposed(Mat([It]));
Mat([
  [123],
  [456],
  [789]
])
-------------------------------
LinSol(M,[L,[1,2,3]]);
[[199/5, 742/5, -181/5], [4/15, 7/15, -1/15]]
------------------------------- 
</example>
    </description>

    <syntax>
LinSol(M:MAT,L:LIST):LIST

where M is an m x n matrix over Z or Q, and L is a list of length m
with entries in Z or Q (or a list of such lists).
</syntax>

    <see>LinKer</see>

    <type>matrix</type>

    <key>linear solve</key>
    <key>linsol</key>
    <key>solve</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>List</title>
    <short_description>convert an expression into a list</short_description>

    <description>
This function converts the expression E into a list.  It
is the same as Cast(E,LIST).

        
<example>
Use R ::= Q[x,y];
M:=Jacobian([x^2y^2,x+y]);
M;
Mat([
  [2xy^2, 2x^2y],
  [1, 1]
])
-------------------------------
Head(M);

-------------------------------
ERROR: Bad parameters
CONTEXT: Head(M)
-------------------------------
Head(List(M));
[2xy^2, 2x^2y]
------------------------------- 
</example>

The error occurs because the function <coderef>Head</coderef> only accepts lists as
arguments.
    </description>

    <syntax>
List(E:OBJECT):LIST

where E has type LIST, MAT, or VECTOR.
</syntax>

    <see>NewList</see>

    <type>list</type>
    <type>matrix</type>
    <type>vector</type>

    <key>list</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LM</title>
    <short_description>the leading monomial of a polynomial or vector</short_description>

    <description>
This function returns the leading monomial of P.  The monomial
includes the coefficient.  To get the leading term of P, (which does
not included the coefficient), use <coderef>LT</coderef>.

        
<example>
Use R ::= Q[x,y];
LM(3x^2y+y);
3x^2y
-------------------------------
LM(Vector(2x,y));
Vector(2x, 0)
-------------------------------
LT(Vector(2x,y));
Vector(x, 0)
------------------------------- 
</example>
    </description>

    <syntax>
LM(P:POLY or VECTOR):same type as P
</syntax>

    <see>LC</see>
    <see>LPP</see>
    <see>LT</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>lm</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Log</title>
    <short_description>the list of exponents of the leading term of a polynomial</short_description>

    <description>
This function returns the list of exponents of the leading term of F.

        
<example>
Use R ::= Q[x,y,z];
F := x^3y^2z^5+x^2y+xz^4;
Log(F);
[3, 2, 5]
------------------------------- 
</example>
    </description>

    <syntax>
Log(F:POLY):LIST
</syntax>

    <see>ILogBase</see>
    <see>LT</see>
    <see>LogToTerm</see>

    <type>polynomial</type>

    <key>log</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LogToTerm</title>
    <short_description>returns a monomial (power-product) with given exponents</short_description>

    <description>
This function returns the power-product whose list of exponents is L.

        
<example>
Use R ::= Q[x,y,z];
LogToTerm([2,3,5]);
x^2y^3z^5
-------------------------------
Log(It);
[2, 3, 5]
------------------------------- 
</example>
    </description>

    <syntax>
LogToTerm(L:LIST):POLY

where L is a list of integers.
</syntax>

    <see>Log</see>

    <type>polynomial</type>

    <key>logtoterm</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LPos</title>
    <short_description>the position of the leading power-product in a vector</short_description>

    <description>
This function returns the position of the leading power-product of V.

        
<example>
Use R ::= Q[x,y],ToPos;  -- ToPos is the default module term-ordering
LT(Vector(x,y^2));
Vector(0, y^2)
-------------------------------
LPP(Vector(x,y^2));
y^2
-------------------------------
LPos(Vector(x,y^2));
2
-------------------------------
Use R ::= Q[x,y],PosTo;
LT(Vector(x,y^2));
Vector(x, 0)
-------------------------------
LPP(Vector(x,y^2));
x
-------------------------------
LPos(Vector(x,y^2));
1
------------------------------- 
</example>
    </description>

    <syntax>
LPos(V:VECTOR):INT
</syntax>

    <see>LM</see>
    <see>LPP</see>
    <see>LT</see>

    <type>vector</type>

    <key>lpos</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LPP</title>
    <short_description>the leading power-product of a polynomial or vector</short_description>

    <description>
This function returns the leading power-product of P.

        
<example>
Use R ::= Q[x,y];
LPP(3x^2y+y);  -- LPP is the same as LT for polynomials
x^2y
-------------------------------
LPP(Vector(2x,y));
x
-------------------------------
LT(Vector(2x,y));  -- Note the difference between LPP and LT
                   -- for vectors.
Vector(x, 0)
------------------------------- 
</example>
    </description>

    <syntax>
LPP(P:POLY or VECTOR):POLY
</syntax>

    <see>LC</see>
    <see>LM</see>
    <see>LT</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>lpp</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>LT</title>
    <short_description>the leading term of an object</short_description>

    <description>
If E is a polynomial this function returns the leading term of the
polynomial E with respect to the term-ordering of the current ring.
For the leading monomial, which includes the coefficient, use <coderef>LM</coderef>.

        
<example>
Use R ::= Q[x,y,z];  -- the default term-ordering is DegRevLex
LT(y^2-xz);
y^2
-------------------------------
Use R ::= Q[x,y,z], Lex;
LT(y^2-xz);
xz
------------------------------- 
</example>

If E is a vector, LT(E) gives the leading term of E with respect to
the module term-ordering of the current ring.  For the leading
monomial, which includes the coefficient, use <coderef>LM</coderef>.

        
<example>
Use R ::= Q[x,y];
V := Vector(0,x,y^2);
LT(V); -- the leading term of V w.r.t. the default term-ordering, ToPos
Vector(0, 0, y^2)
-------------------------------
Use R ::= Q[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 E is an ideal or module, LT(E) 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 ::= Q[x,y,z];
I := Ideal(x-y,x-z^2);
LT(I);
Ideal(x, z^2)
------------------------------- 
</example>
    </description>

    <syntax>
LT(E):same type as E

where E has type IDEAL, MODULE, POLY, or VECTOR.
</syntax>

    <see>LC</see>
    <see>LM</see>
    <see>LPP</see>
    <see>Module Orderings</see>
    <see>Orderings</see>

    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>leading term</key>
    <key>lt</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>M</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Man</title>
    <short_description>search online help system</short_description>

    <description>
The <code>Man</code> function is used to search the online help system for
information matching a keyword.  See <coderef>?</coderef> for more
details.  (The command <code>?</code> was introduced in CoCoA 4.2 and
is intended to replace <code>Man</code>.)
        
<example>
Man("po");

See:
  Commands and Functions for Polynomials
  DensePoly
  EquiIsoDec
  Evaluation of Polynomials
  Factoring Polynomials

            --&gt; Output suppressed  &lt;--

Man("for poly");

============ Commands and Functions for Polynomials =============

The following are commands and functions for polynomials:

            --&gt; Output suppressed  &lt;-- 
</example>

    </description>

    <syntax>
Man(S:STRING):NULL
Man(S:STRING,N:INT):NULL

where <em>S</em> is a literal string and N = 0 or 1.
</syntax>

    <see>?</see>
    <see>H.Commands</see>
    <see>H.Syntax</see>

    <type>help</type>
    <type>online-help</type>

    <key>? man</key>
    <key>help</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MantissaAndExponent</title>
    <short_description>convert rational number to a float</short_description>

    <description>
This function converts a rational number into a Record with
components named Mantissa and Exponent.  The value of the Exponent
field is the unique integer E such that 
<formula>1 <less_eq/> X*10^E <less_eq/> 10</formula>, and the
value of Mantissa is the nearest integer to <formula>(X*10^E)*10^(Prec-1)</formula>.
As an exception the case of X=0 always produces zero values for
both components of the record.

        
<example>
FloatStr(1/2);         -- trailing zeroes are not suppressed
5.000000000*10^(-1)
-------------------------------
MantissaAndExponent(1/2,3);           --  1/2 = 5.00*10^(-1)
Record[Exponent = -1, Mantissa = 500]
-------------------------------
MantissaAndExponent(0.9999, 3);       --  0.9999 rounds up to give 1.00
Record[Exponent = 0, Mantissa = 100]
------------------------------- 
</example>
    </description>

    <syntax>
MantissaAndExponent(X:RAT, Prec:INT):RECORD
</syntax>

    <see>DecimalStr</see>
    <see>FloatApprox</see>
    <see>FloatStr</see>

    <type>rat</type>
    <type>string</type>

    <key>mantissaandexponent</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MapDown</title>
    <short_description>convert a constant polynomial to a number</short_description>

    <description>
This function converts a constant polynomial to the equivalent
coefficient.  If the argument is not a constant polynomial, an error
is signalled.

        
<example>
Use Q[x,y,z];
Type((x+1)^2 - x*(x+2));    -- value is seen as a polynomial
POLY
-------------------------------
MapDown((x+1)^2 - x*(x+2)); -- attempt to map down to the coeff ring
1
-------------------------------
Type(It);                   -- value is now simply a coefficient
RAT
-------------------------------
MapDown((x+1)^2 - x^2);     -- 2*x + 1 is not a coefficient
ERROR: Cannot MapDown non-const poly
CONTEXT: Error(<coc-quotes>Cannot MapDown non-const poly</coc-quotes>)
------------------------------- 
</example>
    </description>

    <syntax>
MapDown(F:POLY):RAT or ZMOD
</syntax>

    <type>polynomial</type>

    <key>mapdown</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Mat</title>
    <short_description>convert an expression into a matrix</short_description>

    <description>
This function converts the expression E into a matrix.  The first form
is equivalent to Cast(E,MAT).

        
<example>
Use R ::= Q[x,y];
L := [[1,2],[3,4]];
Mat(L);
Mat([
  [1, 2],
  [3, 4]
])
-------------------------------
M := Module([x,x^2,y],[x^2,y,0]);
Mat(M);
Mat([
  [x, x^2, y],
  [x^2, y, 0]
])
-------------------------------
Mat([[1,2],[3,4]]);
Mat([
  [1, 2],
  [3, 4]
])
-------------------------------
Mat[[1,2],[3,4]];    -- only square brackets: deprecated!
Mat([
  [1, 2],
  [3, 4]
])
-------------------------------
M:=Mat([[<coc-quotes>a</coc-quotes>,<coc-quotes>b</coc-quotes>],[<coc-quotes>c</coc-quotes>,[1,2]]]);  -- a slightly more obscure example
N:=Mat([[<coc-quotes>d</coc-quotes>,<coc-quotes>e</coc-quotes>],[<coc-quotes>f</coc-quotes>,[3,4]]]);
M+N;
Mat([
  [<coc-quotes>ad</coc-quotes>, <coc-quotes>be</coc-quotes>],
  [<coc-quotes>cf</coc-quotes>, [4, 6]]
])
------------------------------- 
</example>
    </description>

    <syntax>
Mat(E):MAT
Mat[E]:MAT -- deprecated!

where E is either: a <em>rectangular</em> lists of lists, a vector, or a
module.
</syntax>

    <see>BlockMatrix</see>
    <see>NewMat</see>

    <type>list</type>
    <type>matrix</type>
    <type>vector</type>

    <key>mat</key>
    <key>matrix</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MatConcatHor</title>
    <short_description>create a simple block matrix</short_description>

    <description>
This function creates a simple block matrix.  The two entries are
matrices (or lists cast-able to a matrix) with the same number of
rows.  MatrixConcatHor(A,B) will return a matrix of the form
<verbatim>
                | A B |
</verbatim>

        
<example>
A := [[1,2,3], [4,5,6]];
B := [[101,102], [103,104]];

MatConcatHor(A,B);
Mat([
  [1, 2, 3, 101, 102],
  [4, 5, 6, 103, 104]
])
------------------------------- 
</example>
    </description>

    <syntax>
MatConcatHor(A:LIST,MAT, B:LIST,MAT):MAT

where A and B have the same number of rows
</syntax>

    <type>list</type>
    <type>matrix</type>

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

    <description>
This function creates a simple block matrix.  The two entries are
matrices (or lists cast-able to a matrix) with the same number of
columns.  MatConcatVer(A,B) will return a matrix of the form
<verbatim>
                | A |
                | B |
</verbatim>

        
<example>
A := [[1,2,3], [4,5,6]];
B := [[101,102,103]];

MatConcatVer(A,B);
Mat([
  [1, 2, 3],
  [4, 5, 6],
  [101, 102, 103]
])
------------------------------- 
</example>
    </description>

    <syntax>
MatConcatVer(A:LIST,MAT, B:LIST,MAT):MAT

where A and B have the same number of columns
</syntax>

    <type>list</type>
    <type>matrix</type>

    <key>matconcatver</key>
    <key>extend columns</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Max, Min</title>
    <short_description>a maximum or minimum element of a sequence or list</short_description>

    <description>
In the first form, these functions return a maximum and minimum,
respectively, of <formula>E_1,...,E_n</formula>.  In the second form, they return a
maximum and minimum, respectively, of the objects in the list L.

        
<example>
Max([1,2,3]);
3
-------------------------------
Max(1,2,3);
3
-------------------------------
Min(1,2,3);
1
-------------------------------
Use R ::= Q[x,y,z];
Max(x^3z, x^2y^2); -- x^2y^2 &gt; x^3z in the default ordering, DegRevLex
x^2y^2
-------------------------------
Min(x^3z, x^2y^2);
x^3z
-------------------------------
Use R ::= Q[x,y,z], DegLex;
Max(x^3z, x^2y^2); -- x^3z &gt; x^2y^2 in DegLex
x^3z 
-------------------------------
Max(Ideal(x),Ideal(x^2),Ideal(x,y),Ideal(x-2,y-1));  -- ordered by inclusion
                        -- a maximal element in the list is returned
Ideal(x, y)
------------------------------- 
</example>
    </description>

    <syntax>
Max(E_1:OBJECT,...,E_n:OBJECT):OBJECT
Min(E_1:OBJECT,...,E_n:OBJECT):OBJECT

Max(L:LIST):OBJECT
Min(L:LIST):OBJECT
</syntax>

    <see>Relational Operators</see>

    <type>integer</type>
    <type>ideal</type>
    <type>list</type>
    <type>module</type>
    <type>rat</type>
    <type>string</type>
    <type>type</type>

    <key>max</key>
    <key>min</key>
    <key>max, min</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MDeg</title>
    <short_description>multi-degree of an polynomial</short_description>

    <description>
This function returns the multi-degree of F, as determined by the
weights of the current ring.  The function <coderef>Deg</coderef> returns the weight
given by the first row of the weights matrix.

        
<example>
Use R ::= Q[x,y], Weights(Mat([[1,2],[3,4],[5,6]]));
MDeg(x);
[1, 3, 5]
-------------------------------
MDeg(y);
[2, 4, 6]
-------------------------------
Deg(y);
2
-------------------------------
MDeg(x^2+y);
[2, 6, 10]
------------------------------- 
</example>
    </description>

    <syntax>
MDeg(F:POLY):LIST
</syntax>

    <see>Deg</see>
    <see>Weights Modifier</see>
    <see>PositiveGrading4</see>

    <type>polynomial</type>
    <type>ring</type>

    <key>mdeg</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Memory</title>
    <short_description>contents of local memory or ring-bound memory</short_description>

    <description>
The first form of this function prints the contents of the working
memory, i.e, all non-global variables. The second form lists all
global variables bound to the ring R.

<par/>
For more information about memory in CoCoA, see the chapter entitled
<ref>Memory Management</ref>.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x-y^2,xy-z^3);
X := 14;
ENV.R.Y := 5;  --  a global variable bound to R
               -- recall that <coc-quotes>ENV.R</coc-quotes> is equivalent to <coc-quotes>MEMORY.ENV.R</coc-quotes>
Use S ::= Q[a,b];
J := Ideal(a,b);
ENV.S.Z := 7;
Memory();
[<coc-quotes>I</coc-quotes>, <coc-quotes>J</coc-quotes>, <coc-quotes>X</coc-quotes>]
-------------------------------
Memory(R);
[<coc-quotes>Y</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Memory():TAGGED(<coc-quotes>Memory</coc-quotes>)
Memory(R:RING):TAGGED(<coc-quotes>Memory</coc-quotes>)
</syntax>

    <see>GlobalMemory</see>
    <see>Memory Management</see>

    <type>memory</type>

    <key>memory</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MinGens</title>
    <short_description>list minimal generators</short_description>

    <description>
If M is an ideal or module, this function returns a list of minimal
generators for M.  If M is the quotient of the current ring by an
ideal I or the quotient of a free module by the submodule N, then
MinGens returns a set of minimal generators for I or N, respectively.

<par/>
The coefficient ring must be a field.

<par/>
The input must be homogeneous.  The similar command <coderef>Minimalized</coderef>,
will accept inhomogeneous input.

        
<example>
Use R ::= Q[x,y,z];
I:=Ideal(x-y,(x-y)^4,z+y,(z+y)^2);
I;
Ideal(x - y, x^4 - 4x^3y + 6x^2y^2 - 4xy^3 + y^4, y + z, y^2 + 2yz + z^2)
-------------------------------
MinGens(I);
[y + z, x + z]
-------------------------------
MinGens(R/I);
[y + z, x + z]
-------------------------------
M :=Module([x+y,x-y],[(x+y)^2,(x+y)(x-y)]);
MinGens(M);
[Vector(x + y, x - y)]
-------------------------------
MinGens(R^2/M);
[Vector(x + y, x - y)]
------------------------------- 
</example>
    </description>

    <syntax>
MinGens(M:IDEAL or MODULE or TAGGED(<coc-quotes>Quotient</coc-quotes>)):LIST
</syntax>

    <see>Minimalize</see>
    <see>Minimalized</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>mingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Minimalize</title>
    <short_description>remove redundant generators</short_description>

    <description>
In the inhomogeneous case it removes redundant generators from the
ideal or module contained in X, storing the result in X, i.e. the 
original ideal or module is overwritten.

<par/>
In the homogeneous case, it obtains a generating set with smallest
possible cardinality.  The minimal set of generators found by CoCoA is
not necessarily a subset of the given generators.  As with the
inhomogeneous case, it overwrites its argument.

<par/>
The coefficient ring is assumed to be a field.

<par/>
The similar function <coderef>Minimalized</coderef> performs the same
operation, but returns the minimalized ideal or module and does not
modify the argument.
        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x-y^2,z-y^5,x^5-z^2);
I;
Ideal(-y^2 + x, -y^5 + z, x^5 - z^2)
-------------------------------
Minimalize(I);
I;
Ideal(-y^2 + x, -y^5 + z)
-------------------------------
J := Ideal(x, x-y, y-z, z^2);
Minimalized(J);
Ideal(y - z, x - z, z)
------------------------------- 
</example>
    </description>

    <syntax>
Minimalize(X:IDEAL):NULL
Minimalize(X:MODULE):NULL

where X is a variable containing an ideal or module.
</syntax>

    <see>MinGens</see>
    <see>Minimalized</see>

    <type>ideal</type>
    <type>module</type>

    <key>minimalize</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Minimalized</title>
    <short_description>remove redundant generators</short_description>

    <description>
In the inhomogeneous case it returns the ideal or module
obtained by removing redundant generators from E.

<par/>
In the homogeneous case, it obtains a generating set with smallest
possible cardinality.  The minimal set of generators found by CoCoA is
not necessarily a subset of the given generators.  It returns the
minimalized ideal or module.

<par/>
The coefficient ring is assumed to be a field.

<par/>
The similar function <coderef>Minimalize</coderef> performs the same
operation, but modifies the argument and returns NULL.
        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x-y^2,z-y^5,x^5-z^2);
I;
Ideal(-y^2 + x, -y^5 + z, x^5 - z^2)
-------------------------------
Minimalized(I);
Ideal(-y^2 + x, -y^5 + z)
-------------------------------
I;
Ideal(-y^2 + x, -y^5 + z, x^5 - z^2)
-------------------------------
Minimalize(I);
I;
Ideal(-y^2 + x, -y^5 + z)
-------------------------------
J := Ideal(x, x-y, y-z, z^2);
Minimalized(J);
Ideal(y - z, x - z, z)
------------------------------- 
</example>
    </description>

    <syntax>
Minimalized(E:IDEAL):IDEAL
Minimalized(E:MODULE):MODULE

where X is a variable containing an ideal or module.
</syntax>

    <see>MinGens</see>
    <see>Minimalize</see>

    <type>ideal</type>
    <type>module</type>

    <key>minimalized</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Minors</title>
    <short_description>list of minor determinants of a matrix</short_description>

    <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(2,M);
[4, 7, 2]
------------------------------- 
</example>
    </description>

    <syntax>
Minors(N:INT,M:MAT):LIST
</syntax>

    <see>Det</see>

    <type>matrix</type>

    <key>minors</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MinSyzMinGens</title>
    <short_description>minimal generators of syzygies of minimal generators</short_description>

    <description>

The MinSyzMinGens function has been removed.

    </description>

    <syntax>
MinSyzMinGens:  FUNCTION ELIMINATED.
</syntax>

    <see>SyzMinGens</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>minsyzmingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Mod</title>
    <short_description>remainder for integers</short_description>

    <description>
If N = Q*D + R, and <formula>0 <less_eq/> R &lt; |D|</formula>, then <code>Div(N,D)</code> returns Q and
<code>Mod(N,D)</code> returns R.

<par/>
NOTE: To perform the division algorithm on a polynomial or vector, use
<coderef>NR</coderef> (normal remainder) to find the remainder, or
<coderef>DivAlg</coderef> to get both the quotients and the remainder.

        
<example>
Div(10,3);
3
-------------------------------
Mod(10,3);
1
------------------------------- 
</example>
    </description>

    <syntax>
Mod(N:INT,D:INT):INT
</syntax>

    <see>Div</see>
    <see>DivAlg</see>
    <see>GenRepr</see>
    <see>NF</see>
    <see>NR</see>

    <type>integer</type>

    <key>mod</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Mod2Rat</title>
    <short_description>reconstructing rationals from modular integers</short_description>

    <description>
This function determines a rational number equivalent to the given
residue modulo the given modulus; the denominator will not exceed
DenomBound, and the absolute value of the numerator will be at most
Modulus/(2*DenomBound) -- this guarantees uniqueness of the answer.
If no such rational exists, or if DenomBound exceeds Modulus/2 then
zero is returned.  DenomBound must be positive; if not, zero is
returned. 

        
<example>
Mod2Rat(239094665,314159265,10000);
355/113
-------------------------------
Residue := 1234567;                         -- To compute inverse of
Modulus := 2^100;                           -- Residue modulo Modulus,
Mod2Rat(Residue, Modulus, Div(Modulus-1,2));-- result is the denominator.
1/284507170216309247716413542199
------------------------------- 
</example>
    </description>

    <syntax>
Mod2Rat(Residue:INT, Modulus:INT, DenomBound:INT):RAT
</syntax>

    <see>Div</see>
    <see>Mod</see>

    <type>integer</type>
    <type>rational</type>
    <type>zmod</type>

    <key>mod2rat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Module</title>
    <short_description>convert an expression into a module</short_description>

    <description>
The first function returns the module generated by the vectors
<code>V_1,...,V_n</code>.  The second function returns the module generated by the
(elements cast-able to) vectors in L.  The third function returns the
module generated by the generators of I.  This is the same as the
function <code>Cast(E,MODULE)</code>.

        
<example>
Use R ::= Q[x,y,z];
M := Module([x^2-y^3,x^3-yz],[x^3,z^2]);
M;
Module([-y^3 + x^2, x^3 - yz], [x^3, z^2])
-------------------------------
L := [[-y^3 + x^2, x^3 - yz], [x^3, z^2]];
Module(L) = M;
TRUE
-------------------------------
I := Ideal(x,y^2,z^3);
Module(I);
Module([x], [y^2], [z^3])
------------------------------- 
</example>
    </description>

    <syntax>
Module(V_1:VECTOR,...,V_n:VECTOR):MODULE
Module(L:LIST):MODULE
Module(I:IDEAL):MODULE

where L is a list of elements cast-able to vectors.
</syntax>

    <see>Cast</see>

    <type>module</type>

    <key>module</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Monic</title>
    <short_description>divide polynomials by their leading coefficients</short_description>

    <description>
In the first form, this function returns F divided by its leading
coefficient (see <coderef>LC</coderef>) or, if F is zero, it returns zero.

<par/>
In its second form, it returns the list obtained by applying the first
form of Monic to each of the components of L.

        
<example>
Use R ::= Q[x,y];
L := [4x^5-y^2,3x-2y^4];
Monic(L);
[x^5 - 1/4y^2, y^4 - 3/2x]
-------------------------------
Use R ::= Z[x,y];
-- WARNING: Coeffs are not in a field
-- GBasis-related computations could fail to terminate or be wrong
-------------------------------

-------------------------------
L := [4x^5-y^2,3x-2y^4];
Monic(L);  -- can&apos;t invert coefficients over Z

-------------------------------
ERROR: Cannot divide
CONTEXT: Cond(Type(X) = LIST, [Monic(A)|A IN X], IsZero(X), X, X / LC(X))
-------------------------------
Use R ::= Z/(5)[x,y];
F := 2x^2+4y^3;
Monic(F);
y^3 - 2x^2
------------------------------- 
</example>
    </description>

    <syntax>
Monic(F:POLY):POLY
Monic(L:LIST of POLY):LIST of POLY
</syntax>

    <see>LC</see>

    <type>list</type>
    <type>polynomial</type>

    <key>monic</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Monomials</title>
    <short_description>the list of monomials of a polynomial or vector</short_description>

    <description>
This function returns the list of monomials of F.  The function
<coderef>Support</coderef> returns the list of terms (monomials without coefficients).

        
<example>
Use R ::= Q[xy];
F := 3x^2y+5y^3-xy^5;
Monomials(F);
[-xy^5, 3x^2y, 5y^3]
-------------------------------
Support(F);
[xy^5, x^2y, y^3]
-------------------------------
Monomials(Vector(3x^2y+y,5xy+4));
[Vector(3x^2y, 0), Vector(0, 5xy), Vector(y, 0), Vector(0, 4)]
------------------------------- 
</example>
    </description>

    <syntax>
Monomials(F:POLY or VECTOR):LIST
</syntax>

    <see>Coefficients</see>
    <see>Support</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>monomials</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>MonsInIdeal</title>
    <short_description>ideal generated by the monomials in an ideal</short_description>

    <description>
This function returns the ideal generated by all monomials in the
original ideal I.

        
<example>
Use R ::= Q[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>

    <syntax>
MonsInIdeal(I:IDEAL):IDEAL
</syntax>

    <type>ideal</type>

    <key>monsinideal</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>More</title>
    <short_description>print a string, N lines at a time</short_description>

    <description>
The purpose of this function is to print the string S without
scrolling off of the screen.

<par/>
The first form of this function stores the string S in a <code>MoreDevice</code>,
then prints the first N lines from the MoreDevice where N is the
integer stored in the global variable MEMORY.MoreCount.  Subsequent
calls to <code>More</code> print the next N lines from the MoreDevice, (each time
removing the lines from the device) until the MoreDevice is empty.
After each call to <code>More</code> a line with <code>More();</code> is printed as long as
the MoreDevice is not empty.  This line is easily cut-and-pasted.

<par/>
The user may set the number of lines to print with the command
<code>MEMORY.MoreCount := X</code>, where X is an integer.  The default is value
is 20.

<par/>
If E is *any* CoCoA object, the command <code>Sprint(E)</code> converts E into a
string.  The output may then be given to <code>More</code> for printing.

<par/>
To use the more device with the online help system, see 
<coderef>H.SetMore</coderef>, <coderef>H.UnSetMore</coderef>.
    </description>

    <syntax>
More(S:STRING):NULL
More():NULL
</syntax>

    <see>H.UnSetMore</see>
    <see>H.SetMore</see>
    <see>Commands and Functions for Strings</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>
    <type>system</type>

    <key>more</key>
    <key>scrolling</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Multiplicity</title>
    <short_description>the multiplicity (degree) of a ring or quotient object</short_description>

    <description>
This function computes the multiplicity (or degree) of the ring R,
i.e., the leading coefficient of the Hilbert polynomial multiplied by
the factorial of the degree of the Hilbert polynomial.  The weights of
the indeterminates of the current ring must all be 1.

        
<example>
Use R ::= Q[t,x,y,z];
Multiplicity(R/Ideal(x,y,z)^5);
35
------------------------------- 
</example>
    </description>

    <syntax>
Multiplicity(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):INT
</syntax>

    <see>Hilbert</see>
    <see>HilbertSeries</see>
    <see>Poincare</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>multiplicity</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>N</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NewId</title>
    <short_description>create a new identifier</short_description>

    <description>
This function returns a string of the form <code>V#N</code> where N is an
integer.  Each time it is called, the integer N changes, producing a
new string.  The purpose is to produce identifiers for variables or
rings.  (CoCoA does not check for the unlikely event that variables of
the same form have been defined without the use of <code>NewId</code>.)  The
function <code>NewId</code> is often used with <coderef>Var</coderef>.

<par/>
The most important use for this function is for creating temporary
rings within user-defined functions.  For an example, see the section
of the tutorial entitled <ref>Rings Inside User-Defined Functions</ref>.

        
<example>
NewId();
V#0
-------------------------------
NewId();
V#1
-------------------------------
X := NewId();
X;
V#2
-------------------------------
Var(X) := 3;
Var(NewId()) := 4;
Describe Memory();
------------[Memory]-----------
It = V#2
V#2 = 3
V#3 = 4
X = V#2
-------------------------------
Y := NewId();
Var(Y) ::= Q[a,b];
Use Var(Y);
RingEnvs();
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>V#6</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Y;
V#6
-------------------------------
Var(Y);
Q[a,b]
------------------------------- 
</example>
    </description>

    <syntax>
NewId():STRING
</syntax>

    <see>Rings Inside User-Defined Functions</see>
    <see>Var</see>

    <type>function</type>
    <type>string</type>

    <key>newid</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NewList</title>
    <short_description>create a new list</short_description>

    <description>
The second function returns a list of length N, filled by E.  The
first function, in which E is not indicated, returns a list of length
N filled with <code>Null</code> values.

        
<example>
NewList(4,<coc-quotes>a</coc-quotes>);
[<coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>]
-------------------------------
NewList(4);
[Null, Null, Null, Null]
------------------------------- 
</example>
    </description>

    <syntax>
NewList(N:INT):LIST
NewList(N:INT,E:OBJECT)
</syntax>

    <see>List</see>

    <type>list</type>

    <key>newlist</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NewMat</title>
    <short_description>create a new matrix</short_description>

    <description>
The second function returns an MxN matrix, filled by E.  The first
function, in which E is not indicated, returns an MxN matrix filled
with <coc-quotes>Null</coc-quotes> values.

        
<example>
NewMat(2,3,<coc-quotes>a</coc-quotes>);
Mat([
  [<coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>],
  [<coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>, <coc-quotes>a</coc-quotes>]
])
-------------------------------
NewMat(2,2);
Mat([
  [Null, Null],
  [Null, Null]
])
------------------------------- 
</example>
    </description>

    <syntax>
NewMat(M:INT,N:INT):MAT
NewMat(M:INT,N:INT,E:OBJECT):MAT
</syntax>

    <see>Mat</see>

    <type>matrix</type>

    <key>newmat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NewVector</title>
    <short_description>create a new vector</short_description>

    <description>
The second function returns a vector of length N, each of whose
components is E.  The first function, in which E is not indicated,
returns a vector of length N filled with zeros.

        
<example>
Use R ::= Q[x,y];
NewVector(4);
Vector(0, 0, 0, 0)
-------------------------------
NewVector(3,x^2+y);
Vector(x^2 + y, x^2 + y, x^2 + y)
------------------------------- 
</example>
    </description>

    <syntax>
NewVector(N:INT):VECTOR
NewVector(N:INT,E:OBJECT):VECTOR

where E is cast-able to POLY.
</syntax>

    <see>Vector</see>

    <type>vector</type>

    <key>newvector</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NextPPrime</title>
    <short_description>find the next largest probable prime number</short_description>

    <description>
This function computes the smallest probable prime number greater than N.  If
N is negative an error is generated.  This
function can generate primes larger than permitted as the
characteristic of a finite field in CoCoA.

        
<example>
NextPPrime(1000);
1009
-------------------------------
NextPPrime(10^50);
100000000000000000000000000000000000000000000000151
-------------------------------

</example>
    </description>

    <syntax>
NextPPrime(N:INT):INT
    
</syntax>

    <see>IsPPrime</see>
    <see>NextPrime</see>

    <type>integer</type>

    <key>nextpprime</key>
    <key>nextprime</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NextPrime</title>
    <short_description>find the next largest prime number</short_description>

    <description>
This function computes the smallest prime number greater than N.  If
N is negative or too large then the value zero is returned.  This
function may generate primes larger than permitted as the
characteristic of a finite field in CoCoA.  On most platforms primes
up to about 45000 can be generated; in some cases a higher limit
exists.

        
<example>
NextPrime(1000);
1009
------------------------------- 
</example>
    </description>

    <syntax>
NextPrime(N:INT):INT
</syntax>

    <see>IsPrime</see>
    <see>NextPPrime</see>

    <type>integer</type>

    <key>nextprime</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NF</title>
    <short_description>normal form</short_description>

    <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/>
The coefficient ring is assumed to be a field.  Note that the
definition of normal form depends on the current value of the option
FullRed of the panel GROEBNER.  If FullRed is FALSE it means that a
polynomial is in normal form when its leading term with respect to the
the current term ordering cannot be reduced. If FullRed is TRUE it
means that a polynomial is in NF if and only if each monomial cannot
be reduced.


        
<example>
Use R ::= Q[x,y,z];
Set FullRed;
I := Ideal(z);
NF(x^2+xy+xz+y^2+yz+z^2,I);
x^2 + xy + y^2
-------------------------------
UnSet FullRed;
NF(x^2+xy+xz+y^2+yz+z^2,I);
x^2 + xy + y^2 + xz + yz + z^2
------------------------------- 
</example>
    </description>

    <syntax>
NF(F:POLY,I:IDEAL):POLY
NF(V:VECTOR,M:MODULE):VECTOR
</syntax>

    <see>DivAlg</see>
    <see>FullRed</see>
    <see>GenRepr</see>
    <see>IsIn</see>
    <see>NFsAreZero</see>
    <see>NR</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>polynomial</type>
    <type>vector</type>

    <key>nf</key>
    <key>normal form</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NFsAreZero</title>
    <short_description>test if normal forms are zero</short_description>

    <description>
This function returns TRUE if each component of L
has normal form 0 with respect to M, i.e., if each component is an
element of M.  Otherwise, it returns FALSE.  The coefficient ring is
assumed to be a field.

        
<example>
Use S ::= Q[t,x,y,z];
I := Ideal(t^31-t^6-x, t^8-y, t^10-z);
F := y^5-z^4;
G := (t^8-y)(3F+t^10-z);
NFsAreZero([F,G],I);   -- F and G are in I
TRUE
-------------------------------
NFsAreZero([F,x,G],I); -- x is not in I
FALSE
------------------------------- 
</example>
    </description>

    <syntax>
NFsAreZero(L:LIST of POLY,M IDEAL):BOOL
NFsAreZero(L:LIST of VECTOR,M:MODULE):BOOL
</syntax>

    <see>IsIn</see>
    <see>NF</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>polynomial</type>
    <type>module</type>
    <type>vector</type>

    <key>nfsarezero</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NonZero</title>
    <short_description>remove zeroes from a list</short_description>

    <description>
This function returns the list obtained by removing the zeroes from L.

        
<example>
Use R ::= Q[x,y,z];
NonZero([<coc-quotes>a</coc-quotes>,0,0,3,Ideal(y),0]);
[<coc-quotes>a</coc-quotes>, 3, Ideal(y)]
------------------------------- 
</example>
    </description>

    <syntax>
NonZero(L:LIST or VECTOR):LIST
</syntax>

    <see>FirstNonZero</see>
    <see>FirstNonZeroPos</see>

    <type>list</type>
    <type>vector</type>

    <key>nonzero</key>
    <key>non-zero</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Not, And, Or</title>
    <short_description>boolean operators</short_description>

    <description>
These operators have their usual meanings.  Note that when two or more
boolean expressions are combined with AND, they are evaluated one by
one until a FALSE expression is found. The rest are not evaluated.
For example, given the expression <code>A And B</code>, the system does not
attempt to evaluate B unless A evaluates to TRUE.  Similarly,
evaluation of a sequence of boolean expressions connected by OR stops
as soon as a TRUE expression is found.
    </description>

    <syntax>
Not E
E And F
E Or F

where E and F are of type BOOL.
</syntax>

    <type>boolean</type>

    <key>not</key>
    <key>and</key>
    <key>or</key>
    <key>not, and, or</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NR</title>
    <short_description>normal reduction</short_description>

    <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 <coderef>DivAlg</coderef>.  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 <coderef>GenRepr</coderef> or <coderef>NF</coderef>
instead).

        
<example>
Use R::= Q[xyz];
F := x^2y+xy^2+y^2;
NR(F,[xy-1,y^2-1]);
x + y + 1
-------------------------------
V := Vector(x^2+y^2+z^2,xyz);
NR(V,[Vector(x,y),Vector(y,z),Vector(z,x)]);
Vector(z^2, z^3 - yz - z^2)
------------------------------- 
</example>
    </description>

    <syntax>
NR(X:POLY,L:LIST of POLY):POLY
NR(X:VECTOR,L:LIST of VECTOR):VECTOR
</syntax>

    <see>DivAlg</see>
    <see>GenRepr</see>
    <see>NF</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>nr</key>
    <key>normal reduction</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Num</title>
    <short_description>numerator</short_description>

    <description>
These functions return the numerator and denominator of N.  The
numerator and denominator can also be found using <code>.Num</code>
and <code>.Den</code> (fragile).

        
<example>
Num(3);
3
-------------------------------
Num(x/(x+y));
x
-------------------------------
X := 2/3;
X.Num; X.Den;
2
-------------------------------
3
------------------------------- 
</example>
    </description>

    <syntax>
Num(N:INT or RAT):INT
Num(N:POLY or RATFUN):POLY
</syntax>

    <see>Numerators and Denominators for Rational Functions</see>
    <see>Numerators and Denominators for Rational Numbers</see>
    <see>Den</see>

    <type>integer</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>

    <key>num</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NumComps</title>
    <short_description>the number of components of a vector</short_description>

    <description>
If X is a vector, this function returns the number of components of
X; it gives the same result as Len(X).  If X is a module, then this
function returns the rank of the free module in which X is defined.

        
<example>
Use R ::= Q[x,y];
NumComps(Vector(x,y,x^2+y^2,x^2-y^2));
4
-------------------------------
M := Module([x,y^2,2+x^2y],[x,0,y]);  -- a submodule of R^3 
NumComps(M);
3
-------------------------------
M.NumComps;  -- alternative syntax
3
------------------------------- 
</example>
    </description>

    <syntax>
NumComps(X:VECTOR or MODULE):INT
</syntax>

    <see>Len</see>

    <type>vector</type>

    <key>numcomps</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>NumIndets</title>
    <short_description>number of indeterminates</short_description>

    <description>
This function returns the number of indeterminates of the current ring
or of R.

        
<example>
S ::= Q[x,y];
Use R ::= Q[x,y,z];
NumIndets();
3
-------------------------------
NumIndets(S);
2
------------------------------- 
</example>
    </description>

    <syntax>
NumIndets():INT
NumIndet(R:RING):INT
</syntax>

    <see>Indet</see>
    <see>IndetInd</see>
    <see>IndetIndex</see>
    <see>IndetName</see>
    <see>Indets</see>

    <type>ring</type>

    <key>numindets</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>O</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenIFile</title>
    <short_description>open input file</short_description>

    <description>
This function opens the file with name S for input.
Input from that file can then be read with <coderef>Get</coderef>.  

<par/>
(Note: one would normally use <coderef>Source</coderef> to read CoCoA commands from a file.)

        
<example>
D := OpenOFile(<coc-quotes>my-test</coc-quotes>);  -- open <coc-quotes>my-test</coc-quotes> for output from CoCoA
Print <coc-quotes>hello world</coc-quotes> On D;   -- print string into <coc-quotes>mytest</coc-quotes>
Close(D);
D := OpenIFile(<coc-quotes>my-test</coc-quotes>);  -- open <coc-quotes>my-test</coc-quotes> 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>

    <syntax>
OpenIFile(S:STRING):DEVICE
</syntax>

    <see>Close</see>
    <see>Introduction to IO</see>
    <see>OpenOFile</see>
    <see>OpenIString</see>
    <see>OpenOString</see>
    <see>OpenSocket</see>
    <see>Source</see>
    <see><formula>&lt;&lt;</formula></see>

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

    <key>openifile</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenIString</title>
    <short_description>open input string</short_description>

    <description>
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.  <code>OpenIString</code> is used to read input from the
string T with the help of <coderef>Get</coderef>.
        
<example>
S := <coc-quotes>hello world</coc-quotes>;
D := OpenIString(<coc-quotes></coc-quotes>,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>

    <syntax>
OpenIString(S:STRING,T:STRING):DEVICE
OpenOString(S:STRING):DEVICE
</syntax>

    <see>Close</see>
    <see>Introduction to IO</see>
    <see>OpenOString</see>
    <see>OpenIFile</see>
    <see>OpenOFile</see>
    <see>Source</see>
    <see><formula>&lt;&lt;</formula></see>
    <see>Sprint</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>openistring</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenLog</title>
    <short_description>open a log of a CoCoA session</short_description>

    <description>
This function opens the output device D and starts to record the
output from a CoCoA session on D.  The <coderef>CloseLog</coderef> 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
<coderef>OpenOFile</coderef>) or an output string (see <coderef>OpenOString</coderef>).  Several output
devices may be open at a time.  If the panel option <code>Echo</code> is set to
TRUE, both the input and output of the CoCoA session are logged;
otherwise, just the output is logged.

        
<example>
D := OpenOFile(<coc-quotes>MySession</coc-quotes>);
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 <coc-quotes>MySession</coc-quotes>:
2
-------------------------------
2 + 2
4
-------------------------------
F := 2
CloseLog(D) 
</example>
    </description>

    <syntax>
OpenLog(D:DEVICE):NULL
</syntax>

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

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

    <key>openlog</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenOFile</title>
    <short_description>open output file</short_description>

    <description>
This function opens the file with name S---creating it if it
does not already exist---for output.  The function <code>Print On</code> is then
used for writing output to the file.  If OpenOFile is used without a
second argument or if the second argument is not <code>w</code> or <code>W</code> then
<code>Print On</code> will append output to the file.  Otherwise, any existing
file with the name S will be erased before the output is written.

<example>
D := OpenOFile(<coc-quotes>my-test</coc-quotes>);  -- open <coc-quotes>my-test</coc-quotes> for output from CoCoA
Print <coc-quotes>hello world</coc-quotes> On D;   -- print string into <coc-quotes>mytest</coc-quotes>
Print <coc-quotes> test</coc-quotes> On D;  -- append to the file <coc-quotes>mytest</coc-quotes>
Close(D);  -- close the file
D := OpenOFile(<coc-quotes>my-test</coc-quotes>,<coc-quotes>w</coc-quotes>); -- clear <coc-quotes>my-test</coc-quotes>
Print <coc-quotes>goodbye</coc-quotes> On D; -- <coc-quotes>mytest</coc-quotes> now consists only of the string <coc-quotes>goodbye</coc-quotes>
Close(D); 
</example>
    </description>

    <syntax>
OpenOFile(S:STRING):DEVICE
OpenOFile(S:STRING,<coc-quotes>w</coc-quotes> or <coc-quotes>W</coc-quotes>):DEVICE
</syntax>

    <see>Close</see>
    <see>Introduction to IO</see>
    <see>OpenIFile</see>
    <see>OpenIString</see>
    <see>OpenOString</see>
    <see>Source</see>
    <see><formula>&lt;&lt;</formula></see>

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

    <key>openofile</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenOString</title>
    <short_description>open output string</short_description>

    <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.  <code>OpenOString</code> is used to write to a
string with the help of <code>Print On</code>.

        
<example>
D := OpenOString(<coc-quotes></coc-quotes>);  -- open a string for output from CoCoA
L := [1,2,3]; -- a list
Print L On D;  -- print to D
D;
Record[Name = <coc-quotes></coc-quotes>, Type = <coc-quotes>OString</coc-quotes>, Protocol = <coc-quotes>CoCoAL</coc-quotes>]
-------------------------------
S := Cast(D,STRING);  -- S is the string output to D
S; -- a string
[1, 2, 3]
Print <coc-quotes> more characters</coc-quotes> On D;  -- append to the existing output string
Cast(D,STRING);
[1, 2, 3] more characters
------------------------------- 
</example>
    </description>

    <syntax>
OpenOString(S:STRING):DEVICE
</syntax>

    <see>Close</see>
    <see>Introduction to IO</see>
    <see>OpenIFile</see>
    <see>OpenOFile</see>
    <see>OpenIString</see>
    <see>Source</see>
    <see><formula>&lt;&lt;</formula></see>
    <see>Sprint</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>openostring</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>OpenSocket</title>
    <short_description>open a socket connection</short_description>

    <description>
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 <code>localhost</code> on
port <code><coc-quotes>0xc0c0</coc-quotes></code>.
To change these settings redefine in your <code>userinit.coc</code> or
<code>.cocoarc</code> the variables 
<verbatim>
MEMORY.CoCoAServerMachine := <coc-quotes>localhost</coc-quotes>;
MEMORY.CoCoAServerPort := <coc-quotes>0xc0c0</coc-quotes>;
</verbatim>

<example>
D := OpenSocket(<coc-quotes>localhost</coc-quotes>, <coc-quotes>10000</coc-quotes>);
Print 100^6 On D;
Source D;
Close(D);
</example>
    </description>

    <syntax>
OpenSocket(Machine: STRING, Port: STRING): DEVICE
</syntax>

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

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

    <key>opensocket</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Option</title>
    <short_description>status of a panel option</short_description>

    <description>
This function returns the status of a panel option (TRUE/FALSE).  For
a list of panels, use <coderef>Panels</coderef> and for the current status of each
option for a panel with name P, use <code>Panel(P)</code>.  To toggle option
values, use <coderef>Set-Unset</coderef>.  The function <coderef>Option</coderef> is particularly
useful inside a user-defined function in order to temporarily change
the value of an option (restoring the option&apos;s original value when the
function is complete). See <ref>Setting Options</ref> for an example of this
use of <coderef>Option</coderef>.

        
<example>
Option(Indentation);
FALSE
------------------------------- 
</example>
    </description>

    <syntax>
Option(O):BOOL

where O is a panel option.
</syntax>

    <see>Introduction to Panels</see>
    <see>Panel</see>
    <see>Panels</see>
    <see>Setting Options</see>
    <see>Unset</see>

    <type>panels</type>
    <type>system</type>

    <key>option</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Ord</title>
    <short_description>matrix defining a term-ordering</short_description>

    <description>
The first two forms return matrices which describe the term-ordering
of the current ring or of the ring R, respectively.  The last form is
used as a modifier when creating a new ring.  In that case, it
determines the term-ordering for the ring (see <ref>Orderings</ref>).  Its
argument is a matrix of small integers which defines a term-ordering;
i.e. for a ring with N indeterminates it must be an NxN matrix of full
rank where the first non-zero entry in each column is positive.  The
matrix entries must be in the range -32767 to +32767, otherwise an
error results.

        
<example>
Use S ::= Q[x,y,z], Ord(Mat([[1,0,0],
                             [0,1,0],
                             [0,0,1]]));

M := Mat([[1,1],[0,-1]]);
T ::= Q[a,b], Ord(M);
U ::= Z/(101)[x,y,z,t], DegRevLex;
-- The term-order for the current ring, S.
Ord();
Mat([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
-------------------------------
Ord(T);
Mat([
  [1, 1],
  [0, -1]
])
-------------------------------
Ord(U);
Mat([
  [1, 1, 1, 1],
  [0, 0, 0, -1],
  [0, 0, -1, 0],
  [0, -1, 0, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
Ord():MAT
Ord(R:RING):MAT
Ord(M:MAT):MAT
</syntax>

    <see>DegLexMat</see>
    <see>DegRevLexMat</see>
    <see>LexMat</see>
    <see>RevLexMat</see>
    <see>XelMat</see>
    <see>Elim</see>
    <see>Orderings</see>
    <see>Predefined Term-Orderings</see>

    <type>ring</type>

    <key>ord</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>P</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Packages</title>
    <short_description>list of loaded packages</short_description>

    <description>
This function returns the names of the loaded packages as a list of
strings.  The string <code>$user</code> refers to the user-defined
functions defined in the current CoCoA session.

        
<example>
Packages();
[<coc-quotes><code>$builtin</code></coc-quotes>, <coc-quotes><code>$coclib</code></coc-quotes>, <coc-quotes><code>$user</code></coc-quotes>, <coc-quotes>$help</coc-quotes>,
<coc-quotes>$io</coc-quotes>, <coc-quotes>$misc</coc-quotes>] 
------------------------------- 
</example>
    </description>

    <syntax>
Packages():LIST
</syntax>

    <see>CoCoA Packages</see>
    <see>Supported Packages</see>

    <type>packages</type>

    <key>packages</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Panel</title>
    <short_description>print status of a panel&apos;s options</short_description>

    <description>
This command prints the status of the options in one of the three
panels.  It returns no value.

        
<example>
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
------------------------------- 
</example>
    </description>

    <syntax>
Panel(E)

where E is one of <coc-quotes>GENERAL</coc-quotes> or <coc-quotes>GROEBNER</coc-quotes>.
</syntax>

    <see>Introduction to Panels</see>
    <see>Option</see>
    <see>Panels</see>
    <see>Unset</see>

    <type>panels</type>
    <type>system</type>

    <key>panel</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Panels</title>
    <short_description>list of CoCoA panels</short_description>

    <description>
This function returns a list of CoCoA&apos;s panels.

        
<example>
Panels();
[<coc-quotes>GENERAL</coc-quotes>, <coc-quotes>GROEBNER</coc-quotes>]
-------------------------------
Panel(It[1]);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
------------------------------- 
</example>
    </description>

    <syntax>
Panels()
</syntax>

    <see>Introduction to Panels</see>
    <see>Option</see>
    <see>Panel</see>
    <see>Unset</see>

    <type>panels</type>
    <type>system</type>

    <key>panels</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Partitions</title>
    <short_description>partitions of an integer</short_description>

    <description>
These function returns all integer partitions of N, positive integer

        
<example>
Partitions(3);
[[3], [1, 2], [1, 1, 1]]
------------------------------- 
</example>
    </description>

    <syntax>
Partitions(N: INT): LIST
</syntax>

    <see>Subsets</see>
    <see>Tuples</see>

    <type>integer</type>

    <key>partitions</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Permutations</title>
    <short_description>returns all permutations of the entries of a list</short_description>

    <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]]
-------------------------------
Set(Permutations([2, 2, x]));
[[2, 2, x], [2, x, 2], [x, 2, 2]]
------------------------------- 
</example>
    </description>

    <syntax>
Permutations(L: LIST): LIST
</syntax>

    <see>Subsets</see>
    <see>Tuples</see>

    <type>list</type>

    <key>permutations</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Pfaffian</title>
    <short_description>the Pfaffian of a skew-symmetric matrix</short_description>

    <description>
This function returns the Pfaffian of M.

        
<example>
Use R ::= Q[x,y];
Pfaffian(Mat([[0,y],[-y,0]]));
y
------------------------------- 
</example>
    </description>

    <syntax>
Pfaffian(M:MAT)

where M is skew-symmetric.  The resulting type depends on the entries
of the matrix.
</syntax>

    <see>Det</see>

    <type>matrix</type>

    <key>pfaffian</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PkgName</title>
    <short_description>returns the name of a package</short_description>

    <description>
This function returns the (long) name of a package.  The first form
returns <code>$coclib</code> 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>

    <syntax>
PkgName():STRING
S.PkgName():STRING

where S is the identifier or alias for a package.
</syntax>

    <type>packages</type>

    <key>pkgname</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Poincare</title>
    <short_description>the Hilbert-Poincare series</short_description>

    <description>
Same as <coderef>HilbertSeries</coderef>.

    </description>

    <syntax>
Poincare(M:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>Dim</see>
    <see>Hilbert</see>
    <see>HilbertSeries</see>
    <see>HVector</see>
    <see>Multiplicity</see>
    <see>PoincareMultiDeg</see>
    <see>PoincareShifts</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>poincare</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PoincareShifts</title>
    <short_description>the Hilbert-Poincare series</short_description>

    <description>
Same as <coderef>HilbertSeriesShifts</coderef>.

    </description>

    <syntax>
PoincareShifts(M: Module, ShiftsList: LIST):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
PoincareShifts(M: TAGGED(<coc-quotes>Quotient</coc-quotes>), ShiftsList: LIST)
                                           :TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>Dim</see>
    <see>Hilbert</see>
    <see>HilbertSeries</see>
    <see>HilbertSeriesShifts</see>
    <see>HVector</see>
    <see>Multiplicity</see>
    <see>Poincare</see>
    <see>PoincareMultiDeg</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>poincareshifts</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PoincareMultiDeg</title>
    <short_description>the Hilbert-Poincare series wrt a multigrading</short_description>

    <description>
Same as <coderef>HilbertSeriesMultiDeg</coderef>.

<example>
Use R ::= Q[x,y,z];

WM := Mat([[1,0,0],[1,-1,0]]);
PoincareMultiDeg(R/Ideal(Indets())^2, WM);
</example>
    </description>

    <syntax>
PoincareMultiDeg(TAGGED(<coc-quotes>Quotient</coc-quotes>),WM:MAT):TAGGED(<coc-quotes>$hp.PSeries</coc-quotes>)
</syntax>

    <see>HilbertSeries</see>
    <see>HilbertSeriesMultiDeg</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>hilbert</type>
    <type>quotient</type>
    <type>ring</type>

    <key>poincaremultideg</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Poly</title>
    <short_description>convert an expression into a polynomial</short_description>

    <description>
This function converts the expression E into a polynomial, if
possible.  It is the same as Cast(E,POLY). 

        
<example>
F := 3;
G := Poly(3);
Type(F);
INT
-------------------------------
Type(G);
POLY
-------------------------------
Use R ::= Q[x];
Poly(Vector(x));
x
------------------------------- 
</example>
    </description>

    <syntax>
Poly(E:OBJECT):POLY
</syntax>

    <see>Cast</see>

    <type>polynomial</type>

    <key>poly</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PositiveGrading4</title>
    <short_description>extend a positive grading (for CoCoA-4
    multigradings limitation)</short_description>

    <description>
This function returns a matrix defining a <em>similar</em> multigrading.
Because of an innate limitation (see <see>Weights Modifier</see>)
CoCoA-4 does not allow zero entries in the first row of the weights matrix.
This function returns a matrix which has an extra first row which is a
suitable combination of the following rows and has no zero entries.
This we can work in CoCoA-4 with any positive grading being the
first component the multidegree <em>redundant</em>.

<example>
  G := Mat([[1,1,1,0,0], [0,0,0,1,1]]);
  PG := PositiveGrading4(G);
  Use Q[x[1..5]], Weights(PG);
  MDeg(x[2]); -- ignore the first entry to get the degree wrt G
[1, 1, 0]
-------------------------------
  Tail(MDeg(x[2]));
[1, 0]
-------------------------------
</example>
    </description>

    <syntax>
PositiveGrading4(M:MATRIX):MATRIX
</syntax>

    <see>Weights Modifier</see>
    <see>IsPositiveGrading</see>
    <see>HilbertSeriesMultiDeg</see>

    <type>matrix</type>

    <key>positivegrading4</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PowerMod</title>
    <short_description>compute a modular power efficiently</short_description>

    <description>
This function calculates efficiently an integer power modulo a given
modulus.  Thus <code>PowerMod(A,B,M)</code> is equal to <code>Mod(A^B, M)</code>, but the former
is computed faster.  B 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>

    <syntax>
PowerMod(A:INT,B:INT,M:INT):INT
    
</syntax>

    <type>int</type>

    <key>powermod</key>
    <key>modular power</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PrimaryDecomposition</title>
    <short_description>primary decomposition of an ideal</short_description>

    <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.

        
<example>
Use R ::= Q[x,y,z];
PrimaryDecomposition(Ideal(xy, xz, yz));
[Ideal(y, z), Ideal(x, z), Ideal(x, y)]
------------------------------- 
</example>
    </description>

    <syntax>
PrimaryDecomposition(I: SQUAREFREE MONOMIAL IDEAL): LIST of IDEAL
</syntax>

    <see>EquiIsoDec</see>

    <type>ideal</type>

    <key>primarydecomposition</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Print</title>
    <short_description>print the value of an expression</short_description>

    <description>
This command displays the value of each of the expressions, <code>E_i</code>.
The parentheses are optional.  The argument <code>NewLine</code> (without
quotes, but note the two capital letters), moves the cursor to the
next line.  

<par/>
The similar command <coderef>PrintLn</coderef> is equivalent
to <code>Print</code> with a final extra argument, <code>NewLine</code>.

        
<example>
For I := 1 To 10 Do  
  Print(I^2, <coc-quotes> </coc-quotes>);
EndFor;
1 4 9 16 25 36 49 64 81 100 
-------------------------------
Print <coc-quotes>hello</coc-quotes>,NewLine,<coc-quotes>world</coc-quotes>;
hello
world
------------------------------- 
</example>
    </description>

    <syntax>
Print E_1,...,E_n :NULL
Print(E_1,...,E_n):NULL

where the E_i are CoCoA expressions.
</syntax>

    <see>Print On</see>
    <see>PrintLn</see>

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

    <key>newline</key>
    <key>print</key>
    <key>println</key>
    <key>print, println</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Print On</title>
    <short_description>print to an output device</short_description>

    <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 <coderef>OpenOFile</coderef> or <coderef>OpenOString</coderef>.

        
<example>
D := OpenOFile(<coc-quotes>my-test</coc-quotes>);  -- open <coc-quotes>my-test</coc-quotes> for output from CoCoA
Print <coc-quotes>hello world</coc-quotes> On D;   -- print string into <coc-quotes>mytest</coc-quotes>
Close(D);  -- close the file
D := OpenIFile(<coc-quotes>my-test</coc-quotes>);  -- open <coc-quotes>my-test</coc-quotes> 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>

See <coderef>OpenOFile</coderef> for an example using output strings.
For printing to the CoCoA window, just use <code>Print E</code> which is short for 
<code>Print E On DEV.OUT</code>. 
    </description>

    <syntax>
Print E:OBJECT On D:DEVICE
</syntax>

    <see>Introduction to IO</see>
    <see>OpenIFile</see>
    <see>OpenOFile</see>
    <see>OpenIString</see>
    <see>OpenOString</see>
    <see>Print</see>
    <see>PrintLn</see>

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

    <key>print on</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>PrintLn</title>
    <short_description>print the value of an expression</short_description>

    <description>
This command is equivalent to <coderef>Print</coderef> with a final extra
argument, <code>NewLine</code>; in other words, it prints the values of its
arguments, then moves the cursor to the next line.  The parentheses
are optional.

        
<example>
For I := 1 To 10 Do  
  Print(I^2, <coc-quotes> </coc-quotes>);
EndFor;
1 4 9 16 25 36 49 64 81 100 
-------------------------------
For I := 1 To 3 Do
  PrintLn(I);
EndFor;
1
2
3

-------------------------------
Print <coc-quotes>hello</coc-quotes>,NewLine,<coc-quotes>world</coc-quotes>;
hello
world
------------------------------- 
</example>
    </description>

    <syntax>
PrintLn E_1,...,E_n :NULL
PrintLn(E_1,...,E_n):NULL

where the E_i are CoCoA expressions.
</syntax>

    <see>Print</see>
    <see>Print On</see>

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

    <key>newline</key>
    <key>println</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Product, Sum</title>
    <short_description>the product or sum of the elements of a list</short_description>

    <description>
These functions return the product and sum, respectively, of the
objects in the list L.

        
<example>
Use R ::= Q[x,y];
Product([3,x,y^2]);
3xy^2
-------------------------------
Sum([3,x,y^2]);
y^2 + x + 3
-------------------------------
Product(1..40)=Fact(40);
TRUE
-------------------------------
Sum([<coc-quotes>c</coc-quotes>,<coc-quotes>oc</coc-quotes>,<coc-quotes>oa</coc-quotes>]);
cocoa
------------------------------- 
</example>
    </description>

    <syntax>
Product(L:List):OBJECT
Sum(L:List):OBJECT
</syntax>

    <see>Algebraic Operators</see>

    <type>ideal</type>
    <type>integer</type>
    <type>list</type>
    <type>matrix</type>
    <type>polynomial</type>
    <type>rat</type>
    <type>ratfun</type>
    <type>vector</type>
    <type>zmod</type>

    <key>product</key>
    <key>sum</key>
    <key>product, sum</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>Q</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Quit</title>
    <short_description>quit CoCoA</short_description>

    <description>
This command is used to quit CoCoA.  Note, it is issued as follows:

Quit;

without parentheses.
    </description>

    <syntax>
Quit
</syntax>

    <see>Ciao</see>

    <type>system</type>

    <key>quit</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>QuotientBasis</title>
    <short_description>vector space basis for zero-dimensional quotient rings</short_description>

    <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.

        
<example>
Points:=[[Rand(-9,9) | N In 1..3] | S In 1..25];
Use Q[x,y,z];
I:=IdealOfPoints(Points);
QuotientBasis(I);     -- power products underneath the DegRevLex reduced GBasis
[1, z, z^2, z^3, z^4, y, yz, yz^2, yz^3, y^2, y^2z, y^2z^2, y^3, x,
xz, xz^2, xz^3, xy, xyz, xyz^2, xy^2, x^2, x^2z, x^2y, x^3]
-------------------------------
Use Q[x,y,z],Lex;
I:=IdealOfPoints(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, z^13, 
y, yz, yz^2, yz^3, yz^4, yz^5, yz^6, y^2, y^2z, y^2z^2, y^2z^3]
------------------------------- 
</example>
    </description>

    <syntax>
QuotientBasis(I:IDEAL):LIST
</syntax>

    <see>IdealOfPoints</see>

    <type>ideal</type>

    <key>quotientbasis</key>
    <key>quotient basis</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>QZP, ZPQ</title>
    <short_description>change field for polynomials and ideals</short_description>

    <description>
These functions 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 QZP maps polynomials with rational coefficients to
polynomials with coefficients in a finite field; the function ZPQ
does the reverse, mapping a polynomial with finite field coefficients
into one with rational (actually, integer) coefficients.  The function
ZPQ 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::=Q[x,y,z];
F:=1/2*x^3+34/567*x*y*z-890;   -- a poly with rational coefficients
Use S::=Z/(101)[x,y,z];
QZP(F);                        -- compute its image with coeffs in Z/(101)
-50x^3 - 19xyz + 19
-------------------------------
G:=It;
Use R;
ZPQ(G);                        -- now map that result back to Q[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 Z/(101)[x,y,z]
0
------------------------------- 
</example>
    </description>

    <syntax>
QZP(F:POLY):POLY
ZPQ(F:POLY):POLY
QZP(F:LIST of POLY):LIST of POLY
ZPQ(F:LIST of POLY):LIST of POLY
QZP(I:IDEAL):IDEAL
ZPQ(I:IDEAL):IDEAL
</syntax>

    <see>Accessing Other Rings</see>
    <see>BringIn</see>
    <see>Image</see>
    <see>Ring Mappings: the Image Function</see>

    <type>ideal</type>
    <type>polynomial</type>
    <type>ring</type>

    <key>qzp</key>
    <key>zpq</key>
    <key>qzp, zpq</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>R</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Radical</title>
    <short_description>radical of an ideal</short_description>

    <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 ::= Q[x,y];
I := Ideal(x,y)^3;
Radical(I);
Ideal(y, x)
------------------------------- 
</example>
    </description>

    <syntax>
Radical(I:IDEAL):IDEAL
</syntax>

    <see>EquiIsoDec</see>
    <see>RadicalOfUnmixed</see>

    <type>groebner</type>
    <type>ideal</type>

    <key>radical</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RadicalOfUnmixed</title>
    <short_description>radical of an unmixed ideal</short_description>

    <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 ::= Q[x,y];
I := Ideal(x^2 - y^2 - 4x + 4y, x - 2);
-------------------------------
RadicalOfUnmixed(I);
Ideal(x^2 - y^2 - 4x + 4y, x - 2, y - 2)
-------------------------------
Minimalized(It); -- the result may not be presented in its simplest form
Ideal(x - 2, y - 2)
------------------------------- 
</example>
    </description>

    <syntax>
RadicalOfUnmixed(I:IDEAL):IDEAL
</syntax>

    <see>EquiIsoDec</see>
    <see>Radical</see>

    <type>groebner</type>
    <type>ideal</type>

    <key>radicalofunmixed</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Rand</title>
    <short_description>random integer</short_description>

    <description>
In the first form, the function returns a random integer.  In the
second, it returns a random integer between X and Y, inclusive. (Note:
|X-Y| should be less than <formula>2^33</formula> to assure a more random distribution.)

        
<example>
Rand();
6304433354
-------------------------------
Rand(1,100);
8
-------------------------------
Rand(100,1);
14
-------------------------------
Rand(-10^4,0);
-2747
------------------------------- 
</example>
    </description>

    <syntax>
Rand():INT
Rand(X:INT,Y:INT):INT
</syntax>

    <see>Randomize</see>
    <see>Randomized</see>
    <see>Seed</see>

    <type>integer</type>
    <type>miscellaneous</type>

    <key>rand</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Randomize</title>
    <short_description>randomize the coefficients of a given polynomial</short_description>

    <description>
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 <coderef>Randomized</coderef> performs the same operation,
but returns the randomized polynomial without modifying the argument. 

        
<example>
Use R ::= Q[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>

    <syntax>
Randomize(V:POLY):POLY

where V is a variable containing a polynomial.
</syntax>

    <see>Rand</see>
    <see>Randomized</see>

    <type>polynomial</type>

    <key>randomize</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Randomized</title>
    <short_description>randomize the coefficients of a given polynomial</short_description>

    <description>
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 <coderef>Randomize</coderef> performs the same operation,
but returns NULL and modifies the argument. 
        
<example>
Use R ::= Q[x];
F := 1+x+x^2;
Randomized(F);
-2917104644x^2 + 3623608766x - 2302822308
-------------------------------
F;
x^2 + x + 1
-------------------------------
Randomized(23);
-3997312402
-------------------------------
Use R ::= Z/(7)[x,y];
Randomized(x^2+3x-5);
3x^2 + 2x - 2
------------------------------- 
</example>
    </description>

    <syntax>
Randomized(F:POLY or INT):POLY or INT

where V is a variable containing a polynomial.
</syntax>

    <see>Rand</see>
    <see>Randomize</see>

    <type>polynomial</type>

    <key>randomized</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Rank</title>
    <short_description>rank of a module</short_description>

    <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 NumComps which simply counts the number of components the module has.

        
<example>
Use R ::= Q[x,y,z];
Rank(Module([x,y,z,0]));
1
-------------------------------
Rank(Module([[1,2,3],[2,4,6]]));
1
-------------------------------
Rank(Module([[1,2,3],[2,5,6]]));
2
------------------------------- 
</example>
    </description>

    <syntax>
Rank(M:MODULE):INT
Rank(M:MAT):INT
</syntax>

    <type>module</type>

    <key>rank</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RealRootRefine</title>
    <short_description>refine a root of a univariate polynomial over Q</short_description>

    <description>
This functions computes a refinement of a real root of a univariate
polynomial over Q to the desired precision (width of isolating
interval).  The starting root must be a record produced by RealRoots.


        
<example>
RR := RealRoots(x^2-2);
RealRootRefine(RR[1], 1/2);
Record[ CoeffList = [-8, 1456, -712], Inf = -91/64, Sup = -45/32]
-------------------------------
RR := [RealRootRefine(Root, 10^(-20)) | Root In RR];
FloatStr(RR[1].Inf);
-1.414213562*10^0
------------------------------- 
</example>
    </description>

    <syntax>
RealRootRefine(Root:RECORD, Precision:RAT):RECORD
</syntax>

    <see>RealRoots</see>
    <see>RootBound</see>

    <type>polynomial</type>

    <key>realrootrefine</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RealRoots</title>
    <short_description>computes a root of a univariate polynomial over Q</short_description>

    <description>
This function computes isolating intervals for the real roots of a
univariate polyomial over Q.  It returns the list of the real roots,
where a root is represented as a record containing either the exact root
(if the fields Inf and Sup 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 RealRootRefine.


        
<example>
RealRoots(x^2-2);
[Record[CoeffList = [8, -16, 7], Inf = -4, Sup = 0],
Record[CoeffList = [8, 0, -1], Inf = 0, Sup = 4]]
-------------------------------
RR := RealRoots((x^2-2)*(x-1), 10^(-5));
FloatStr(RR[1].Inf);  -- left end of interval
-1.414213657*10^0
-------------------------------
FloatStr(RR[1].Sup);  -- right end of interval
-1.414213419*10^0
-------------------------------
RR := RealRoots(x^2-2, 10^(-20), [0, 2]);
RR[1].Inf;                               -- incomprehensible
3339217363285192246361/2361183241434822606848
-------------------------------
FloatStr(RR[1].Inf, 20);                 -- comprehensible
1.4142135623730950488*10^0
------------------------------- 
</example>
    </description>

    <syntax>
RealRoots(F:POLY):LIST
RealRoots(F:POLY, Precision:RAT):LIST
RealRoots(F:POLY, Precision:RAT, Interval:[RAT,RAT]):LIST
</syntax>

    <see>RealRootRefine</see>
    <see>RootBound</see>

    <type>polynomial</type>

    <key>realroots</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Record</title>
    <short_description>create a record</short_description>

    <description>
This function returns a record with fields <code>X_1</code>,...,<code>X_n</code>.  The
empty record is given by <code>Record[]</code>.  The records are <em>open</em> in the
sense that new fields may be added after the record is first defined.

        
<example>
P := Record[ Height = 10, Width = 5];
P.Height * P.Width;
50
-------------------------------
P.Area := It;
P;
Record[Area = 50, Height = 10, Width = 5]
------------------------------- 
</example>
    </description>

    <syntax>
Record[X_1 = OBJECT,...,X_n = OBJECT]

where each X_i is a variable.
</syntax>

    <see>Fields</see>

    <type>record</type>

    <key>record</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ReducedGBasis</title>
    <short_description>compute a reduced Groebner basis</short_description>

    <description>
If M is an ideal or module, this function returns a list whose
components form a reduced Groebner basis for M with respect to the
term-ordering of the current ring.  If M is a quotient of the current
ring by an ideal I or of a free module by a submodule N, then the
Groebner basis for M is defined to be that of I or N, respectively.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(t^3-x,t^4-y,t^5-z);
GB.Start_GBasis(I);  -- start the Interactive Groebner Framework
GB.Step(I);  -- take one step towards computing the Groebner basis
I.GBasis;  -- the Groebner basis so far
[t^3 - x]
-------------------------------
GB.Complete(I);  -- finish the computation
I.GBasis;
[t^3 - x, -tx + y, -ty + z, -y^2 + xz, -x^2 + tz, t^2z - xy]
-------------------------------
ReducedGBasis(I);
[t^3 - x, tx - y, ty - z, y^2 - xz, x^2 - tz, t^2z - xy]
------------------------------- 
</example>
    </description>

    <syntax>
ReducedGBasis(M:IDEAL, MODULE, or TAGGED(<coc-quotes>Quotient</coc-quotes>)):LIST
</syntax>

    <see>Introduction to Groebner Bases in CoCoA</see>
    <see>The Interactive Groebner Framework</see>

    <type>groebner</type>
    <type>groebner-interactive</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>reducedgbasis</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RegularityIndex</title>
    <short_description>regularity index of a Hilbert function or series</short_description>

    <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 ::= Q[x,y,z];
  Quot := R/Ideal(x^3, y^2);
  HilbertFn(Quot);
H(0) = 1
H(1) = 3
H(2) = 6
H(3) = 10
H(4) = 15
H(t) = 7t - 14   for t >= 5
-------------------------------
  RegularityIndex(Hilbert(Quot));
3
-------------------------------
  RegularityIndex(Poincare(Quot));
3
-------------------------------
</example>
    </description>

    <syntax>
Multiplicity(R:RING or TAGGED(<coc-quotes>Quotient</coc-quotes>)):INT
</syntax>

    <see>Hilbert</see>
    <see>HilbertFn</see>
    <see>HilbertSeries</see>
    <see>Poincare</see>

    <type>hilbert</type>

    <key>regularityindex</key>
  </command>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RefineGCDFreeBasis</title>
    <short_description>refine an integer GCD free basis</short_description>

    <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(GCDFreeBasis([Fact(10),Bin(20,10)]);
[14175, 4, 46189]
-------------------------------
RefineGCDFreeBasis(B, 15);
[[7, 3, 5, 4, 46189], 1]
-------------------------------

</example>
    </description>

    <syntax>
RefineGCDFreeBasis(B:LIST of INT, N:INT):LIST of INT
    
</syntax>

    <see>GCDFreeBasis</see>

    <type>int</type>

    <key>refinegcdfreebasis</key>
    <key>greatest common divisor</key>

  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Remove</title>
    <short_description>remove an object in a list</short_description>

    <description>
This function removes the N-th component from L.  (The function
<coderef>WithoutNth</coderef> returns the list obtained by removing the N-th component
of L without affecting L, itself.) 

        
<example>
Use R ::= Q[x,y,z];
L := Indets();
L;
[x, y, z]
-------------------------------
Remove(L,2);
L;
[x, z]
------------------------------- 
</example>
    </description>

    <syntax>
Remove(V:LIST,N:INT):NULL

where V is a variable containing a list.
</syntax>

    <see>Insert</see>
    <see>WithoutNth</see>

    <type>list</type>

    <key>remove</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Repeat</title>
    <short_description>loop command</short_description>

    <description>
In the first form, the command sequence C is repeated until B
evaluates to FALSE.  Unlike the <code>While</code> command, C is executed at
least once.  Note that there is no <code>EndRepeat</code> following B.  In the
second form, the command sequence C is repeated until a <code>Break</code> or
<code>Return</code> is encountered within C.

        
<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);
  Return If N = 5;
EndRepeat;
1
2
3
4
5

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

    <syntax>
Repeat C Until B
Repeat C EndRepeat

where C is a sequence of commands and B is a boolean expression.
</syntax>

    <see>For</see>
    <see>Foreach</see>
    <see>While</see>

    <type>programming</type>
    <type>loops</type>

    <key>repeat</key>
    <key>until</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Res</title>
    <short_description>free resolution</short_description>

    <description>
This function returns the minimal free resolution of M.  If M is a
quotient of the current ring by an ideal I or a quotient of a free
module by a submodule N, then the resolution of M is defined
to be that of I or N, respectively.

<par/>
<code>Res</code> only works in the homogeneous context, and the coefficient ring
must be a field.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x,y,z^2);
Res(R/I);
0 --&gt; R(-4) --&gt; R(-2)(+)R^2(-3) --&gt; R^2(-1)(+)R(-2) --&gt; R
-------------------------------
Describe It;

Mat([
  [y, x, z^2]
])
Mat([
  [x, z^2, 0],
  [-y, 0, z^2],
  [0, -y, -x]
])
Mat([
  [z^2],
  [-x],
  [y]
])
-------------------------------
</example>

For fine control and monitoring of Groebner basis calculations,
including various types of truncations, see <ref>The Interactive Groebner
Framework</ref> and <ref>Introduction to Panels</ref>. 
    </description>

    <syntax>
Res(M):TAGGED(<coc-quotes>$gb.Res</coc-quotes>)

where M is of type IDEAL or MODULE or TAGGED(<coc-quotes>Quotient</coc-quotes>).
</syntax>

    <see>Example: Interactive Resolution Computation</see>
    <see>Example: Truncations</see>
    <see>Introduction to Groebner Bases in CoCoA</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>res</key>
    <key>resolutions</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Resultant</title>
    <short_description>the resultant of two polynomials</short_description>

    <description>
This function returns the resultant of the polynomials F and G with
respect to the indeterminate X.

        
<example>
Use R ::= Q[p,q,x];
F := x^3+px-q; G := Der(F,x);
Resultant(F,G,x);
4p^3 + 27q^2
------------------------------- 
</example>
    </description>

    <syntax>
Resultant(F:POLY,G:POLY,X:INDET):POLY
</syntax>

    <see>Discriminant</see>
    <see>Sylvester</see>

    <type>polynomial</type>

    <key>resultant</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Reset</title>
    <short_description>reset panels and random number seed to defaults</short_description>

    <description>
This function resets the options in the CoCoA panels to their default
values and executes <code>Seed(0)</code>.

        
<example>
Set Indentation;
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : TRUE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
-------------------------------
Reset();
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
------------------------------- 
</example>
    </description>

    <syntax>
Reset():NULL
</syntax>

    <see>Introduction to Panels</see>
    <see>ResetPanels</see>
    <see>Seed</see>

    <type>panels</type>
    <type>system</type>

    <key>reset</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ResetPanels</title>
    <short_description>reset panels to their default values</short_description>

    <description>
This function resets the options in the CoCoA panels to their default
values.

        
<example>
Set Indentation;
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : TRUE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
-------------------------------
ResetPanels();
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
------------------------------- 
</example>
    </description>

    <syntax>
ResetPanels():NULL
</syntax>

    <see>Introduction to Panels</see>
    <see>Reset</see>

    <type>panels</type>
    <type>system</type>

    <key>resetpanels</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Return</title>
    <short_description>exit from a structured command</short_description>

    <description>
This function is used to exit from a structured command.  The latter
form returns the value of the expression E to the user.  If executed
within a nested loop or inside a user-defined function, it breaks out
back to the <em>top level</em>, not just to the next higher loop.  (For
breaks to the next higher loop, see <coderef>Break</coderef>.)

        
<example>
Define Rev(L) -- reverse a list
  If Len(L) &lt; 2 Then Return L EndIf;
  M := Rev(Tail(L)); -- recursive function call
  H := Head(L);
  Return Concat(M,[H]);
EndDefine;
Rev([1,2,3,4];
[4, 3, 2, 1]
-------------------------------
-- Another example: returning from a nested loop
For I := 1 To 5 Do
  For J := 1 To 5 Do
    If J &gt; 2 Then Return Else Print([I,J], <coc-quotes> </coc-quotes>) EndIf
  EndFor;
EndFor;
[1, 1] [1, 2] 
------------------------------- 
</example>
    </description>

    <syntax>
Return
Return E

where E is an expression.
</syntax>

    <see>Break</see>
    <see>Define</see>

    <type>function</type>
    <type>loops</type>

    <key>return</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Reverse, Reversed</title>
    <short_description>reverse a list</short_description>

    <description>
The the function <code>Reverse</code> reverses the order of the elements of the
list in V, returning Null.  It does *not* return the reversed list,
but instead changes L itself.  The function <code>Reversed</code> returns the
reversed list without changing L.

        
<example>
L := [1,2,3,4];
Reverse(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>

    <syntax>
Reverse(V:LIST):NULL
Reversed(L:LIST):NULL

where V is a variable containing a list in the first case.
</syntax>

    <see>Sort</see>
    <see>Sorted</see>

    <type>list</type>

    <key>reverse</key>
    <key>reversed</key>
    <key>reverse, reversed</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RevLexMat</title>
    <short_description>matrices for std. term-orderings</short_description>

    <description>
This function return the matrix defining a standard ordering (which is
not a term-ordering!).

        
<example>
RevLexMat(3);
Mat([
  [0, 0, -1],
  [0, -1, 0],
  [-1, 0, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
RevLexMat(N:INTEGER):MAT
</syntax>

    <see>Ord</see>
    <see>Orderings</see>
    <see>DegRevLexMat</see>
    <see>DegLexMat</see>
    <see>LexMat</see>
    <see>XelMat</see>

    <type>matrix</type>

    <key>xelmat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Ring</title>
    <short_description>returns the ring with a given name</short_description>

    <description>
This function returns the ring with identifier R.

        
<example>
Use R ::= Q[x,y,z];
S ::= Z/(3)[a,b];
Ring(S);
Z/(3)[a,b]
-------------------------------
Ring(R);
Q[x,y,z]
-------------------------------
R;  -- same as above, as long as there is no variable with identifier
    -- R in the working memory
Q[x,y,z]
-------------------------------
CurrentRing();
Q[x,y,z]
-------------------------------
R := 5;  -- a variable with identifier R; now there are two objects
         -- with the identifier R: a variable and a ring
R;
5
-------------------------------
Memory();  -- the variables of the working memory
[<coc-quotes>It</coc-quotes>, <coc-quotes>R</coc-quotes>]
-------------------------------
RingEnvs();  -- the list of rings
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Ring(R);  -- the ring with identifier R
Q[x,y,z]
------------------------------- 
</example>
    </description>

    <syntax>
Ring(R:RING):RING
</syntax>

    <see>CurrentRing</see>
    <see>Introduction to Rings</see>
    <see>RingEnv</see>
    <see>RingEnvs</see>

    <type>ring</type>

    <key>ring</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RingEnv</title>
    <short_description>name of the current ring</short_description>

    <description>
The first form of this function returns the identifier for the
current ring.  The second form returns the identifier of the ring on
which the object E is dependent.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x,y);  -- an object dependent on R
S ::= Z/(3)[a,b];  -- define S, but do not make S active
RingEnv();  -- the current ring
R
-------------------------------
RingEnvs();  -- your result here could be different
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Ring(S);
Z/(3)[a,b]
-------------------------------
I;
Ideal(x, y)
-------------------------------
Use S;  -- S is now the active ring
I;  -- I is labeled by its ring.  The label appears explicitly when R
    -- is not the current ring.
R :: Ideal(x, y)
-------------------------------
RingEnv(I);  -- the ring labeling I
R
-------------------------------
CurrentRing();
Q[x,y,z]
-------------------------------
Use Q[ab];
RingEnv();
CurrentRingEnv
------------------------------- 
</example>
    </description>

    <syntax>
RingEnv():STRING
RingEnv(E:POLY, IDEAL, MODULE, RATFUN, VECTOR):STRING
</syntax>

    <see>CurrentRing</see>
    <see>Ring</see>
    <see>RingEnvs</see>

    <type>ring</type>

    <key>ringenv</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RingEnvs</title>
    <short_description>names of all defined rings</short_description>

    <description>
This function returns the tagged list of identifiers for the existing
rings.

        
<example>
R_1 ::= Q[a,b,c];
R_2 ::= Q[x,y];
RingEnvs();   -- your result may be different
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>R_1</coc-quotes>, <coc-quotes>R_2</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
RingEnvs():TAGGED
</syntax>

    <see>CurrentRing</see>
    <see>Ring</see>
    <see>RingEnv</see>

    <type>ring</type>
    <type>memory</type>

    <key>ringenvs</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>RootBound</title>
    <short_description>bound on roots of a polynomial over Q</short_description>

    <description>
This function computes a bound on the absolute values of the complex
roots of a univariate polynomial over Q.

        
<example>
RootBound(x^2-2);
4
------------------------------- 
</example>
    </description>

    <syntax>
RootBound(F:POLY):INT
</syntax>

    <see>RealRootRefine</see>
    <see>RealRoots</see>

    <type>polynomial</type>

    <key>rootbound</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>S</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Saturation</title>
    <short_description>saturation of ideals</short_description>

    <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 ::= Q[x,y,z];
I := Ideal(x-z, y-2z);
J := Ideal(x-2z, 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
-------------------------------
Saturation(L, Ideal(x,y,z)) = K; -- saturating gets rid of the
                                 -- irrelevant component
TRUE
------------------------------- 
</example>
    </description>

    <syntax>
Saturation(I:IDEAL,J:IDEAL):IDEAL
</syntax>

    <see>Colon</see>
    <see>HColon</see>
    <see>HSaturation</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>

    <key>saturation</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>ScalarProduct</title>
    <short_description>scalar product</short_description>

    <description>
This function returns the sum of the product of the components of L
and M; precisely: 

<par/>
  ScalarProduct(L,M) = Sum([L[I]*M[I]|I In 1..Min(Len(L),Len(M))])).

<par/>
Thus, the function works even if the lengths of L and M are different.
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
-------------------------------
ScalarProduct([1,2,3],[5,0]);
5
-------------------------------
Use R ::= Q[x,y];
ScalarProduct([Ideal(x,y),Ideal(x^2-xy)],[x^2,y]);
Ideal(x^3, x^2y, x^2y - xy^2)
------------------------------- 
</example>
    </description>

    <syntax>
ScalarProduct(L, M):OBJECT

where each of L and M is of type VECTOR or LIST
</syntax>

    <see>Algebraic Operators</see>

    <type>list</type>
    <type>vector</type>

    <key>scalarproduct</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Seed</title>
    <short_description>seed for <code>Rand</code></short_description>

    <description>
This function seeds the random number generator, <coderef>Rand</coderef>.

        
<example>
Seed(5);
Rand();
1991603592
-------------------------------
Rand();
-1650270230
-------------------------------
Seed(5);  -- with the same seed, <coc-quotes>Rand</coc-quotes> generates the same sequence
Rand();
1991603592
-------------------------------
Rand();
-1650270230
-------------------------------
-- The following shows how to make a seed based on the date.
D := Date();
D;
Mon Mar 02 14:43:44 1998
-------------------------------
F := Sum([Ascii(D[N])| N In 1..Len(D)]);
F;
[1455]
-------------------------------
Seed(F[1]); 
</example>
    </description>

    <syntax>
Seed(N:INT):INT
</syntax>

    <see>Rand</see>

    <type>integer</type>
    <type>miscellaneous</type>

    <key>seed</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SeparatorsOfPoints</title>
    <short_description>separators for affine points</short_description>

    <description>
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 <coderef>IdealOfPoints</coderef>.

<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
<coderef>SeparatorsOfProjectivePoints</coderef>.  

        
<example>
Use R ::= Q[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>

    <syntax>
SeparatorsOfPoints(Points:LIST):LIST

where Points is a list of lists of coefficients representing a set of
*distinct* points in affine space.
</syntax>

    <see>GenericPoints</see>
    <see>IdealAndSeparatorsOfPoints</see>
    <see>IdealAndSeparatorsOfProjectivePoints</see>
    <see>IdealOfPoints</see>
    <see>IdealOfProjectivePoints</see>
    <see>Interpolate</see>
    <see>SeparatorsOfProjectivePoints</see>

    <type>list</type>
    <type>points</type>

    <key>separatorsofpoints</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SeparatorsOfProjectivePoints</title>
    <short_description>separators for projective points</short_description>

    <description>
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 <coderef>IdealOfProjectivePoints</coderef>.

<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
<coderef>SeparatorsOfPoints</coderef>.  

        
<example>
Use R ::= Q[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>

    <syntax>
SeparatorsOfProjectivePoints(Points:LIST):LIST

where Points is a list of lists of coefficients representing a set of
*distinct* points in projective space.
</syntax>

    <see>GenericPoints</see>
    <see>IdealAndSeparatorsOfPoints</see>
    <see>IdealAndSeparatorsOfProjectivePoints</see>
    <see>IdealOfPoints</see>
    <see>IdealOfProjectivePoints</see>
    <see>Interpolate</see>
    <see>SeparatorsOfPoints</see>

    <type>list</type>
    <type>points</type>

    <key>separatorsofprojectivepoints</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Set</title>
    <short_description>remove duplicates from a list</short_description>

    <description>
This function returns a list obtained by removing duplicates from L.

        
<example>
Set([2,2,2,1,2,1,1,3,3]);
[2, 1, 3]
------------------------------- 
</example>

WARNING: to test two sets for equality use the function EqSet instead
of a normal equality test (because the latter yields false if the
elements are in a different order).

<par/>
NOTE: there is a command named <code>Set</code> for setting panel options.  Its
search key in the online help is <coderef>Unset</coderef>.  The search key for the
present function is <code>Set</code>.
    </description>

    <syntax>
Set(L:LIST):LIST
</syntax>

    <see>EqSet</see>
    <see>Intersection</see>
    <see>IntersectionList</see>
    <see>Insert</see>
    <see>Remove</see>

    <type>list</type>

    <key>set</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Set-Unset</title>
    <short_description>set and unset panel options</short_description>

    <description>
See <coderef>Unset</coderef>.
    </description>

    <syntax>
Set O
Set O := B:BOOL
UnSet O

where O is a panel option.
    </syntax>

    <see>Unset</see>
    <see>Introduction to Panels</see>
    <see>Panel</see>
    <see>Option</see>
    <see>Panels</see>

    <type>panels</type>
    <type>system</type>

    <key>set-unset</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Shape</title>
    <short_description>extended list of types involved in an expression</short_description>

    <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, <code>Shape(E)</code> is the type of E.

        
<example>
Use R ::= Q[x]; 
L := [1,[1,<coc-quotes>a</coc-quotes>],x^2-x];
Shape(L);
[INT, [INT, STRING], POLY]
-------------------------------
R := Record[Name = <coc-quotes>test</coc-quotes>, Contents = L];
Shape(R);
Record[Contents = [INT, [INT, STRING], POLY], Name = STRING]
-------------------------------
It.Name;
STRING
------------------------------- 
</example>

There are undocumented functions, <code>IsSubShape</code> and <code>IsSubShapeOfSome</code>,
for determining if the <code>shape</code> of a CoCoA expression is a <code>subshape</code>
of another.  To see the code for these functions, enter 
<verbatim>
Describe Function(<coc-quotes>$misc.IsSubShape</coc-quotes>);
Describe Function(<coc-quotes>$misc.IsSubShapeOfSome</coc-quotes>);
</verbatim>
    </description>

    <syntax>
Shape(E:LIST):LIST (of TYPE)
Shape(E:MAT):MAT (of TYPE)
Shape(E:RECORD):RECORD (of TYPE)
Shape(E:OTHER):TYPE

where OTHER stands for a type which is not LIST, MAT, or RECORD.
</syntax>

    <see>Data Types</see>

    <type>type</type>

    <key>shape</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Size</title>
    <short_description>the amount of memory used by an object</short_description>

    <description>
This function returns the amount of memory used by the object E,
expressed in words (1 word = 4 bytes = 32 bits).

        
<example>
Use R ::= Q[x,y];
Size(1);
1
-------------------------------
Size(2^32-1);
1
-------------------------------
Size(2^32);
2
-------------------------------
Size(2^64);
3
-------------------------------
Size(x);
32
-------------------------------
Size([x,y]);
64
------------------------------- 
</example>
    </description>

    <syntax>
Size(E:OBJECT):INT
</syntax>

    <see>Count</see>
    <see>Len</see>

    <type>ideal</type>
    <type>integer</type>
    <type>list</type>
    <type>matrix</type>
    <type>memory</type>
    <type>module</type>
    <type>polynomial</type>
    <type>ratfun</type>
    <type>vector</type>

    <key>size</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Skip</title>
    <short_description>does nothing</short_description>

    <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 <code>Tao</code>.

        
<example>
Skip; 
</example>
    </description>

    <syntax>
Skip
</syntax>

    <type>miscellaneous</type>
    <type>programming</type>

    <key>skip</key>
    <key>tao</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Sort</title>
    <short_description>sort a list</short_description>

    <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 <coderef>SortBy</coderef>, <coderef>SortedBy</coderef>.

        
<example>
L := [3,2,1];
Sort(L);  -- this returns nothing and modifies L
L;
[1, 2, 3]
-------------------------------
Use R ::= Q[x,y,z];
L := [x,y,z];
Sort(L);  -- this returns nothing and modifies L
L[1];
z
-------------------------------
Sort([y,x,z,x^2]);  -- this returns nothing!!
Sorted([y,x,x^2]);  -- this returns the sorted list
[y, x, x^2]
-------------------------------
</example>
    </description>

    <syntax>
Sort(V:LIST):NULL

where V is a variable containing a list.
</syntax>

    <see>Relational Operators</see>
    <see>Sorted</see>
    <see>SortBy</see>
    <see>SortedBy</see>

    <type>list</type>

    <key>sort</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Sorted</title>
    <short_description>sort a list</short_description>

    <description>
This function returns the list of the sorted elements of L without
affecting L, itself.

For more on the default comparisons, see <ref>Relational Operators</ref>
in the chapter on operators.
For more complicated sorting, see <coderef>SortBy</coderef>, <coderef>SortedBy</coderef>.

        
<example>
L := [3,2,1];
Sorted(L);
[1, 2, 3]
-------------------------------
Use R ::= Q[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([<coc-quotes>b</coc-quotes>,<coc-quotes>c</coc-quotes>,<coc-quotes>a</coc-quotes>]);
[<coc-quotes>a</coc-quotes>, <coc-quotes>b</coc-quotes>, <coc-quotes>c</coc-quotes>]
-------------------------------
Sorted([Ideal(x,y),Ideal(x)]); -- ideals are ordered by containment
[Ideal(x), Ideal(x, y)]
------------------------------- 
</example>
    </description>

    <syntax>
Sorted(L:LIST):LIST

where V is a variable containing a list.
</syntax>

    <see>Relational Operators</see>
    <see>SortBy</see>
    <see>SortedBy</see>
    <see>Sort</see>

    <type>list</type>

    <key>sorted</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SmoothFactor</title>
    <short_description>find small prime factors of an integer</short_description>

    <description>
This function finds the small prime factors of an integer.  It simply
tries dividing by all primes up to the given bound.  The result is a
list of the prime factors found together with the unfactored part of N.
Be careful about supplying large values for MaxP (e.g. greater than a
million): the function could take a very long time.  MaxP must be positive.

<example>
SmoothFactor(100,3);
[[2, 2], 25]
-------------------------------
SmoothFactor(123456789,3700);
[[3, 3, 3607, 3803], 1]
-------------------------------

</example>
    </description>

    <syntax>
SmoothFactor(N:INT, MaxP:INT):[LIST of INT, INT]
    
</syntax>

    <see>IsPrime</see>
    <see>IsPPrime</see>

    <type>int</type>
    <type>list</type>

    <key>smoothfactor</key>
    <key>small prime factors</key>
    <key>partial factorization</key>

  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SortBy</title>
    <short_description>sort a list</short_description>

    <description>
This function sorts the elements of the list in V with respect
to the comparisons made by F; it overwrites V and returns NULL.

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 := [<coc-quotes>dog</coc-quotes>,<coc-quotes>mouse</coc-quotes>,<coc-quotes>cat</coc-quotes>];
SortBy(M, Function(<coc-quotes>ByLength</coc-quotes>));
M;
[<coc-quotes>mouse</coc-quotes>, <coc-quotes>dog</coc-quotes>, <coc-quotes>cat</coc-quotes>]
-------------------------------
</example>
    </description>

    <syntax>
SortBy(V:LIST,F:FUNCTION):NULL

where V is a variable containing a list and F is a boolean-valued
comparison function of two arguments (e.g. representing <em>less than</em>).
</syntax>

    <see>Sort</see>
    <see>Sorted</see>
    <see>SortedBy</see>

    <type>list</type>

    <key>sortby</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SortedBy</title>
    <short_description>sort a list</short_description>

    <description>
This function returns the list of the sorted elements of L without
affecting L, itself.  As for <coderef>SortBy</coderef>, 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 := [<coc-quotes>dog</coc-quotes>,<coc-quotes>mouse</coc-quotes>,<coc-quotes>cat</coc-quotes>];
SortedBy(M,Function(<coc-quotes>ByLength</coc-quotes>));
[<coc-quotes>mouse</coc-quotes>, <coc-quotes>dog</coc-quotes>, <coc-quotes>cat</coc-quotes>]
-------------------------------
M;  -- M is not changed
[<coc-quotes>dog</coc-quotes>, <coc-quotes>mouse</coc-quotes>, <coc-quotes>cat</coc-quotes>]
-------------------------------
Sorted(M);  -- the function <coc-quotes>Sort</coc-quotes> sorts using the default ordering:
            -- in this case, alphabetical order.
[<coc-quotes>cat</coc-quotes>, <coc-quotes>dog</coc-quotes>, <coc-quotes>mouse</coc-quotes>]
-------------------------------
SortBy(M,Function(<coc-quotes>ByLength</coc-quotes>));  -- sort M in place, changing M
M;
[<coc-quotes>mouse</coc-quotes>, <coc-quotes>dog</coc-quotes>, <coc-quotes>cat</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
SortedBy(L:LIST,F:FUNCTION):LIST

where V is a variable containing a list and F is a boolean-valued
comparison function of two arguments (e.g. representing <em>less than</em>).
</syntax>

    <see>Sort</see>
    <see>Sorted</see>
    <see>SortBy</see>

    <type>list</type>

    <key>sortedby</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Source</title>
    <short_description>read commands from a file or device</short_description>

    <description>
This command executes all CoCoA commands in the file or device named
S.  A typical use of <code>Source</code> is to collect user-defined functions and
variables in a text file, say, <code>MyFile.coc</code> and then execute:
<verbatim>
    Source <coc-quotes>MyFile.coc</coc-quotes>;
</verbatim>
or, equivalently,
<verbatim>
    &lt;&lt; <coc-quotes>MyFile.coc</coc-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 <code>Source</code> in the 
<code>userinit.coc</code> file.
    </description>

    <syntax>
Source S:STRING
&lt;&lt; S:STRING
</syntax>

    <see>Introduction to IO</see>
    <see>Introduction to Packages</see>
    <see>User Initialization</see>
    <see><formula>&lt;&lt;</formula></see>

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

    <key>source</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Spaces</title>
    <short_description>return a string of spaces</short_description>

    <description>
This function returns a string consisting of N spaces.

        
<example>
L := <coc-quotes>a</coc-quotes> + Spaces(5) + <coc-quotes>b</coc-quotes>;
L;
a     b
------------------------------- 
</example>
    </description>

    <syntax>
Spaces(N:INT):STRING
</syntax>

    <see>Dashes</see>
    <see>Equals</see>

    <type>string</type>

    <key>spaces</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Sprint</title>
    <short_description>convert to a string</short_description>

    <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 ::= Q[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 <coc-quotes>Ideal(x, y)</coc-quotes>.
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>

    <syntax>
Sprint(E:OBJECT):STRING
</syntax>

    <see>Introduction to IO</see>
    <see>IO.SprintTrunc</see>
    <see>Print</see>
    <see>PrintLn</see>

    <type>io</type>
    <type>printing</type>
    <type>string</type>

    <key>sprint</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>StarPrint</title>
    <short_description>print polynomial with *&apos;s for multiplications</short_description>

    <description>
These functions print the polynomial F with asterisks added to denote
multiplications.  They may be useful when cutting and pasting from
CoCoA to other mathematical software.  StarPrint inserts newline
characters (only between terms) to avoid lines much longer than about
70 characters.  If a different approximate maximum length is desired
this may be specified as the second argument to StarPrintFold; a
negative value means no line length limit.

        
<example>
Use R ::= Q[x,y];
F := x^3+2xy-y^2;
StarPrint(F);
1*x^3+2*x*y-1*y^2
-------------------------------
StarPrintFold(F,0); -- this will print one term per line
1*x^3
+2*x*y
-1*y^2
------------------------------- 
</example>
    </description>

    <syntax>
StarPrint(F:POLY):NULL
StarPrintFold(F:POLY, LineWidth:INT)
</syntax>

    <type>polynomial</type>

    <key>starprint</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Starting</title>
    <short_description>list functions starting with a given string</short_description>

    <description>
This function returns a list of all CoCoA functions starting with the
string <code>S</code>.  In general, this list will include undocumented
commands.  For these, one may find some information using
<code>Describe Function(<coc-quotes>Fn_Name</coc-quotes>)</code> or 
<code>Describe Function(<coc-quotes>$PackageName.Fn_Name</coc-quotes>)</code>.

        
<example>
Starting(<coc-quotes>Su</coc-quotes>);
[<coc-quotes>SubstPoly</coc-quotes>, <coc-quotes>Support</coc-quotes>, <coc-quotes>Subsets</coc-quotes>, <coc-quotes>SubSet</coc-quotes>, <coc-quotes>Submat</coc-quotes>, <coc-quotes>Sum</coc-quotes>, <coc-quotes>Subst</coc-quotes>]
------------------------------- 
</example>
    </description>

    <syntax>
Starting(S:STRING):LIST of STRING
</syntax>

    <see>Other Help</see>

    <type>help</type>
    <type>miscellaneous</type>

    <key>starting</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Submat</title>
    <short_description>submatrix</short_description>

    <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);
Mat([
  [3, 4, 5],
  [13, 14, 15]
])
-------------------------------
L := [[1,2,3],[4,5,6]];
Submat(L,[2],[1,3]);
Mat([
  [4, 6]
])
------------------------------- 
</example>
    </description>

    <syntax>
Submat(M:LIST or MAT,R:LIST of INT,C:LIST of INT):MAT
</syntax>

    <see>Introduction to Matrices</see>
    <see>Minors</see>

    <type>list</type>
    <type>matrix</type>

    <key>submat</key>
    <key>submatrix</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Subsets</title>
    <short_description>returns all sublists of a list</short_description>

    <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(Set([2,3,3]));
[[ ], [3], [2], [2, 3]]
------------------------------- 
</example>
    </description>

    <syntax>
Subsets(S:LIST):LIST
Subsets(S:LIST, N:INT):LIST
</syntax>

    <see>IsSubset</see>
    <see>Partitions</see>
    <see>Permutations</see>
    <see>Set</see>
    <see>Tuples</see>

    <type>list</type>

    <key>subsets</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Subst</title>
    <short_description>substitute values for indeterminates</short_description>

    <description>
The first form of this function substitutes <code>F_i</code> for <code>X_i</code> 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 <coderef>Eval</coderef>.

        
<example>
Use R ::= Q[x,y,z,t];
F := x+y+z+t^2;
Subst(F,x,-2);
t^2 + y + z - 2
-------------------------------
Subst(F,x,z/y);
(yt^2 + y^2 + yz + z)/y
-------------------------------
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,3z-x]];
Subst(xyzt,MySubst);  -- substitute into the function xyzt
-x^2z + 3xz^2
------------------------------- 
</example>
    </description>

    <syntax>
Subst(E:OBJECT,X,F):OBJECT
Subst(E:OBJECT,[[X_1,F_1],...,[X_r,F_r]]):OBJECT

where each X or X_i is an indeterminate and each F or F_i is a number,
polynomial, or rational function.
</syntax>

    <see>Eval</see>
    <see>Evaluation of Polynomials</see>
    <see>Image</see>
    <see>QZP, ZPQ</see>
    <see>Substitutions</see>

    <type>polynomial</type>
    <type>ratfun</type>

    <key>subst</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Support</title>
    <short_description>the list of terms of a polynomial or vector</short_description>

    <description>
This function returns the list of terms of F.  To get a list of
monomials, which includes coefficients, use <coderef>Monomials</coderef>.

        
<example>
Use R ::= Q[x,y];
F := 3x^2-4xy+y^3+3;
Support(F);
[y^3, x^2, xy, 1]
-------------------------------
Monomials(F);
[y^3, 3x^2, -4xy, 3]
-------------------------------
Support(Vector(x^2y,x^3-3y^2,34));
[Vector(0, x^3, 0), Vector(x^2y, 0, 0), Vector(0, y^2, 0), Vector(0, 0, 1)]
------------------------------- 
</example>
    </description>

    <syntax>
Support(F:POLY or VECTOR):LIST
</syntax>

    <see>Coefficients</see>
    <see>Monomials</see>

    <type>polynomial</type>
    <type>vector</type>

    <key>support</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Sylvester</title>
    <short_description>the Sylvester matrix of two polynomials</short_description>

    <description>
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 ::= Q[p,q,x];
F := x^3+px-q; G := Der(F,x);
Sylvester(F,G,x);
Mat([
  [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>

    <syntax>
Sylvester(F:POLY,G:POLY,X:INDET)
</syntax>

    <see>Resultant</see>

    <type>polynomial</type>

    <key>sylvester</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Syz</title>
    <short_description>syzygy modules</short_description>

    <description>
In the first two forms this function computes the syzygy module of a list
of polynomials or vectors.  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.

<par/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[x,y,z];
Syz([x^2-y,xy-z,xy]);
Module([0, xy, -xy + z], [z, x^2 - y, -x^2 + y], [yz, -y^2, y^2 - xz],
[xy, 0, -x^2 + y])
-------------------------------
I := Ideal(x^2-yz, xy-z^2, xyz);
Syz(I,0);
Module([x^2 - yz], [xy - z^2], [xyz])
-------------------------------
Syz(I,1);
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 --&gt; R^2(-6) --&gt; R(-4)(+)R^3(-5) --&gt; R^2(-2)(+)R(-3)
-------------------------------

For fine control and monitoring of Groebner basis calculations, see
<ref>The Interactive Groebner Framework</ref> and <ref>Introduction to Panels</ref>. 
</example>
    </description>

    <syntax>
Syz(L:LIST of POLY):MODULE
Syz(L:LIST of VECTOR):MODULE
Syz(M:IDEAL or MODULE, Index:INT):MODULE
</syntax>

    <see>Introduction to Groebner Bases in CoCoA</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>list</type>
    <type>module</type>

    <key>syz</key>
    <key>syzygies</key>
    <key>syzygy</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SyzMinGens</title>
    <short_description>syzygy module for a set of minimal generators</short_description>

    <description>

The SyzMinGens function has been removed.

    </description>

    <syntax>
SyzMinGens:  FUNCTION ELIMINATED
</syntax>

    <see>Syz</see>
    <see>SyzOfGens</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>syzmingens</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>SyzOfGens</title>
    <short_description>syzygy module for a given set of generators</short_description>

    <description>
If M is an ideal or module, this function calculates the syzygy
module for the given set of generators of M.  If M is a quotient of
the current 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/>
The coefficient ring must be a field.

        
<example>
Use R ::= Q[x,y];
I := Ideal(x,y,x+y);
SyzOfGens(I);
Module([1, 1, -1], [y, -x, 0])
------------------------------- 
</example>
    </description>

    <syntax>
SyzOfGens(M:IDEAL, MODULE, or TAGGED(<coc-quotes>Quotient</coc-quotes>)):MODULE
</syntax>

    <see>Syz</see>
    <see>SyzMinGens</see>

    <type>groebner</type>
    <type>groebner-basic</type>
    <type>ideal</type>
    <type>module</type>
    <type>quotient</type>

    <key>syzofgens</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>T</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Tag</title>
    <short_description>returns the tag string of an object</short_description>

    <description>
If E is a tagged object, this function returns the tag of E;
otherwise, it returns the empty string.
        
<example>
L := Tagged(3,<coc-quotes>MyTag</coc-quotes>);
Type(L);
TAGGED(<coc-quotes>MyTag</coc-quotes>)
-------------------------------
Tag(L);
MyTag
------------------------------- 
</example>
    </description>

    <syntax>
Tag(E:OBJECT):STRING
</syntax>

    <see>Tagged Printing</see>
    <see>Tagged</see>
    <see>Untagged</see>

    <type>io</type>
    <type>printing</type>
    <type>tags</type>

    <key>tag</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Tagged</title>
    <short_description>tag an object for pretty printing</short_description>

    <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,<coc-quotes>MyTag</coc-quotes>);
Type(L);
LIST
-------------------------------
Type(M);
TAGGED(<coc-quotes>MyTag</coc-quotes>)
-------------------------------
Type(Untagged(M));
LIST
-------------------------------
</example>
    </description>

    <syntax>
Tagged(E:OBJECT,S:STRING):TAGGED(S)
</syntax>

    <see>Tagged Printing</see>
    <see>Tag</see>
    <see>Untagged</see>

    <type>io</type>
    <type>printing</type>
    <type>tags</type>

    <key>tagged</key>
    <key>tag an object</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Tail</title>
    <short_description>remove the first element of a list</short_description>

    <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>

    <syntax>
Tail(L:LIST):OBJECT
</syntax>

    <see>First</see>
    <see>Head</see>
    <see>Last</see>

    <type>list</type>

    <key>tail</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>TensorMat</title>
    <short_description>returns the tensor product of two matrices</short_description>

    <description>
This function returns the tensor product of two matrices.

        
<example>
Use R ::= Q[x,y,z,w];
TensorMat(Mat([[1,-1],[2,-2],[3,-3]]),Mat([[x,y],[z,w]]));
Mat([
  [x, y, -x, -y],
  [z, w, -z, -w],
  [2x, 2y, -2x, -2y],
  [2z, 2w, -2z, -2w],
  [3x, 3y, -3x, -3y],
  [3z, 3w, -3z, -3w]
])
------------------------------- 
</example>
    </description>

    <syntax>
TensorMat(M:Mat, N:Mat):MAT
</syntax>

    <type>matrix</type>

    <key>tensormat</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Toric</title>
    <short_description>saturate toric ideals</short_description>

    <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 <code>x^k(+) - x^k(-)</code> as k ranges over K.  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 *containing* 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 Q[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(HPPI8, [x[1],y[2]]);
Len(BL.Gens);
340
-------------------------------
Use Q[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(HPPI9, [x[1],y[2]]);
Len(BL.Gens);
-------------------------------
798
-------------------------------
Use R ::= Q[x,y,z,w];
Toric(Ideal(xz-y^2, xw-yz));
Ideal(-y^2 + xz, -yz + xw, z^2 - yw)
-------------------------------
Toric([xz-y^2, xw-yz]);
Ideal(-y^2 + xz, -yz + xw, z^2 - yw)
-------------------------------
Toric([xz-y^2, xw-yz], [y]);
Ideal(-y^2 + xz, -yz + xw, z^2 - yw)
-------------------------------
Use R ::= Q[x,y,z];
Toric([[1,3,2],[3,4,8]]);
Ideal(-x^16 + y^2z^5)
-------------------------------
Toric(Mat([[1,3,2],[3,4,8]]));
Ideal(-x^16 + y^2z^5)
------------------------------- 
</example>
    </description>

    <syntax>
Toric(L:LIST of BINOMIAL):IDEAL
Toric(L:LIST of BINOMIAL,X:LIST of INDETS):IDEAL
Toric(M:MAT or LIST of LIST):IDEAL

where M is a matrix of integers with no zero column.  Elements of L
must be homogeneous (w.r.t. the first row of the weights matrix).
</syntax>

    <see>Toric.CheckInput</see>

    <type>ideal</type>
    <type>matrix</type>
    <type>list</type>
    <type>toric</type>

    <key>toric</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Toric.CheckInput</title>
    <short_description>check input to <code>Toric</code></short_description>

    <description>
This function checks if E or (E,X) is suitable input for <coderef>Toric</coderef>.
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 <coderef>Toric</coderef> anyway).

        
<example>
Use R ::= Q[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):BOOL
Toric.CheckInput(E:OBJECT,X:LIST):BOOL
</syntax>

    <see>Toric</see>

    <type>ideal</type>
    <type>matrix</type>
    <type>list</type>
    <type>toric</type>

    <key>toric.checkinput</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Transposed</title>
    <short_description>the transposition of a matrix</short_description>

    <description>
This function returns the transpose of the matrix M.

        
<example>
M := Mat([[1,2,3],[4,5,6]]);
M;
Mat([
  [1, 2, 3],
  [4, 5, 6]
])
-------------------------------
Transposed(M);
Mat([
  [1, 4],
  [2, 5],
  [3, 6]
])
------------------------------- 
</example>
    </description>

    <syntax>
Transposed(M:MAT):MAT
</syntax>

    <type>matrix</type>

    <key>transposed</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Tuples</title>
    <short_description>N-tuples</short_description>

    <description>
This function computes all N-tuples with entries in S.
It is equivalent to <code>S &gt;&lt; S &gt;&lt; ... &gt;&lt; S</code>  [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>

    <syntax>
Tuples(S:LIST, N:INT):LIST
</syntax>

    <see><formula>&gt;&lt;</formula></see>
    <see>Permutations</see>
    <see>Subsets</see>

    <type>list</type>

    <key>tuples</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Type</title>
    <short_description>the data type of an expression</short_description>

    <description>
This function returns the data type of E.  The function <coderef>Types</coderef>
returns the list of CoCoA data types.

        
<example>
Define CollectInts(L)
  Result := [];
  Foreach X In L Do
    If Type(X) = INT Then Append(Result,X) EndIf
  EndForeach;
  Return Result
EndDefine;

CollectInts([1,<coc-quotes>a</coc-quotes>,2,<coc-quotes>b</coc-quotes>,3,<coc-quotes>c</coc-quotes>]);
[1, 2, 3]
-------------------------------
Type(Type(INT));  -- Type returns a value of type TYPE
TYPE
-------------------------------
Types();
[NULL, BOOL, STRING, TYPE, ERROR, RECORD, DEVICE, INT, RAT, ZMOD,
POLY, RATFUN, VECTOR, IDEAL, MODULE, MAT, LIST, RING, TAGGED(<coc-quotes></coc-quotes>),
FUNCTION] 
------------------------------- 
</example>
    </description>

    <syntax>
Type(E:OBJECT):TYPE
</syntax>

    <see>Data Types</see>
    <see>Types</see>

    <type>type</type>

    <key>type</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>TypeOfCoeffs</title>
    <short_description>type of the coefficients of the current ring</short_description>

    <description>
This function returns the type of the coefficients of the current ring.

        
<example>
Use R ::= Q[x,y,z];
TypeOfCoeffs();
RAT
-------------------------------
Use S ::= Z/(2)[t];
TypeOfCoeffs();
ZMOD
------------------------------- 
</example>
    </description>

    <syntax>
TypeOfCoeffs():TYPE
</syntax>

    <see>Characteristic</see>
    <see>Coefficients</see>
    <see>CurrentRing</see>
    <see>Indets</see>

    <type>ring</type>
    <type>type</type>

    <key>typeofcoeffs</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Types</title>
    <short_description>lists all data types</short_description>

    <description>
This function lists all CoCoA data types.

        
<example>
Types();
[NULL, BOOL, STRING, TYPE, ERROR, RECORD, DEVICE, INT, RAT, ZMOD,
POLY, RATFUN, VECTOR, IDEAL, MODULE, MAT, LIST, RING, TAGGED(<coc-quotes></coc-quotes>),
FUNCTION] 
------------------------------- 
</example>
    </description>

    <syntax>
Types()
</syntax>

    <see>Data Types</see>
    <see>Type</see>

    <type>type</type>

    <key>types</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>U</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>UnivariateIndetIndex</title>
    <short_description>the index of the indeterminate of a univariate polynomial</short_description>

    <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 Q[x,y];
UnivariateIndetIndex(3x^4-2x-1);
1
-------------------------------
UnivariateIndetIndex(x-y-1);
0
-------------------------------
UnivariateIndetIndex(3);
1
-------------------------------
</example>

    </description>

    <syntax>
UnivariateIndetIndex(F: POLY): INT
</syntax>

    <see>Indet</see>
    <see>IndetInd</see>
    <see>IndetIndex</see>
    <see>IndetName</see>
    <see>Indets</see>
    <see>NumIndets</see>

    <type>ring</type>
    <type>polynomial</type>

    <key>univariateindetindex</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Unset</title>
    <short_description>set and unset panel options</short_description>

    <description>
The command <code>Set</code> in its first form sets a panel option to TRUE.
The command <code>UnSet</code> sets a panel option to FALSE.  The command <code>Set</code>
in the second-listed form can be used to set an option to TRUE or
FALSE.  A list of panels is returned by <code>Panels()</code>, and a list of
panel options for a panel with name P is printed by <code>Panel(P)</code>.  The
current status of an option is returned by <coderef>Option</coderef>.

        
<example>
Panel(GROEBNER);

Sugar........... : TRUE
FullRed......... : TRUE
SingleStepRed... : FALSE
Verbose......... : FALSE
-------------------------------
Set Verbose;
UnSet Sugar;
Set FullRed := FALSE;
Panel(GROEBNER);

Sugar........... : FALSE
FullRed......... : FALSE
SingleStepRed... : FALSE
Verbose......... : TRUE
------------------------------- 
</example>

NOTE: there is also a function called <code>Set</code> which takes a list
obtained by removing duplicate elements.  The search key for that
function in online help is <coderef>Set</coderef> and the search key for the present
command is <code>Unset</code>.
    </description>

    <syntax>
Set O
Set O := B:BOOL
UnSet O

where O is a panel option.
</syntax>

    <see>Introduction to Panels</see>
    <see>Panel</see>
    <see>Option</see>
    <see>Panels</see>

    <type>panels</type>
    <type>system</type>

    <key>unset</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Untagged</title>
    <short_description>untag an object</short_description>

    <description>
This function strips an object E of its tag, if any.
<code>@E</code> is equivalent to <code>Untagged(E)</code>.

<pre/>
Tags are used for pretty printing of objects.  See the reference
listed below.
        
<example>
L := [1,2,3];
M := Tagged(L,<coc-quotes>MyTag</coc-quotes>);
Type(L);
LIST
-------------------------------
Type(M);
TAGGED(<coc-quotes>MyTag</coc-quotes>)
-------------------------------
Type(Untagged(M));
LIST
-------------------------------
</example>
    </description>

    <syntax>
Untagged(E:TAGGED_OBJECT):UNTAGGED_OBJECT
</syntax>

    <see>Tagged Printing</see>
    <see>Tag</see>
    <see>Tagged</see>

    <type>io</type>
    <type>printing</type>
    <type>tags</type>

    <key>untagged</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Use</title>
    <short_description>command for making a ring active</short_description>

    <description>
<code>Use</code> is the command for making a ring active, i.e. for making a ring
the current ring.  The command

<par/>
Use N ::= E;

<par/>
where E is a ring, is a shorthand for

<par/>
N ::= E;
Use N;

        
<example>
Use S ::= Q[x,y,z];
RingEnv();
S
-------------------------------
T::= Z/(3)[a,b];
Use T;
RingEnv();
T
-------------------------------
Use Q[u];  -- note that <coc-quotes>Use</coc-quotes> can be used w/out a ring identifier
RingEnv();
CurrentRingEnv
-------------------------------
CurrentRing();
Q[u]
------------------------------- 
</example>
    </description>

    <syntax>
Use N

where N is either the identifier of an existing ring or a ring
itself.
</syntax>

    <see>Accessing Other Rings</see>
    <see>Using</see>

    <type>ring</type>

    <key>use</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Using</title>
    <short_description>perform commands in non-active ring</short_description>

    <description>
Suppose S is the current ring and R is another ring, then

<verbatim>
  Using R Do
    C;
  EndUsing;
</verbatim>
is equivalent to 
<verbatim>
  Use R;
  C;
  Use S;
</verbatim>
        
<example>
Use S ::= Q[x,y];          -- the current ring is S
R ::= Q[a,b,c];             -- another ring 
Using R Do Indets() EndUsing;
[a, b, c]
------------------------------- 
</example>

Note: <code>Using Q[a,b] Do ...</code> is not proper syntax and will produce an
error.
    </description>

    <syntax>
Using R Do C EndUsing

where R is the identifier for a ring and C is a sequence of commands.
</syntax>

    <see>Accessing Other Rings</see>
    <see>Use</see>

    <type>ring</type>

    <key>using</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>V</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Var</title>
    <short_description>function calls by reference, other complex referencing</short_description>

    <description>
In the first and second form <code>Var</code> is used as a formal parameter to a
user-defined function.  It is used to pass a variable---not its
value---to the user-defined function.  The following example should
make the difference clear.

        
<example>
Define CallByRef(Var L )  -- <coc-quotes>call by reference</coc-quotes>: The variable referred
  L := <coc-quotes>new value</coc-quotes>;       -- to by L is changed.
EndDefine;
M := <coc-quotes>old value</coc-quotes>;
CallByRef(M);
M;
new value
-------------------------------
Define CallByVal(L)  -- <coc-quotes>call by value</coc-quotes>: The value of L is passed to
  L := <coc-quotes>new value</coc-quotes>;  -- the function.
  Return L;
EndDefine;
L := <coc-quotes>old value</coc-quotes>;
CallByVal(L);
new value
-------------------------------
L;
old value.
-------------------------------  
</example>

In the third form, Var(S), references the value of the variable or ring
whose identifier is S:

        
<example>
Var(<coc-quotes>a string</coc-quotes>) := 6; 
Var(<coc-quotes>a string</coc-quotes>);
6
-------------------------------
P := Record[Name = <coc-quotes>test</coc-quotes>, Value = 1];
X := <coc-quotes>Name</coc-quotes>;
P.Var(X);
test
-------------------------------
Var(<coc-quotes>myring</coc-quotes>) ::= Q[a,b];
Var(<coc-quotes>myring</coc-quotes>);
Q[a,b]
-------------------------------
Using Var(<coc-quotes>myring</coc-quotes>) Do (a+b)^2 EndUsing;
a^2 + 2ab + b^2
------------------------------- 
</example>
    </description>

    <syntax>
Var X
Var(X)
Var(S:STRING)

where X is the identifier of a CoCoA variable.
</syntax>

    <see>Define</see>

    <type>function</type>
    <type>string</type>

    <key>var</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>Vector</title>
    <short_description>create a vector</short_description>

    <description>
The first form returns the vector with components <code>F_1,...,F_n</code>; the
second form returns the vector whose components are the components of
the list L.

        
<example>
Use R ::= Q[x];
V := Vector(1,x,x^2);
Type(V);
VECTOR
Vector([1+x,x,x^2]);
Vector(x + 1, x, x^2)
------------------------------- 
</example>
    </description>

    <syntax>
Vector(F_1:POLY,...,F_n:POLY):VECTOR
Vector(L:LIST):VECTOR

where L is a list of polynomials.
</syntax>

    <type>vector</type>

    <key>vector</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>W</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>WeightsList</title>
    <short_description>first row of the weights matrix</short_description>

    <description>
This function returns the first row of the weights matrix for the
current ring as a list.

        
<example>
Use R ::= Q[t,x,y,z];
WeightsList();
[1, 1, 1, 1]
-------------------------------
Use R ::= Q[t,x,y,z], Weights(1,3,5,2);
WeightsList();
[1, 3, 5, 2]
-------------------------------
Use R ::= Q[x,y], Weights(Mat([[1,2],[3,4],[5,6]]));
WeightsList();
[1, 2]
------------------------------- 
</example>
    </description>

    <syntax>
WeightsList():LIST
</syntax>

    <see>Deg</see>
    <see>MDeg</see>
    <see>Weights Modifier</see>
    <see>WeightsMatrix</see>

    <type>ring</type>

    <key>weightslist</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>WeightsMatrix</title>
    <short_description>matrix of generalized weights for indeterminates</short_description>

    <description>
This function returns the weights matrix for the current ring.

        
<example>
Use R ::= Q[x,y], Weights(Mat([[1,2],[3,4],[5,6]]));
WeightsMatrix();
Mat([
  [1, 2],
  [3, 4],
  [5, 6]
])
-------------------------------
MDeg(y);
[2, 4, 6]
-------------------------------
WeightsList();  -- the first row of the weights matrix
[1, 2]
-------------------------------  
</example>
    </description>

    <syntax>
WeightsMatrix():MAT
</syntax>

    <see>Deg</see>
    <see>MDeg</see>
    <see>Weights Modifier</see>
    <see>WeightsList</see>

    <type>ring</type>

    <key>weightsmatrix</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>While</title>
    <short_description>loop command</short_description>

    <description>
The command sequence C is repeated until B evaluates to FALSE.

        
<example>
N := 0;
While N &lt;= 5 Do
  PrintLn(2, <coc-quotes>^</coc-quotes>, N, <coc-quotes> = </coc-quotes>, 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>

    <syntax>
While B Do C EndWhile

where B is a boolean expression and C is a sequence of commands.
</syntax>

    <see>For</see>
    <see>Foreach</see>
    <see>Repeat</see>

    <type>programming</type>
    <type>loops</type>

    <key>while</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>WithoutNth</title>
    <short_description>removes the N-th component from a list</short_description>

    <description>
This function returns the list obtained by removing the N-th
component of the list L.  The list L is not affected (as opposed to
the command <coderef>Remove</coderef>).

        
<example>
L := [1,2,3,4,5];
WithoutNth(L,3);
[1, 2, 4, 5]
------------------------------- 
</example>
    </description>

    <syntax>
WithoutNth(L:LIST,N:INT):LIST
</syntax>

    <see>Insert</see>
    <see>Remove</see>

    <type>list</type>

    <key>withoutnth</key>
  </command>
<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>WLog</title>
    <short_description>weighted list of exponents</short_description>

    <description>
This function returns the weighted list of exponents of the leading
term of F, as determined by the first row of the weights matrix.
Thus, if all the weights are 1, this function returns the same thing
as <code>Log(F)</code>.

        
<example>
Use R ::= Q[x,y];
F := x^2-y;
WLog(F);
[2, 0]
-------------------------------
Use R ::= Q[x,y],Weights(2,3);
F := x^2-y;
WLog(F);
[4, 0]
------------------------------- 
</example>
    </description>

    <syntax>
WLog(F:POLY):LIST of INT
</syntax>

    <see>Log</see>

    <type>polynomial</type>

    <key>wlog</key>
  </command>

 </chapter_letter>
 <!-- ===  CHAPTER  =============================================== -->
 <chapter_letter>
   <chapter_name>X</chapter_name>

<!-- ===  COMMAND  =============================================== -->
  <command>
    <title>XelMat</title>
    <short_description>matrices for std. term-orderings</short_description>

    <description>
This function return the matrix defining a standard term-ordering.

        
<example>
XelMat(3);
Mat([
  [0, 0, 1],
  [0, 1, 0],
  [1, 0, 0]
])
------------------------------- 
</example>
    </description>

    <syntax>
XelMat(N:INTEGER):MAT
</syntax>

    <see>Ord</see>
    <see>Orderings</see>
    <see>DegRevLexMat</see>
    <see>DegLexMat</see>
    <see>LexMat</see>
    <see>RevLexMat</see>

    <type>matrix</type>

    <key>xelmat</key>
  </command>


 </chapter_letter>

</cocoa_commands>





<!-- *************************** -->
<!-- LIST OF PARTS OF THE MANUAL -->
<!-- *************************** -->
<manual_parts>
  <part number="1">
    <name></name>
<!-- ===  CHAPTER  =============================================== -->
    <chapter number="1">
      <chapter_name>Preamble</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Version</title>
        <type>1</type>

        <description>
        <verbatim>
-------------------------------------------------------
---           ___/       ___/         \             ---
--           /     _ \  /     _ \    , \             --
--           \    |   | \    |   |  ___ \            --
---          ____, __/  ____, __/ _/    _\          ---
-------------------------------------------------------
--   Online Help : CoCoA <coc_version/>                         --
--        Author : David Perkinson                   --
--         email : davidp@reed.edu                   --
--          addr : Reed College, Portland, OR, USA   --
--          date : <coc_date/>                        --
--------------------------------------------------------
        </verbatim>
    </description>

        <key>version</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Preface</title>
        <type>1</type>

        <description>
CoCoA is a system for doing <em>Computations in Commutative Algebra.</em>
It is one of the projects of an active research team in Computer
Algebra at the University of Genova, Italy, and whose current members are:
Lorenzo Robbiano (team manager), John Abbott, Anna Bigatti, Massimo Caboara,
Martin Kreuzer, David Perkinson, and occasionally other researchers and
students.  Notable contributions from outside the team have been received
from Volker Augustin and Arndt Wills.  Much of the original code for CoCoA
was written by Gianfranco Niesi and Antonio Capani.
    </description>

        <key>preface</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>System Distribution</title>
        <type>1</type>

        <description>
CoCoA is public domain software, available at

  <code>http://cocoa.dima.unige.it</code>

where there is also a great deal of information about the system.
Besides the main site in Genoa, Italy, there is a mirror of the
official distribution:

 USA, West Coast:
 <code>http://www.reed.edu/cocoa</code>

CoCoA is distributed freely under the following condition: any
research activity which uses CoCoA should cite the system in the
following form:
<verbatim>
  CoCoATeam
  CoCoA, a system for doing Computations in Commutative Algebra,
  Available at http://cocoa.dima.unige.it
</verbatim>
  (see also <code>http://cocoa.dima.unige.it/citing.html</code>)

<par/>
The system can be freely redistributed to other users. New users
should notify the CoCoA team at the email address below so they can be
included in a users list. All members of this list will be kept up to
date about the progress of the system.

<par/>
The system is distributed <em>as is</em>.  The authors make no guarantee
about the fitness of the system for any particular application. They
will not be liable for any direct, indirect, special, incidental or
consequential damages in connection with the use of the system or of
the manual.

<par/>
Bug reports, questions, and suggestions should be sent to the
following email address:

<par/>
              cocoa (at) dima.unige.it

<par/>
Comments on the online help system would be greatly appreciated.  They
may be sent to the above address or to davidp (at) reed.edu.
    </description>

        <key>system distribution</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>System Requirements</title>
        <type>1</type>

        <description>
CoCoA <coc_version/> runs on most common platforms.  Please visit the CoCoA
web site to see whether it is available for the platform you wish
to use.  If the version you seek is absent let us know, and we will
try to rectify the situation.
    </description>

        <key>system requirements</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Copyright and Trademarks</title>
        <type>1</type>

        <description>
The product names mentioned in this manual are trademarks or
registered trademarks of their manufacturers.
    </description>

        <key>copyright and trademarks</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Acknowledgments</title>
        <type>1</type>

        <description>
The CoCoA project is partly supported by:
<par/>
  * Department of Mathematics, University of Genova
<par/>
  * Department of Computer Science, University of Genova
<par/>
  * Consiglio Nazionale delle Ricerche
<par/>
  * Ministero dell&apos;Universita` e della Ricerca Scientifica e Tecnologica

<par/>
The author of the online help package would like to thank Tony
Geramita, Lorenzo Robbiano and the CoCoA team.  Thanks to Antonio
Capani and Gianfranco Niesi for patiently answering my questions and
for allowing me to use their <em>CoCoA User&apos;s Manual, version 3.0b
Draft,</em> from which the online help package borrows, sometimes
verbatim.
    </description>

        <key>acknowledgments</key>
      </section>

    </chapter>


  </part>
  <part number="2">
    <name>Introduction to CoCoA</name>
<!-- ===  CHAPTER  =============================================== -->
    <chapter number="1">
      <chapter_name>The CoCoA System</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>An Overview of the System</title>
        <type>1</type>

        <description>
CoCoA is a computer algebra system for doing <em>Computations in
Commutative Algebra</em>.  Since its first version CoCoA has been designed
to offer maximum ease of use and flexibility to the mathematician with
little or no knowledge of computers.  It is able to perform simple and
sophisticated operations on multivariate polynomial rings and on
various data connected with them (ideals, modules, matrices, rational
functions).

<par/>
The system is capable of performing basic operations such as
<verbatim>
    * sums, products, powers, derivatives, gcd, lcm of polynomials;
    * sums, products, powers, derivatives  of rational functions;
    * sums, products, powers of ideals;
    * sums  of modules;
    * sums, products, powers, determinants, adjoints of matrices;
    * operations between heterogeneous values, like the product
      between an ideal and a polynomial, etc.
</verbatim>
Besides these, more advanced operations are available. For example:
<verbatim>
    * Groebner bases of ideals and modules;
    * syzygies of ideals and modules;
    * minimal free resolutions of ideals and modules;
    * intersection and division of ideals and modules;
    * inclusion and equality test for ideals and modules;
    * elimination of indeterminates;
    * homogenization of ideals;
    * Poincare series and Hilbert functions;
    * factorization of polynomials;
    * saturation of toric ideals.
</verbatim>
Every computation is performed within a <em>current</em> or <em>active</em>
ring, but the user can easily define and switch between many rings in
a single CoCoA session.

<par/>
CoCoA includes an extensive Pascal-like programming language, CoCoAL,
that allows the user to customize the system and extend the embedded
library.
    </description>

        <key>an overview of the system</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>System Structure</title>
        <type>1</type>

        <description>
CoCoA is written in C language and is available on several platforms.
The core of the system is an implementation of Buchberger&apos;s algorithm
for computing Groebner bases of ideals and modules over a polynomial
ring whose coefficient ring is a field, and a variation of it for
computing syzygies. The algorithm has been optimized in several
directions and is used as a building block for many operations. Most
users can, however, completely ignore the theory of Groebner bases and
even their existence: CoCoA will do all the necessary <em>Groebner
stuff</em> in the background. However, for optimum use of the system some
knowledge of the theory is helpful.

<par/>
The system interacts with the external world using a Low Level
Protocol (LLP) that is independent of any machine architecture.  High
level inputs from the user are translated into LLP-requests to the
CoCoA kernel.  The LLP-answers are then translated back into high
level, user-readable outputs.
    </description>

        <key>system structure</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Contributions</title>
        <type>1</type>

        <description>
Important parts of the system have been developed by:
<verbatim>
John Abbott: factorization and linear algebra
Anna Bigatti: Hilbert-Poincare series, toric ideals
Massimo Caboara: advanced ideal and module operations
Martin Kreuzer: testing and debugging
David Perkinson: online help
Volker Augustin: graphical user interface
Arndt Wills: graphical help system
</verbatim>
    </description>

        <key>contributions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>CoCoA and Macaulay</title>
        <type>1</type>

        <description>
Most of the standard scripts from the computer algebra system
Macaulay (Classic) have been translated into CoCoAL.  For
information, see

  <code>http://www.matha.mathematik.uni-dortmund.de/~kreuzer/projects.html</code>
    </description>

        <key>cocoa and macaulay</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Pointers to the Literature</title>
        <type>1</type>

        <description>
The following are articles which may be of interest to CoCoA users.
Many of the algorithms discussed in these articles have been
implemented in CoCoA.

<par/>
J. Abbott, <em>Univariate factorization over the integers,</em>  Preprint (1998).

<par/>
A.M. Bigatti, <em>Computations of Hilbert-Poincare Series,</em> J. Pure
Appl. Algebra, 119/3, 237--253 (1997).

<par/>
A.M. Bigatti, A. Capani, G. Niesi, L. Robbiano, <em>Hilbert-Poincare
Series and Elimination Problems,</em> Preprint (1998).

<par/>
A.M. Bigatti, R. La Scala, L. Robbiano, <em>Computing Toric Ideals,</em>
Preprint (1998).

<par/>
A.M. Bigatti, L. Robbiano, <em>Borel Sets and Sectional Matrices,</em>
Annals of Combinatorics, 1, 197--213, (1997)

<par/>
M. Caboara, P. Conti, and C. Traverso, <em>Yet Another Ideal
Decomposition Algorithm,</em> AAECC-12, Springer LNCS 1255, 39--54,
(1997). 

<par/>
M. Caboara, G. De Dominicis, L. Robbiano, <em>Multigraded Hilbert
Functions and Buchberger Algorithm,</em> In Proc. ISSAC`96, 72--78 (1996),
Y.N. Lakshman, editor, New York. ACM Press.

<par/>
A. Capani, G. De Dominicis, <em>Web Algebra,</em> In Proc. of WebNet
96. Association for the Advancement of Computing in Education (AACE)
Charlottesville, USA, (1996).

<par/>
A. Capani, G. De Dominicis, G. Niesi, L. Robbiano, <em>Computing Minimal
Finite Free Resolutions,</em> J. Pure Appl. Algebra, 117/118, 105--117,
(1997). 

<par/>
A. Capani, G. Niesi, <em>The CoCoA 3 Framework for a Family of
Buchberger-like Algorithms,</em> In Groebner Bases and Applications
(Proc. of the Conf. 33 Years of Groebner Bases) , London
Math. Soc. Lecture Notes Series, Vol. 251, B. Buchberger and
F. Winkler eds., Cambridge University Press, p. 338--350, (1998).

<par/>
A. Capani, G. Niesi, <em>CoCoA 3.0 User&apos;s Manual,</em> (1995).

<par/>
A. Capani, G. Niesi, L. Robbiano, <em>Some Features of CoCoA 3,</em>
Comput. Sci. J. of Moldova 4, 296--314, (1996).

<par/>
A. Giovini, T. Mora, G. Niesi, L. Robbiano, C. Traverso, <em>`One sugar
cube, please' or selection strategies in the Buchberger algorithm,</em> In
Proc. ISSAC`91, 49--54, Stephen M. Watt, editor, New York, ACM
Press, (1991).

<par/>
A. Giovini and G. Niesi, <em>CoCoA: a user-friendly system for commutative
algebra,</em>  In Design and Implementation of Symbolic Computation
Systems -- International Symposium DISCO`90, Lecture Notes in
Comput. Sci., 429, 20--29, Berlin, Springer Verlag, (1990).

<par/>
B. Sturmfels, <em>Groebner Bases and Convex Polytopes</em>, AMS University
Lecture Series, Vol. 8 (1995).

<par/>
SOME BOOKS AND ARTICLES MENTIONING CoCoA:
W. W. Adams, P. Loustaunau, <em>An Introduction to Groebner Bases,</em>
Graduate Studies in Mathematics, AMS, Providence, R.I. (1994).

<par/>
D. Cox, J. Little, D. O&apos;shea, <em>Ideals, Varieties, and Algorithms,</em>
Springer-Verlag, New York (1992).

<par/>
M. Kreuzer, L. Robbiano, <em>Computational Commutative Algebra 1</em>
Springer-Verlag, (2000).

<par/>
L. Robbiano, <em>Groebner Bases and Statistics,</em> in <em>Groebner Bases
and Applications,</em> (Proceedings of the Conference: 33 Years of
Groebner Bases), LMS Lecture Note Series, Vol. 251, B. Buchberger and
F. Winkler eds., Cambridge University Press, p. 79--204 (1998).
    </description>

        <key>pointers to the literature</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="2">
      <chapter_name>Tutorial</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>A Tutorial Introduction to CoCoA</title>
        <type>1</type>

        <description>
This is an introduction to CoCoA, mainly through examples.  It is
just a small part of the online CoCoA manual.  

<par/>
If you are using an HTML version of the manual just click on <em>next</em>!
The following few sections are for those who call the manual from
a CoCoA shell.

<par/>
To learn more about finding information in the manual, enter <code>?</code>
(without the quotes).  For now, the only essential command to know is
<code>H.Browse()</code>.  Entering <code>H.Browse();</code> or <code>H.Browse(1);</code> will display
the next section of the manual.  <code>H.Browse(0);</code> will redisplay the
current section, and <code>H.Browse(-1);</code> will display the previous
section.  Start browsing the tutorial now by entering <code>H.Browse();</code>.
    </description>

        <key>a tutorial introduction to cocoa</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Setting Up CoCoA for the Tutorial</title>
        <type>1</type>

        <description>
If you are using an HTML version of the manual skip this section.

<par/>
Some of the information from the online manual (and results of CoCoA
calculations, in general) may scroll off of the screen.  It is best to
run CoCoA from a system that has scrollable windows with enough
room to hold the output from each CoCoA command.

<par/>
Under X-windows, you might try running CoCoA from an xterm started
with the command <code>xterm -sb -sl 512</code> (scroll bar enabled,
saving 512 lines).  In addition, you may want to increase the vertical
size of your window, e.g., <code>xterm -sb -sl 512 -geometry 80x40</code> 
under X-windows.  Better yet: run CoCoA from a shell
within Emacs.

<par/>
IF YOU DO NOT HAVE SCROLLABLE WINDOWS: enter the command
<code>H.SetMore();</code> to receive output 20 lines at a time.  As long as there
is output waiting to be printed, you will be prompted to enter
<code>More();</code> to get the next 20 lines.  You may type <code>H.SetMore(N)</code> in
order to get N lines at a time instead of 20.

<par/>
Enter <code>H.Browse();</code> to continue.  (The <code>Browse</code> command will be assumed
from now on.)
    </description>

        <key>setting up cocoa for the tutorial</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Entering Commands</title>
        <type>1</type>

        <description>
While reading the tutorial it is highly recommended that you have
a copy of CoCoA running in a separate window in order to play with the
examples presented.  

<par/>
If you are using the CoCoA GUI (Graphical User Interface) then you 
should follow the dedicated link <em>Graphical User Interface</em> for
entering commands.

<par/>
To execute a CoCoA command, type it into the window, ending it with a
semicolon, then press the <em>return</em> key or <em>enter</em> key (depending on
your system).  A command can run over several lines; CoCoA will wait
for a semicolon before processing the command.  Also, several commands
may be written on a single line (each ending with a semicolon).

<par/>
See the next section for examples.

<par/>
IMPORTANT NOTES for Macintosh OS 9 (up to version 4.0):

<par/>
1.  Only the <em>enter</em> key (on the far right of the keyboard is the one
to use) will function to enter CoCoA commands.  Experiment.

<par/>
2. To enter multiple lines, one needs to highlight the lines using the
mouse before hitting the <em>enter</em> key.  Otherwise, the enter key just
feeds the line containing the cursor to CoCoA.
    </description>

        <key>entering commands</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Examples of Entering Commands</title>
        <type>1</type>

        <description>
Here are some examples of entering simple commands in CoCoA.
(Macintosh OS9 and GUI users please remember the special instructions
made in the previous section.)



        
<example>
-------------------------------
1+1;  -- a simple command
2
-------------------------------
1  +   -- the same command spread over several lines

1;   
2
-------------------------------
1+1; 2+2; 3+3;  -- several commands on a single line
2
-------------------------------
4
-------------------------------
6
------------------------------- 
</example>

NOTE: The output above appears just as it does in my CoCoA window.
The examples in the online manual will often be annotated.  When CoCoA
encounters *double dashes*, as above, it regards the rest of the line
as a comment.
    </description>

        <key>examples of entering commands</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>More on Entering Commands</title>
        <type>1</type>

        <description>
One may save a sequence of commands in a file and read them into a
CoCoA session with the <coderef>Source</coderef> command.
For instance, if a sequence of CoCoA commands is saved in the file
<code>MySession</code>, one may enter
<verbatim>
  &lt;&lt; MySession;
</verbatim>
to run the commands (give the full pathname, or store your file in the
cocoa directory).  User-defined functions are often stored in files
and sourced in this way.
    </description>

        <key>more on entering commands</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>After the Tutorial</title>
        <type>1</type>

        <description>
Browsing through the examples in this tutorial may enable you to
solve your particular problems.  If not, or to learn more about CoCoA
in general, enter <code>?</code> to learn more about CoCoA&apos;s online help.  For
example, you will see that <code>H.Command(<coc-quotes></coc-quotes>)</code> gives a long annotated
list of CoCoA commands, and <code>?keyword</code> will look for information about
<em>keyword</em> in the manual.

The GUI Help System (html) and the printable/browsable version (pdf)
contain exactly the same information as the online help.
You may choose your preferred format or exploit the different
searching methods suiting best your need.

<par/>
With the following section, the tutorial proper begins.  To see a
table of contents for the tutorial, enter <code>H.Toc(1,2)</code>.  The command
<code>H.Browse()</code> will then continue with the tutorial, or you may give the
title of a tutorial section to <code>?</code> to skip to that section.
    </description>

        <key>after the tutorial</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Arithmetic</title>
        <type>1</type>

        <description>
Here are some first examples; they illustrate CoCoA evaluating
arithmetic expressions.

        
<example>
(2+3)(1+1);  -- multiplication, as usual
10
-------------------------------
2^10;
1024
-------------------------------
2+2/3;
8/3
-------------------------------
1.5+2.3;  -- decimals are converted to fractions
19/5
-------------------------------
Mod(27,5);
2
-------------------------------
2*3;
6
-------------------------------
Fact(4);
24
------------------------------- 
</example>
For multiplication, one may use <code>*</code>, parentheses, or just a space.
    </description>

        <key>arithmetic</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>Variables</title>
        <type>1</type>

        <description>
Results from CoCoA calculations can be stored in variables.
Variables, like CoCoA functions, must begin with a capital letter or an
error will result.

        
<example>
A := 3;
2A;
6
-------------------------------
b := 7;
ERROR: parse error in line 12 of device stdin
-------------------------------
7
-------------------------------
B := 7;
A^2 + B;
16
------------------------------- 
</example>
    </description>

        <key>variables</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="9">
        <title>The Variable <em>It</em></title>
        <type>1</type>

        <description>
When CoCoA evaluates an expression, the result is usually assigned to
the special CoCoA variable named <code>It</code>.

        
<example>
1+1;
2
-------------------------------
It;
2
-------------------------------
It+1;
3
-------------------------------
It;
3
-------------------------------
X := 17;  -- <coc-quotes>It</coc-quotes> is not changed if there is no output
It;
3
-------------------------------
X+It;
20
------------------------------- 
</example>
    </description>

        <key>the variable <em>It</em>, the variable it</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="10">
        <title>Making Lists</title>
        <type>1</type>

        <description>
The following example illustrates the use of lists in CoCoA.

        
<example>
L := [2,3,<coc-quotes>a string</coc-quotes>,[5,7],3,3];  -- L is now a list
L[3];  -- here is the 3rd component of L
a string
-------------------------------
L[4];  -- the 4th component of L is a list, itself
[5, 7]
-------------------------------
L[4][2];  -- the 2nd component of the 4th component of L
7
-------------------------------
L[4,2];  -- same as above
7
-------------------------------
Append(L,<coc-quotes>new</coc-quotes>);
L;
[2, 3, <coc-quotes>a string</coc-quotes>, [5, 7], 3, 3, <coc-quotes>new</coc-quotes>]
-------------------------------
-- insert 8 as the 4th component of L, shifting the other
-- entries to the right:
Insert(L,4,8);  
L;
[2, 3, <coc-quotes>a string</coc-quotes>, 8, [5, 7], 3, 3, <coc-quotes>new</coc-quotes>]
-------------------------------
Remove(L,4);  -- remove it again
L;
[2, 3, <coc-quotes>a string</coc-quotes>, [5, 7], 3, 3, <coc-quotes>new</coc-quotes>]
-------------------------------
Len(L);  -- the number of components of L
7
-------------------------------
Set(L);  -- same as L but with repeats removed
[2, 3, <coc-quotes>a string</coc-quotes>, [5, 7], <coc-quotes>new</coc-quotes>]
-------------------------------
1..5;  -- a range of values
[1, 2, 3, 4, 5]
-------------------------------
[ X^2 | X In 1..5];  -- a useful way to make lists
[1, 4, 9, 16, 25]
-------------------------------
[1,2] &gt;&lt; [3,4] &gt;&lt; [5];  -- Cartesian product: use a greater-than 
                        -- sign <coc-quotes>&gt;</coc-quotes> and a less-than sign <coc-quotes>&lt;</coc-quotes> to make
                        -- the operator <coc-quotes>&gt;&lt;</coc-quotes>.
[[1, 3, 5], [1, 4, 5], [2, 3, 5], [2, 4, 5]]
------------------------------- 
</example>
    </description>

        <key>making lists</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="11">
        <title>Setting Up a Ring</title>
        <type>1</type>

        <description>
A CoCoA session automatically starts with the default ring, R =
Q[x,y,z].  The command <coderef>Use</coderef> is used to change rings.  The following
example shows how to create the ring Z/(5)[a,b,c] (the coefficient
ring is the integers mod 5).  Once the ring has been declared, one may
start to play with polynomials, ideals, modules, and other
constructions in that ring.  In the ring declaration, the
indeterminates are optionally separated by commas, and note the use of
two colons.

<par/>
Some details on handling several rings is provided below in the
section of the Tutorial entitled <ref>Using More Than One Ring</ref>
and <ref>Ring Mapping Example</ref>.

        
<example>
Use S ::= Z/(5)[a,b,c];
F := a-b;
I := Ideal(F^2,c);
I;
Ideal(a^2 - 2ab + b^2, c)
-------------------------------
J := Ideal(a-b);
I + J;
Ideal(a^2 - 2ab + b^2, c, a - b)
-------------------------------
Minimalized(It);  -- find a minimal set of generators for I+J
Ideal(a - b, c)
------------------------------- 
</example>
    </description>

        <key>setting up a ring</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="12">
        <title>A Groebner Basis Example</title>
        <type>1</type>

        <description>
A Groebner basis of an ideal I is calculated with the command
<code>GBasis(I)</code>, as illustrated in the following example.

<par/>
Let <formula>r</formula> be a root of the equation <formula>x^7-x-1</formula> over the rationals.  The
minimal polynomial of <formula>(4r-1)/r^3</formula> can be found by computing the reduced
Groebner basis of the ideal <formula>(x^7-x-1,x^3y-4x+1)</formula> with respect to the
lexicographic term-ordering with <formula>x&gt;y</formula>.

        
<example>
Use R ::= Q[x,y], Lex;
Set Indentation;  -- to improve the appearance of the output
G := GBasis(Ideal(x^7-x-1,x^3y-4x+1));
G;

[ 1602818757152090759440/34524608236181199361x - 4457540/5875764481y^7
  - 47746460716124220/34524608236181199361y^6 +
  890175715271333840/34524608236181199361y^5 -
  3541992534667352220/34524608236181199361y^4 -
  55943894513139464160/34524608236181199361y^3 -
  56473654361333280980/34524608236181199361y^2 -
  27971979712025453040/34524608236181199361y -
  400704689288022689860/34524608236181199361, 1/16384y^7 - 5/16384y^6
  + 147/16384y^4 + 5/128y^3 - 31/16384y^2 + 17/128y - 20479/16384]
-------------------------------
Len(G);
2
-------------------------------
F := 16384*G[2];  -- clear denominators 
F;
y^7 - 5y^6 + 147y^4 + 640y^3 - 31y^2 + 2176y - 20479
------------------------------- 
</example>

The Groebner basis is reported as a list with two elements.  The
second gives a univariate polynomial which is the minimal polynomial
for <formula>r</formula>.

<par/>
Note that the statement declaring the ring includes the modifier,
<code>Lex</code>.  Without this modifier, the default term-ordering, DegRevLex,
is used.  The command <code>Set Indentation</code> forces each polynomial of the
Groebner basis to be printed on a new line.
    </description>

        <key>a groebner basis example</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="13">
        <title>Eliminating Variables</title>
        <type>1</type>

        <description>
The Cartesian equations of the space curve parametrized by 
     
           <formula>t --&gt; (t^<ocb/>31<ccb/>+t^6,t^8,t^<ocb/>10<ccb/>)</formula>

can be found by eliminating the indeterminate t in the ideal
<formula>(t^<ocb/>31<ccb/>+t^6-x, t^8-y, t^<ocb/>10<ccb/>-z)</formula>.

        
<example>
Use R ::= Q[t,x,y,z];
Set Indentation;
Elim(t,Ideal(t^31+t^6-x, t^8-y, t^10-z));
Ideal(
  y^5 - z^4,
  -y^4z^5 + y^4 - 2xy^2z + x^2z^2,
  -z^8 - 2xy^3 + x^2yz + z^3,
  2xy^4z^4 + yz^7 + 3x^2y^2 - 2x^3z - yz^2,
  -y^2z^6 - 1/2xz^7 + 1/2x^3y + y^2z - 3/2xz^2,
  -1/3x^2y^4z^3 - y^3z^5 - 2/3xyz^6 + 1/3x^4 + y^3 - 4/3xyz)
------------------------------- 
</example>

With the command <coderef>Elim</coderef>, CoCoA automatically switches to a
term-ordering suitable for eliminating the variable <formula>t</formula>, then changes
back to the declared term-ordering (in this case the default
term-ordering, DegRevLex).

<par/>
One may see the entire Groebner basis for our ideal with respect to
the elimination term-ordering for <formula>t</formula> as follows:

        
<example>
Use R ::= Q[t,x,y,z], Elim(t);
Set Indentation;
GBasis(Ideal(t^31+t^6-x, t^8-y, t^10-z));
[
  -t^2y + z,
  y^5 - z^4,
  -t^6 - tz^3 + x,
  -tz^4 - y^2 + xz,
  -ty^2 + txz - y^4z,
  -y^4z^5 + y^4 - 2xy^2z + x^2z^2,
  -z^8 - 2xy^3 + x^2yz + z^3,
  2xy^4z^4 + yz^7 + 3x^2y^2 - 2x^3z - yz^2,
  tx^2y - tz^2 - y^2z^3 - xz^4,
  2txyz^3 - z^7 - x^2y + z^2,
  -y^2z^6 - 1/2xz^7 + 1/2x^3y + y^2z - 3/2xz^2,
  t^2x - tx^2z^2 + xy^4z^2 + yz^5 - y,
  t^2z + 2txz^3 - y^4z^3 - x^2,
  -3tx^2z^3 + 2xy^4z^3 + yz^6 + x^3 - yz,
  -1/3x^2y^4z^3 - y^3z^5 - 2/3xyz^6 + 1/3x^4 + y^3 - 4/3xyz,
  1/3tx^3 - 1/3tyz - 1/3x^2y^4 - 1/3y^3z^2 - 1/3xyz^3]
------------------------------- 
</example>
    </description>

        <key>eliminating variables</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="14">
        <title>Using More Than One Ring</title>
        <type>1</type>

        <description>
In CoCoA, every calculation takes place in a <em>current</em> or
<em>active</em> ring.  Ring-dependent objects defined by the user such as
polynomials, ideals, and modules are automatically labeled by the
current ring.  Objects that do not depend essentially on the ring,
e.g., lists or matrices of integers, do not get labeled.

<par/>
CoCoA automatically starts with the ring R = Q[x,y,z].  The
following example illustrates setting up a ring with the construction
<code>::=</code> and changing rings with the command <coderef>Use</coderef>.  One may temporarily
change rings with the command <coderef>Using</coderef>.  The example assumes that you
do not already have a ring with identifier <code>S</code>.

        
<example>
Use R ::= Q[x,y];  -- declare and use a ring R
F := (x+y)^3;
F;
x^3 + 3x^2y + 3xy^2 + y^3
-------------------------------
M := [1,<coc-quotes>test</coc-quotes>,2];
S ::= Q[x,y,z,a,b];   -- declare a ring S with indeterminates x,y,z,a,b
Use S;            -- switch to the ring S
F;  -- F is labeled by ring R
R :: x^3 + 3x^2y + 3xy^2 + y^3
-------------------------------
M;  -- this list is not labeled R since its elements are not
    -- ring dependent (e.g., <coc-quotes>1</coc-quotes> is considered a separate integer, not
    -- part of the ring R)
[1, <coc-quotes>test</coc-quotes>, 2]
-------------------------------
F := Ideal(a^2+b^2);  -- change the definition of F
Use R;  -- switch back to R
F;   -- the old F no longer exists
S :: Ideal(a^2 + b^2)
-------------------------------
GBasis(F);  -- built in functions automatically recognize the ring
[S :: a^2 + b^2]
------------------------------- 
</example>
    </description>

        <key>using more than one ring</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="15">
        <title>Substitutions</title>
        <type>1</type>

        <description>
To substitute a list of numbers or polynomials for the indeterminates
(in the order specified by the definition of the ring), one may use
the function <coderef>Eval</coderef>.  To substitute out of order, use the function
<coderef>Subst</coderef>.

        
<example>
Use R ::= Q[x,y,z];
F := x^2+y^2+z^2;
Eval(F,[1]);  -- substitute x=1
y^2 + z^2 + 1
-------------------------------
Eval(F,[1,2,3]);  -- substitute x=1, y=2, z=3
14
-------------------------------
Subst(F,y,2);  -- substitute y=2
x^2 + z^2 + 4
-------------------------------
Eval(F,[x,2,z]); -- same as above
x^2 + z^2 + 4
-------------------------------
Subst(F,[[y,y^2],[z,z^2]]);  -- substitute y^2 for y, z^2 for z
y^4 + z^4 + x^2
-------------------------------
Eval(Ideal(F),[x^2,z]); -- substitute x^2 for x, z for y
Ideal(x^4 + 2z^2)
------------------------------- 
</example>
    </description>

        <key>substitutions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="16">
        <title>First Functions</title>
        <type>1</type>

        <description>
CoCoA&apos;s gamut of functions can be easily extended with user-defined
functions.  Longer functions are usually cut-and-pasted from a text
editor into a CoCoA session.  If the functions are to be used
repeatedly, they can be saved in a separate text file and read into a
CoCoA session with the <coderef>Source</coderef> command (or <code>&lt;&lt;</code>). The usual way to
define a function is with the syntax: 
<verbatim>
   Define &lt; FunctionName &gt;(&lt; argument list &gt;) &lt; Commands &gt; EndDefine;
</verbatim>
NOTE: Variables defined within a function are usually local to that
function and disappear after the function returns.  Normally, the only
variables accessible within a function are the function&apos;s arguments
and local variables.  (For the exceptions, see the section of the
manual entitled <ref>Global Memory</ref>.)

        
<example>
Define Square(X)   -- a simple function
  Return X^2;
EndDefine;
Square(3);
9
-------------------------------
Define IsPrime(X)  -- a more complicated function
  If Type(X) &lt;&gt; INT Then Return Error(<coc-quotes>Expected INT</coc-quotes>) EndIf;
  I := 2;
  While I^2 &lt;= X Do
    If Mod(X,I) = 0 Then Return False EndIf;
    I := I+1;
  EndWhile;
  Return TRUE;
EndDefine; -- end of function definition
IsPrime(4);
FALSE
-------------------------------
Define Test(A,B)  -- a function with two arguments
  Sum := A+B;
  Prod := A*B;
  PrintLn(<coc-quotes>The sum of </coc-quotes>,A,<coc-quotes> and </coc-quotes>,B,<coc-quotes> is </coc-quotes>,Sum,<coc-quotes>.</coc-quotes>);
  Print(<coc-quotes>The product of </coc-quotes>,A,<coc-quotes> and </coc-quotes>,B,<coc-quotes> is </coc-quotes>,Prod,<coc-quotes>.</coc-quotes>);
EndDefine;
Test(3,5);
The sum of 3 and 5 is 8.
The product of 3 and 5 is 15.
------------------------------- 
</example>
    </description>

        <key>first functions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="17">
        <title>More First Functions</title>
        <type>1</type>

        <description>
A user-defined function can have any number of parameters of any
type, even a variable number of parameters.  Note that even a function
with no parameters must be called with parentheses.

        
<example>
Define Test1()
  PrintLn(<coc-quotes>This is a function with no parameters.</coc-quotes>);
  For I := 1 To 10 Do
    Print(I^2, <coc-quotes> </coc-quotes>);
  EndFor;  
EndDefine;
Test1();
This is a function with no parameters.
1 4 9 16 25 36 49 64 81 100 
-------------------------------
Define Test2(...)  -- a variable number of parameters
  If Len(ARGV) = 0 Then -- parameters are stored in the list ARGV
    Return <coc-quotes>Wrong number of parameters</coc-quotes>;
  Elsif Len(ARGV) = 1 Then 
    Print(<coc-quotes>There is 1 parameter: </coc-quotes>,ARGV[1]);
  Else
    Print(<coc-quotes>There are </coc-quotes>, Len(ARGV), <coc-quotes> parameters: </coc-quotes>);
    Foreach P In ARGV Do
      Print(P, <coc-quotes> </coc-quotes>);
    EndForeach;
  EndIf;
EndDefine;
Test2(1, 2, <coc-quotes>string</coc-quotes>,3);
There are 4 parameters: 1 2 string 3 
------------------------------- 
</example>
    </description>

        <key>more first functions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="18">
        <title>Rings Inside User-Defined Functions</title>
        <type>1</type>

        <description>
As mentioned earlier, user-defined functions cannot reference
(non-global) variables except those defined within the function or
passed as arguments.  However, functions can refer to rings via their
identifiers and use them as one would outside of a function.

<par/>
When a function is called, it assumes the current ring and performs
operations in that ring.  One may define new rings which will exist
after the function returns, but one may not change the current ring
with the command <coderef>Use</coderef>.  However, one may *temporarily* use a ring
with the command <coderef>Using</coderef>.

<par/>
To make functions more portable, it may be useful to refer to the
current ring not by its name but by using the command <coderef>CurrentRing</coderef>.

<par/>
Example I.

<par/>
Test uses the existing rings, R, S, and creates a new ring T.
While a (non-global) *variable* defined in a function will
automatically disappear, a ring (and its name) will not.

        
<example>
Use R ::= Q[x,y,z];
S ::= Q[a,b];
Define Test()
  PrintLn (x+y)^2;
  PrintLn S :: (a+b)^3;
  T ::= Z/(5)[t];
  I := T :: Ideal(t^2);
  Print I;
EndDefine;
Test();
x^2 + 2xy + y^2
S :: a^3 + 3a^2b + 3ab^2 + b^3
T :: Ideal(t^2)
-------------------------------
I;  -- the variable I was local to the function
ERROR: Undefined variable I
CONTEXT: I
-------------------------------
T;  -- The function created the ring T.  (Note: T is not a variable.)
Z/(5)[t]
------------------------------- 
</example>

Example II

<par/>
The use of <coderef>CurrentRing</coderef> within a function.

        
<example>
Define Poincare2(I)
  Return Poincare(CurrentRing()/I);
EndDefine;
Use R ::= Q[x,y];
Poincare2(Ideal(x^2,y^2));
(1 + 2x + x^2)
------------------------------- 
</example>

Example III

<par/>
Creating a ring with a user-supplied name.  For more information,
see <coderef>Var</coderef>.

        
<example>
Define Create(Var(R));
  Var(R) ::= Q[a,b];
EndDefine;
Create(<coc-quotes>K</coc-quotes>);
K;
Q[a,b]
-------------------------------
Create(<coc-quotes>myring</coc-quotes>);
Var(<coc-quotes>myring</coc-quotes>);
Q[a,b]
-------------------------------
Use Var(<coc-quotes>myring</coc-quotes>);  -- make myring current 
</example>

Example IV

<par/>
A more complicated example, creating rings whose names are
automatically generated.  See <coderef>NewId</coderef> and <coderef>Var</coderef>
for more information.

        
<example>
Define CreateRing(I)
  NewRingName := NewId();
  Var(NewRingName) ::= Q[x[1..I]],Lex;
  Return NewRingName;
EndDefine;
  
Use R ::= Q[x,y],DegRevLex;
Use S ::= Q[x,y,z],Lex;
N := 5;
For I := 1 To N Do
  RingName := CreateRing(I); -- RingName is a string
  Using Var(RingName) Do
    PrintLn Indets();
  EndUsing;
  -- Destroy Var(RingName); -- uncomment if you want to destroy the tmp
  -- ring
EndFor;

[x[1]]
[x[1], x[2]]
[x[1], x[2], x[3]]
[x[1], x[2], x[3], x[4]]
[x[1], x[2], x[3], x[4], x[5]]

-------------------------------

RingEnvs();
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>V#1</coc-quotes>, <coc-quotes>V#3</coc-quotes>, <coc-quotes>V#5</coc-quotes>, <coc-quotes>V#7</coc-quotes>, <coc-quotes>V#9</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>rings inside user-defined functions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="19">
        <title>Rational Normal Curve</title>
        <type>1</type>

        <description>
In this example, we compute the ideal of the rational normal curve of
degree <formula>N</formula> in <formula>P^N</formula> then compute its Poincare series for a range of values
of <formula>N</formula>. 

        
<example>
Define Minor2(M, I, J)
  Return M[1,I] M[2,J] - M[2,I] M[1,J];
EndDefine;

Define Rational_Normal_Curve_Ideal(N)
  -- first define the 2xN matrix whose 2x2 minors generate the ideal
  M := NewMat(2,N);
  For C := 0 To N-1 Do
    M[1,C+1] := x[C];
    M[2,C+1] := x[C+1];
  EndFor;
  -- then construct the generators of the ideal
  L := [];
  For C1 := 1 To N-1 Do
    For C2 := C1+1 To N Do
      P := M[1,C1] M[2,C2] - M[2,C1] M[1,C2];
      -- determinant for columns C1,C2
      Append(L,P)
    EndFor;
  EndFor;
  Return Ideal(L);
EndDefine;

For N := 3 To 5 Do  
  S ::= Q[x[0..N]],Lex;
  PrintLn NewLine, <coc-quotes>degree </coc-quotes>, N;
  Using S Do  -- switch, temporarily, to ring S
    I := Rational_Normal_Curve_Ideal(N);
    Print(<coc-quotes>Poincare series: </coc-quotes>), Poincare(S/I);
  EndUsing; 
  PrintLn; 
EndFor; -- for statement

degree 3
Poincare series: (1 + 2x[0]) / (1-x[0])^2

degree 4
Poincare series: (1 + 3x[0]) / (1-x[0])^2

degree 5
Poincare series: (1 + 4x[0]) / (1-x[0])^2

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

        <key>rational normal curve</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="20">
        <title>Generic Minors</title>
        <type>1</type>

        <description>
The following example computes the relations among the 2x2 minors of
a generic 2xN matrix for a range of values of N.  Note the use of
indeterminates with multiple indices.

        
<example>
Define Minor2(M, I, J)
  Return M[1,I] M[2,J] - M[2,I] M[1,J];
EndDefine;

Define Det_SubAlgebra(N)
  M := Mat([[x[I,J] | J In 1..N] | I In 1..2]);
  Cols := (1..N) &gt;&lt; (1..N);
  L := [ y[C[1],C[2]] - Minor2(M, C[1], C[2]) | C In Cols And C[1] &lt; C[2] ];
  Return Ideal(L);
EndDefine; 

Define Det_SubAlgebra_Print(N)  -- calculate and print relations
  J := Det_SubAlgebra(N);
  PrintLn NewLine, <coc-quotes>N = </coc-quotes>, N;
  PrintLn <coc-quotes>Sub-algebra equations:</coc-quotes>;
  PrintLn Gens(Elim(x,J))
EndDefine;

Set Indentation;
For N := 3 To 5 Do
  S ::= Z/(32003)[y[1..(N-1),2..N],x[1..2,1..N]];
  Using S Do
    Det_SubAlgebra_Print(N);
  EndUsing
EndFor;

N = 3
Sub-algebra equations:
[
  0]

N = 4
Sub-algebra equations:
[
  2y[1,4]y[2,3] - 2y[1,3]y[2,4] + 2y[1,2]y[3,4]]

N = 5
Sub-algebra equations:
[
  2y[2,5]y[3,4] - 2y[2,4]y[3,5] + 2y[2,3]y[4,5],
  2y[1,5]y[3,4] - 2y[1,4]y[3,5] + 2y[1,3]y[4,5],
  2y[1,5]y[2,4] - 2y[1,4]y[2,5] + 2y[1,2]y[4,5],
  2y[1,5]y[2,3] - 2y[1,3]y[2,5] + 2y[1,2]y[3,5],
  2y[1,4]y[2,3] - 2y[1,3]y[2,4] + 2y[1,2]y[3,4]]

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

        <key>generic minors</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="21">
        <title>Leading Term (Initial) Ideals, Generic Polynomials</title>
        <type>1</type>

        <description>
The following example produces the leading term (initial) ideal of
the ideal generated by three <em>generic</em> polynomials of degree 2 with
respect to the lexicographic term-ordering.

        
<example>
Use R ::= Z/(32003)[x[1..4]],Lex;
F := DensePoly(2);  -- sum of all power-products of degree 2 
L := [ Randomized(F) | I In 1..3 ]; -- randomize coefficients
LT(Ideal(L));
Ideal(x[1]^2, x[1]x[2], x[1]x[3], x[2]^3, x[1]x[4]^2, x[2]^2x[3],
x[2]^2x[4]^2, x[2]x[3]^3, x[2]x[3]^2x[4]^2, x[2]x[3]x[4]^4,
x[2]x[4]^6, x[3]^8) 
------------------------------- 
</example>
    </description>

        <key>leading term (initial) ideals, generic polynomials</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="22">
        <title>Ring Mapping Example</title>
        <type>1</type>

        <description>
If R is the current ring and E is an object in another ring, then the
function <coderef>Image</coderef> may be used to map E into R by substituting
polynomials from R for the indeterminates in E.  (Also: see the
command <coderef>BringIn</coderef> for a shortcut in certain cases.)

        
<example>
Use S ::= Q[a,b,c];
I := Ideal(a^2+b^2,ab-c^2);
Use R ::= Q[x,y];  -- the current ring is R
F := RMap(x+y,x-y,y^2); -- define a map F:S --&gt; R sending a to x+y, 
                        -- b to x-y, and c to y^2
Image(I,F); -- the image of I under F
Ideal(2x^2 + 2y^2, -y^4 + x^2 - y^2)
------------------------------- 
</example>
    </description>

        <key>ring mapping example</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="23">
        <title>Output to a File</title>
        <type>1</type>

        <description>
The following example illustrates one way of saving CoCoA output to a
file.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(t^2-x,t^5-y,t^7-z);
G := GBasis(I);
G;
[t^2 - x, -tx^2 + y, -x^3 + ty, -xy + z, -ty^2 + x^2z, txz - y^2, y^3 - tz^2]
-------------------------------
D := OpenOFile(<coc-quotes>MyFile</coc-quotes>); -- open <coc-quotes>MyFile</coc-quotes> for output from CoCoA
Print G On D;  -- G is appended to the file <coc-quotes>MyFile</coc-quotes>
Close(D); 
</example>

Text can be read from files using <coderef>OpenIFile</coderef> and <coderef>Get</coderef>, and commands
can be executed from files using <coderef>Source</coderef>.  One may also
keep a log of a CoCoA session (see <coderef>OpenLog</coderef>)
    </description>

        <key>output to a file</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="24">
        <title>Finite Point Sets: Buchberger-Moeller</title>
        <type>1</type>

        <description>
CoCoA includes an implementation of the Buchberger-Moeller algorithm
for efficient computations dealing with finite sets of points.  These
functions include:

<par/>
  * GBM, HGBM -- intersection of ideals for zero-dimensional schemes 

<par/>
  * IdealAndSeparatorsOfPoints -- ideal and separators for affine points

<par/>
  * IdealAndSeparatorsOfProjectivePoints -- ideal and separators for points

<par/>
  * IdealOfPoints -- ideal of a set of affine points

<par/>
  * IdealOfProjectivePoints -- ideal of a set of projective points

<par/>
  * Interpolate -- interpolating polynomial

<par/>
  * SeparatorsOfPoints -- separators for affine points

<par/>
  * SeparatorsOfProjectivePoints -- separators for projective points

<par/>
Details about these functions may be found individually in the online
manual.  Briefly, the functions above may be used to find the ideal of
a set of points in affine or projective space along with a reduced
Groebner basis and separators.  Separators are polynomials that take
the value 1 on one of the points and 0 on the remainder.  The
Buchberger-Moeller algorithm works *much* faster than the
straightforward technique involving intersecting ideals for the
individual points.

        
<example>
Use R ::= Q[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
-------------------------------
Hilbert(R/X.Ideal);
H(0) = 1
H(1) = 4
H(2) = 10
H(t) = 20   for t &gt;= 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 --&gt; R^10(-6) --&gt; R^24(-5) --&gt; R^15(-4) --&gt; R
------------------------------- 
</example>
    </description>

        <key>finite point sets: buchberger-moeller</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="25">
        <title>Syzygies and Resolution Example</title>
        <type>1</type>

        <description>
The following example, among other things, computes the resolution of
ideals of sets of points.

        
<example>
Use R ::= Q[x,y,z];
X1 := [[0,0,1],[1,0,1],[2,0,1],[2,1,1]]; -- 4 points in the projective
                                         -- plane
X2 := [[0,0,1],[1,0,1],[0,1,1],[1,1,1]]; -- 4 more points
I1 := IdealOfProjectivePoints(X1);
I2 := IdealOfProjectivePoints(X2);
Hilbert(R/I1);  -- the Hilbert function of X1
H(0) = 1
H(1) = 3
H(x) = 4   for t &gt;= 2
-------------------------------
Hilbert(R/I2) = Hilbert(R/I1);  -- The Hilbert functions for X1 and X2
                                -- are the same
TRUE
-------------------------------
Res(R/I1);                      -- but the resolutions ... 
0 --&gt; R(-3)(+)R(-4) --&gt; R^2(-2)(+)R(-3) --&gt; R
-------------------------------
Res(R/I2);                      -- are different.
0 --&gt; R(-4) --&gt; R^2(-2) --&gt; R
-------------------------------
Describe Res(R/I1);  -- more information about the resolution for X1
Mat([
  [xy - 2yz, y^2 - yz, x^3 - 3x^2z + 2xz^2]
])
Mat([
  [y - z, x^2 - xz],
  [-x + 2z, 0],
  [0, -y]
])
-------------------------------
Syz(I1,1);  -- the first syzygy module for X1
Module([y - z, -x + 2z, 0], [x^2 - xz, 0, -y])
------------------------------- 
</example>
    </description>

        <key>syzygies and resolution example</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="26">
        <title>Factoring Polynomials</title>
        <type>1</type>

        <description>
CoCoA can factor a polynomial over its coefficient ring.

        
<example>
Use R ::= Q[x,y];
F := x^12 - 37x^11 + 608x^10 - 5852x^9 + 36642x^8 - 156786x^7 + 468752x^6
    - 984128x^5 + 1437157x^4 - 1422337x^3 + 905880x^2 - 333900x + 54000;
Factor(F);
[[x - 2, 1], [x - 4, 1], [x - 6, 1], [x - 3, 2], [x - 5, 3], [x - 1, 4]]
-------------------------------
F := (x+y)^2*(x^2y+y^2x+3);
F;
x^4y + 3x^3y^2 + 3x^2y^3 + xy^4 + 3x^2 + 6xy + 3y^2
-------------------------------
Factor(F);  -- multivariate factorization
[[x^2y + xy^2 + 3, 1], [x + y, 2]]
-------------------------------
Use Z/(37)[x];
Factor(x^6-1);
[[x - 1, 1], [x + 1, 1], [x + 10, 1], [x + 11, 1], [x - 11, 1], [x - 10, 1]]
------------------------------- 
</example>
    </description>

        <key>factoring polynomials</key>
      </section>

    </chapter>


  </part>
  <part number="3">
    <name>The CoCoA Programming Language</name>
<!-- ===  CHAPTER  =============================================== -->
    <chapter number="1">
      <chapter_name>Introduction to CoCoA Programming</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>An Overview of CoCoA Programming</title>
        <type>1</type>

        <description>
The CoCoA system includes a full-fledged high level programming
language, CoCoAL, 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 <coderef>Source</coderef> command.

<par/>
The most important construct in CoCoA programming is the user-defined
function, created with <coderef>Define</coderef>.  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>

        <key>an overview of cocoa programming</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="2">
      <chapter_name>Language Elements</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <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 <code>|</code> 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         <coc-quotes>  </coc-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 |
   | &lt;=   less than or equal to       /*   start comment      |
   | &gt;=   greater than or equal to    */   end comment        |
   | &gt;&lt;   Cartesian product           ::   ring casting       |
   | ::=  ring definition             ...  dots               |
    ----------------------------------------------------------
                     Special Character-groups
</verbatim>

    </description>

        <key>character set and special symbols</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Identifiers</title>
        <type>1</type>

        <description>
There are two types of identifiers or names.

<par/>
  * Identifiers of ring indeterminates. They must begin with lower case
    letters.

<par/>
  * Predefined or user-defined names (functions and CoCoAL variables).
    They must begin with upper case letters.
    </description>

        <key>identifiers</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Names of Indeterminates</title>
        <type>2</type>

        <description>
Each indeterminate of a polynomial ring may have one of the following
forms:

<par/>
   * a single lower case letter;
   * a single lower case letter, indexed by one or more integer
     expressions, separated by commas, and enclosed by square
     brackets, e.g. x[1,3+5,2].
    </description>

        <key>names of indeterminates</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Reserved Names</title>
        <type>1</type>

        <description>
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.

<verbatim>
     ----------------------------------------------------
    | Alias      And      Block       Catch     Ciao     |
    | Clear      Cond     Define      Delete    Describe |
    | Destroy    Do       Elif        Else      End      |
    | EndBlock   EndCatch EndCond     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    |
     ----------------------------------------------------
           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    VECTOR |
    | Xel       ZMOD                              |
     --------------------------------------------
            Case sensitive reserved names
</verbatim>

    </description>

        <key>reserved names</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Comments</title>
        <type>1</type>

        <description>
A comment begins with the symbol <code>/*</code> and ends with the symbol <code>*/</code>.
Comments may contain any number of characters and are always treated as
white space.  Comments may be nested and may span several lines.

<par/>
In addition, text starting with <code>//</code> or <code>--</code> up to the end of a line is
also considered comment.

        
<example>
// This is a line comment 
Print 1+1; -- a command followed by a comment
2
-------------------------------
/* example of /* nested */ comment */ 
</example>
    </description>

        <key>comments</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Data Types</title>
        <type>1</type>

        <description>
Each CoCoA object has a type.  The possible types are:
<verbatim>
  BOOL     : A boolean.  The boolean constants are TRUE and FALSE.
  DEVICE   : For input/output.
  ERROR    : Objects of this type are used in error-handling.
  FUNCTION : A CoCoA-defined function.
  IDEAL    : An ideal.
  INT      : An arbitrary precision integer.
  LIST     : A list.
  MAT      : A matrix.
  MODULE   : A submodule of a free module. 
  NULL     : The null constant is Null.
  POLY     : A polynomial.
  RAT      : An arbitrary precision rational number.
  RATFUN   : A rational function.
  RECORD   : A record is a set of bindings, name --&gt; object.
  RING     : A base ring, a polynomial ring, or a quotient ring.
  STRING   : A string.
  TAGGED   : Used to help in printing complicated objects.
  TYPE     : Returned by the function <code>Type</code>, for example.
  VECTOR   : A vector.
  ZMOD     : An integer modulo another integer, e.g. 3 % 5.
</verbatim>
The types are partially ordered by inclusion of the sets that they
represent, as follows:
<verbatim>
  MAT &lt; LIST
  VECTOR &lt; LIST
  INT &lt; RAT &lt; POLY &lt; RATFUN
  ZMOD &lt; POLY &lt; RATFUN  (if compatible).
</verbatim>
In the manual, OBJECT is used to refer to an arbitrary CoCoA type.  It
is not a type itself.
    </description>

        <key>data types</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Commands and Functions for Data Types</title>
        <type>2</type>

        <description>
The following are commands and functions for data types:
<commands_and_functions_for type="type"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for data types</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="3">
      <chapter_name>Operators</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <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 <code>&gt;&lt;</code>
for forming Cartesian products of lists and an operator <code>::</code> used in
defining rings.

<par/>
The meaning of an operator depends on the types of its operands; the <code>+</code>
in the expression <code>A + B</code> represents the sum of polynomials, or of
ideals, or of matrices, etc. according to the type of A and B.

<par/>
The multiplication symbol <code>*</code> can always be omitted.  The expression
<code>F(E)</code> is intrinsically ambiguous; it can be the variable F multiplied
by the parenthesized expression E, or the application of the function
F to the argument E. CoCoA always interprets this expression in the
latter way. In the former case the user must separate F from the left
parenthesis with a blank or an <code>*</code>.

<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
    Not
    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.

<par/>
Furthermore there is the n-ary operator <code>&gt;&lt;</code> (made by using a greater
than sign <code>&gt;</code> and a less than sign <code>&lt;</code>) for making Cartesian
products of lists (see <coderef>&gt;&lt;</coderef>, <em>Cartesian Product</em>) and the operator
<code>::</code> for defining rings (see <ref>New Rings</ref> and <coderef>Use</coderef>).
    </description>

        <key>cocoa operators</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <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 <code>:</code> 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    ZMOD   POLY   RATFUN  VECTOR IDEAL MODULE MAT LIST
INT    +-*/^  +-*/   *      +-*/   +-*/     *     *     *      *   *
RAT    +-*/^  +-*/          +-*/   +-*/     *     *     *      *   *
ZMOD   *^            +-*/   +-*/   +-*/     *     *     *      *   *
POLY   +-*/^  +-*/   +-*/   +-*/   +-*/     *     *     *      *   *
RATFUN +-*/^  +-*/   +-*/   +-*/   +-*/                        *   *
VECTOR *      *      *      *               +-
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 <coderef>Div</coderef> and <coderef>Mod</coderef> 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>

        <key>algebraic operators</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Relational Operators</title>
        <type>1</type>

        <description>
The relational operators are:
      
<verbatim>
      =    &lt;&gt;    &lt;    &gt;    &lt;=    &gt;=   IsIn
</verbatim>

The operator <coderef>IsIn</coderef> is quite flexible: see its manual for an explanation.
The other relational operators can be applied to two objects of the same type.
The admissible types for <code>=</code> and <code>&lt;&gt;</code> are:

<verbatim>
     NULL, BOOL, STRING, TYPE, INT, RAT, ZMOD, POLY, RATFUN, 
     VECTOR, IDEAL, MODULE, MAT, LIST.
</verbatim>

The admissible types for the other relational operators are:

<verbatim>
     STRING, TYPE, INT, RAT, IDEAL, MODULE.
</verbatim>

The meaning of <code>&lt;</code> for string is the lexicographic comparison.  For
ideals and modules <code>A &lt; B</code> and <code>A &lt;= B</code> both mean that A is (not
necessarily strictly) contained in B.

<par/>
NOTE: It is sometimes hard to judge the type of an expression from the
appearance of CoCoA output, leading to confusing results from the
relational operators.  Here is an simple example:

        
<example>
L:=<coc-quotes>3</coc-quotes>;
L;
3
-------------------------------
L=3;
FALSE
-------------------------------
Type(L);
STRING
-------------------------------
Type(3);
INT
------------------------------- 
</example>

Tagged expressions are especially prone to causing confusion of this
sort.
    </description>

        <key>=</key>
        <key>equality</key>
        <key>relational operators</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Boolean Operators</title>
        <type>1</type>

        <description>
The boolean operators are:
<verbatim>
      Not  And  Or
</verbatim>
see <ref>Introduction to Booleans</ref>.
    </description>

        <key>boolean operators</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <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, VECTOR, 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. |
   | VECTOR       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 <code>L.N</code> indicates the
object contained in the field N of the record L (see <ref>Introduction to
Records</ref> and <ref>Records</ref>).
    </description>

        <key>selection operators</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Range Operator</title>
        <type>1</type>

        <description>
If M and N are of type INT, then the expression:
<verbatim>
      M .. N
</verbatim>
returns 
<verbatim>
      * the list [M, M+1, ... ,N] if M &lt;= N;
      * the empty list, [], otherwise.
</verbatim>
If x and y are indeterminates in a ring, then
 <verbatim>
      x .. y
</verbatim>
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 ::= Q[x,y,z,a,b,c,d];
z..c;
[z, a, b, c]
------------------------------- 
</example>
    </description>

        <key>range operator</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="4">
      <chapter_name>Evaluation and Assignment</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <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
<code>It</code>.

        
<example>
2 + 2;
4
-------------------------------
It + 3;
7
-------------------------------
It;
7
-------------------------------
X := 5;
It;
7
------------------------------- 
</example>
The command <code>X := 5</code> is an assignment, not an evaluation; so it does
not change the value of the variable <code>It</code>.

If an error occurs during the evaluation of an expression, then the
evaluation is interrupted and the user is notified about the error.
    </description>

        <key>evaluation</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <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 (see the chapter entitled <ref>Memory Management</ref>).  If E
is dependent upon a ring, then L is labeled with that ring.  The label
is listed when L is evaluated in another ring.  Then command
<code>RingEnv(L)</code> will return the label for L.


<example>
Use R ::= Q[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 = xz];
P.Degree := Deg(P.F);
P;
Record[Degree = 2, F = xz]
-------------------------------
Use S ::= Q[a,b];
I;  -- I is labeled by R since it depends on R
R :: Ideal(x, y)
-------------------------------
T;  -- T is not labeled by R
14
-------------------------------
J := R:: Ideal(x^2-y);  -- J contains an object dependent on R
J; -- since the ring S is active, J is labeled by R
R :: Ideal(x^2 - y)
-------------------------------
Use R;
J;
Ideal(x^2 - y)
------------------------------- 
</example>

For information about interacting with rings outside of the current
ring, see <ref>Accessing Other Rings</ref> in the chapter entitled <ref>Rings</ref>.

To assign values to global variables, see <ref>Introduction to Memory</ref> or
<ref>Global Memory</ref>.
    </description>

        <key>assignment</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="5">
      <chapter_name>User-Defined Functions</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to User-Defined Functions</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 <coderef>Source</coderef>.  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> as described in a later chapter.

<par/>
To learn about user functions, look up <coderef>Define</coderef> (online, enter
<code>?define</code>) for the complete syntax and for examples.  The <ref>Tutorial</ref>
also contains several examples of functions.
    </description>

        <key>introduction to user-defined functions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for User-Defined Functions</title>
        <type>1</type>

        <description>
User-defined functions can contain just about any CoCoA command and
may refer to other user-defined functions.  The following are some
commands that pertain particularly to functions:
<commands_and_functions_for type="function"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for user-defined functions</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="6">
      <chapter_name>Flow Control: Conditional Statements and Loops</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <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>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for branching</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <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>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for loops</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="7">
      <chapter_name>Input/Output</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to IO</title>
        <type>1</type>

        <description>
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 <coderef>Source</coderef> command---be executed as CoCoA
commands.
    </description>

        <key>introduction to io</key>
        <key>devices</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Standard IO</title>
        <type>2</type>

        <description>
Standard IO is what takes places normally when one interacts with
CoCoA via the CoCoA window.  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 <coderef>Print</coderef> and <coderef>PrintLn</coderef> for more control over the
format of the output.

<par/>
The official devices that are being used here are <code>DEV.STDIN</code> and
<code>DEV.OUT</code>. So for instance, the commands <coderef>Get</coderef> and <coderef>Print On</coderef> can be
used with the standard devices although they are really meant to be
used with the other devices.  <code>Print E On DEV.OUT</code> is synonymous with
<code>Print E</code>.  Also, one may use <code>Get(DEV.STDIN,10)</code>, for example, to get
the next 10 characters typed in the CoCoA window.  Thus, clever use of
<coderef>Get</coderef> 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>

        <key>standard io</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>File IO</title>
        <type>2</type>

        <description>
To print CoCoA output to a file, one first opens the file
with <coderef>OpenOFile</coderef> then prints to the file using <coderef>Print On</coderef>.

<par/>
To receive verbatim input from a file, one first opens the file with
<coderef>OpenIFile</coderef>, then gets characters from the file with <coderef>Get</coderef>.  Actually,
<coderef>Get</coderef> gets a list of ascii codes for the characters in the file.
These can be converted to real characters using the function <coderef>Ascii</coderef>.

        
<example>
D := OpenOFile(<coc-quotes>my-file</coc-quotes>); -- open text file with name <coc-quotes>my-file</coc-quotes>,
                           -- creating it if necessary
Print <coc-quotes>hello world</coc-quotes> On D; -- append <coc-quotes>hello world</coc-quotes> to my-file
Close(D); -- close the file
D := OpenIFile(<coc-quotes>my-file</coc-quotes>); -- open <coc-quotes>my-file</coc-quotes>
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 <coderef>Source</coderef> command.  For instance, if the
file <code>MyFile.coc</code> contains a list of CoCoA commands, then
<verbatim>
  Source(MyFile.coc);
</verbatim>
reads and executes the commands.
    </description>

        <key>file io</key>
        <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>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>String IO</title>
        <type>2</type>

        <description>
To print CoCoA output to a string, on may use <coderef>OpenOString</coderef> to
<em>open</em> the string, then <coderef>Print On</coderef> to write to it.  To read from a
string, one may open the string for input with <coderef>OpenIString</coderef> then get
characters from it with <coderef>Get</coderef>.

        
<example>
S := <coc-quotes>hello world</coc-quotes>;
D := OpenIString(<coc-quotes></coc-quotes>,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(<coc-quotes></coc-quotes>);  -- open a string for output from CoCoA
L := [1,2,3]; -- a list
Print L On D;  -- print to D
D;
Record[Name = <coc-quotes></coc-quotes>, Type = <coc-quotes>OString</coc-quotes>, Protocol = <coc-quotes>CoCoAL</coc-quotes>]
-------------------------------
S := Cast(D,STRING);  -- S is the string output printed on D
S; -- a string
[1, 2, 3]
Print <coc-quotes> more characters</coc-quotes> 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 <coderef>Sprint</coderef>.
    </description>

        <key>string io</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <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>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for io</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Tagged Printing</title>
        <type>1</type>

        <description>
Some CoCoA objects are intrinsically complicated, so printing them
verbatim might be confusing.  For this reason a mechanism has been
implemented which enables automatic pretty printing through the use of
<em>tags</em>.  A user may <em>tag</em> any object with a string and then define
how objects tagged with that string should be printed or described.
Commands that do not have to do with printing ignore the tag.
    </description>

        <key>tagged printing</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Tagging an Object</title>
        <type>2</type>

        <description>
If E is any CoCoA object and S a string, then the function
<code>Tagged(E,S)</code> returns the object E tagged with the string S.  The type
of the returned object is <code>TAGGED(S)</code> (but the type of E is
unchanged).  The function <coderef>Tag</coderef> returns the tag string of an object,
and the function <coderef>Untagged</coderef> (or <code>@</code>) returns the object, stripped of
its tag.

        
<example>
L := [<coc-quotes>Dave</coc-quotes>,<coc-quotes>March 14, 1959</coc-quotes>,372];
M := Tagged(L, <coc-quotes>MiscData</coc-quotes>);  -- L has been tagged with the string <coc-quotes>MiscData</coc-quotes>
Type(L);  -- L is a list
LIST
-------------------------------
Type(M);  -- M is a tagged object
TAGGED(<coc-quotes>MiscData</coc-quotes>)
-------------------------------
Tag(M); -- the tag string of M (it would be the empty string if M
        -- where not a tagged object).
MiscData
-------------------------------
M;  -- Until a special print function is defined, the printing of L
    -- and M is identical.
[<coc-quotes>Dave</coc-quotes>, <coc-quotes>March 14, 1959</coc-quotes>, 372]
-------------------------------
Untagged(M) = L; -- <coc-quotes>Untagged</coc-quotes> removes the tag from M, recovering L.
TRUE
------------------------------- 
</example>
The next section explains how to define functions for pretty printing
of tagged objects.
    </description>

        <key>tagging an object</key>
        <key>dave</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>Printing a Tagged Object</title>
        <type>2</type>

        <description>
Suppose the object E is tagged with the string S.  When one tries to
print E---say with <code>Print E</code> or just <code>E;</code>--- CoCoA looks for a
user-defined function with name <code>Print_S</code>.  If no such function is
available, CoCoA prints E as if it were not tagged, otherwise, it
executes <code>Print_S</code>.

        
<example>
L := [<coc-quotes>Dave</coc-quotes>,<coc-quotes>March 14, 1959</coc-quotes>,372];  -- continuing with the previous example
M := Tagged(L,<coc-quotes>MiscData</coc-quotes>);
M; -- M is printed as normal in the absence of a function <coc-quotes>Print_MiscData</coc-quotes>
[<coc-quotes>Dave</coc-quotes>, <coc-quotes>March 14, 1959</coc-quotes>, 372]
-------------------------------
Define Print_MiscData(X) -- Exactly one parameter is required.
  M := Untagged(X); 
  Print(M[1]);
EndDefine;
Print M; -- Now, any object tagged with the string <coc-quotes>MiscData</coc-quotes> will be
   -- printed using Print_MiscData
Dave
-------------------------------
M;  -- Whenever printing of M is called for, <coc-quotes>Print_MiscData</coc-quotes> is executed.
Dave
------------------------------- 
</example>
The line <code>M := Untagged(X)</code> is actually not necessary here, but in
general one may get into an infinite loop trying to print X, a tagged
object, from within the function that is being defined in order to
print X, if that makes sense.  Untagging X prevents this problem.
    </description>

        <key>printing a tagged object</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="9">
        <title>Describing a Tagged Object</title>
        <type>2</type>

        <description>
If the object E is tagged with the string S, then when the user
enters the command <code>Describe E</code>, CoCoA first looks for a user-defined
function with name <code>Describe_S</code> and executes it; if not found, the
output depends on the type of Untagged(E).

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x-y^2,x-z^3);
I := Tagged(I,<coc-quotes>MyIdeals</coc-quotes>);  -- I is now tagged with <coc-quotes>MyIdeals</coc-quotes>
Describe I;  -- the default description of an ideal
Record[Type = IDEAL, Value = Record[Gens = [-y^2 + x, -z^3 + x]]]
-------------------------------
Define Describe_MyIdeals(X)
  Y := Untagged(X);
  PrintLn(<coc-quotes>The generators are:</coc-quotes>);
  Foreach G In Y.Gens Do
    PrintLn(<coc-quotes>  </coc-quotes>, G);
  EndForeach;
EndDefine;
Describe I;  -- Any object tagged with <coc-quotes>MyIdeals</coc-quotes> is now described
             -- using <coc-quotes>Describe_MyIdeals</coc-quotes>. 
The generators are:
  -y^2 + x
  -z^3 + x

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

        <key>describing a tagged object</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="10">
        <title>Another Example Using Tags</title>
        <type>2</type>

        <description>
Here is one more example using tags.  Note that CoCoA commands that
do not have to do with printing ignore tags.

        
<example>
N := Tagged(4,<coc-quotes>Dots</coc-quotes>);
N;
4
-------------------------------
Define Print_Dots(X)
  For I := 1 To X Do
    Print <coc-quotes>.</coc-quotes>
  EndFor
EndDefine;
N;
....
-------------------------------
N+N;  -- As long as printing is not involved, N is treated as if
      -- it has no tag.  In this case, the sum of two tagged objects
      -- returns an integer, not another tagged object.
8
-------------------------------
M := Tagged(12,<coc-quotes>Dots</coc-quotes>);
M;
............
------------------------------- 
</example>
    </description>

        <key>another example using tags</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="11">
        <title>Commands and Functions for Tags</title>
        <type>2</type>

        <description>
The following are commands and functions involving tags:
<commands_and_functions_for type="tags"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for tags</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="8">
      <chapter_name>Memory Management</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Memory</title>
        <type>1</type>

        <description>
CoCoA has three types of memory: <em>working</em>, <em>global</em>, and
<em>ring-bound</em> memory.  Unlike previous versions of CoCoA, starting
with CoCoA 3.5, variables defined during a session are by default
assigned to a *working memory*, accessible from all rings (but not
from user-defined functions).  There are no longer variables that are
local to a particular ring.  However, as in previous versions of
CoCoA, one may define variables in the *global memory* by using the
prefix <code>MEMORY</code>.  The word <em>global</em> now refers to the fact that these
variables are accessible not only to all rings but also to
user-defined functions.  A special class of global variables can be
stored in what is called the *ring-bound memory*. These variables are
formed with the prefix <code>MEMORY.ENV.R</code> where <code>R</code> is a ring identifier;
they are <em>bound</em> to the ring, which means that they are automatically
destroyed when their corresponding rings cease to exist.  Otherwise,
variables in the ring-bound memory behave exactly as all other global
variables.  Most users will never need the ring-bound memory.

<par/>
These three types of memory are discussed separately, below.
    </description>

        <key>introduction to memory</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Working Memory</title>
        <type>1</type>

        <description>
The *working memory* consists of all variables except those defined
with the prefix <code>MEMORY</code>, e.g. <code>MEMORY.X</code>.  All variables in the
working memory are accessible from all rings, but they are not
accessible from within a user-define function (see examples in the
next section).  The function <code>Memory</code> displays the contents of the
working memory. More information is provided by <code>Describe Memory()</code>.

<par/>
Ring-dependent variables such as those containing polynomials, ideals,
or modules, are labeled by their corresponding rings.  If the ring of
a ring-dependent variable in the working memory is destroyed, the
variable will continue to exist, but labeled by a ring automatically
generated by CoCoA.  Once all variables dependent on this new ring
cease to exist, so does the ring. 

        
<example>
Use R ::= Q[x,y,z];
Memory();  -- the working memory is empty
[ ]
-------------------------------
I:= Ideal(xy-z^3,x^2-yz);
X := 3;
M := Mat([[1,2],[3,4]]);
Memory();
[<coc-quotes>I</coc-quotes>, <coc-quotes>It</coc-quotes>, <coc-quotes>M</coc-quotes>, <coc-quotes>X</coc-quotes>]
-------------------------------
Describe Memory();
------------[Memory]-----------
I = Ideal(-z^3 + xy, x^2 - yz)
It = [<coc-quotes>I</coc-quotes>, <coc-quotes>It</coc-quotes>, <coc-quotes>M</coc-quotes>, <coc-quotes>X</coc-quotes>]
M = Mat([
  [1, 2],
  [3, 4]
])
X = 3
-------------------------------
Use S ::= Z/(3)[t];  -- switch to a different ring
X := t^2+t+1;  -- the identifier X is used again
Y := 7;
Describe Memory();  -- note that I is labeled by its ring
------------[Memory]-----------
I = R :: Ideal(-z^3 + xy, x^2 - yz)
It = [<coc-quotes>I</coc-quotes>, <coc-quotes>It</coc-quotes>, <coc-quotes>M</coc-quotes>, <coc-quotes>X</coc-quotes>]
M = Mat([
  [1, 2],
  [3, 4]
])
X = t^2 + t + 1
Y = 7
-------------------------------
GBasis(I);  -- The Groebner basis for the ideal in R can be calculated
            -- even though the current ring is S.
[R :: x^2 - yz, R :: -z^3 + xy]
-------------------------------
M^2;
Mat([
  [7, 10],
  [15, 22]
])
-------------------------------
Use R ::= Q[s,t];  -- redefine the ring R
I;  -- Note that I is labeled by a new ring, automatically produced by
    -- CoCoA.  This ring will automatically cease to exist when there
    -- are no longer variables dependent upon it, as shown below.
R#17 :: Ideal(-z^3 + xy, x^2 - yz)
-------------------------------
RingEnvs();
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>R#17</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
I:=3; -- I is overwritten with an integer, and since it is the only
      -- variable dependent on R#17, the ring R#17 ceases to exist.
RingEnvs();  -- Since the only variable that was dependent upon the 
             -- temporary ring <coc-quotes>R#17</coc-quotes> was overwritten, that ring is
             -- destroyed.
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>working memory</key>
        <see>Commands and Functions for Memory</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Global Memory</title>
        <type>1</type>

        <description>
Starting with CoCoA 3.5, a <em>global</em> variable is one that is
accessible from within a user-defined function.  A global variable is
formed by using the prefix <code>MEMORY</code>.  The special prefixes <code>DEV</code>,
<code>ENV</code>, <code>ERR</code>, and <code>PKG</code> are shorthand for <code>MEMORY.DEV</code>, <code>MEMORY.ENV</code>,
etc.  Any global variable prefixed by <code>MEMORY.ENV.R</code> where <code>R</code> is the
identifier of a ring, becomes part of the ring-bound memory discussed
in the next section.  A list of the global variables which are not
ring-bound is provided by the function <coderef>GlobalMemory</coderef>.

        
<example>
Use R ::= Q[x,y,z];
X := 5;  -- a variable called <coc-quotes>X</coc-quotes> in the working memory
MEMORY.X := 7; -- a global variable
X;
5
-------------------------------
MEMORY.X;
7
-------------------------------
Memory();  -- the working memory
[<coc-quotes>It</coc-quotes>, <coc-quotes>X</coc-quotes>]
-------------------------------
GlobalMemory(); -- the global memory
[<coc-quotes>DEV</coc-quotes>, <coc-quotes>ENV</coc-quotes>, <coc-quotes>ERR</coc-quotes>, <coc-quotes>PKG</coc-quotes>, <coc-quotes>X</coc-quotes>]
-------------------------------
Define Test()
  PrintLn(MEMORY.X);
  MEMORY.X := <coc-quotes>a new value</coc-quotes>;
  PrintLn(X);
EndDefine;
-- MEMORY.X is accessible from within a function
-- X is not accessible within a function (thus we get an error) 
Test(); 
7


-------------------------------
ERROR: Undefined variable X
CONTEXT: PrintLn(X)
-------------------------------
MEMORY.X;  -- the contents of the global memory can be changed from
           -- within a function
a new value
-------------------------------
Fields(MEMORY.ENV);  -- a list of all defined rings
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>global memory</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Ring-Bound Memory</title>
        <type>1</type>

        <description>
A variable prefixed by <code>MEMORY.ENV.R</code> where <code>R</code> is the identifier of
a ring, becomes bound to the ring R.  This means that when R ceases to
exist, so does the variable (unlike variables that are part of the
working memory, labeled by R: see <ref>Working Memory</ref>, above).  The
collection of these variables comprises the *ring-bound memory.*
The variables bound to a ring R can be listed with the command
<code>Memory(R)</code>. Note that since ring-bound variables are, in particular,
prefixed by <code>MEMORY</code>, they are also part of the global memory
discussed in the previous section.

<par/>
Most users will never need ring-bound variables.  Their main use is
within functions which need to define and use rings temporarily,
destroying them (along with their variables) before returning.

<par/>
The prefix <code>ENV</code> is shorthand for <code>MEMORY.ENV</code>.

        
<example>
Use R ::= Q[x,y,z];
X := Ideal(x,y);  -- a variable in the current memory
ENV.R.Y := <coc-quotes>bound to R</coc-quotes>;  -- a variable in the memory bound to R
Use S ::= Q[a,b];
Z := 6;
Memory();  -- the working memory
[<coc-quotes>X</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
Memory(R);  -- the memory bound to R 
[<coc-quotes>Y</coc-quotes>]
-------------------------------
Destroy R;
Memory();
[<coc-quotes>It</coc-quotes>, <coc-quotes>X</coc-quotes>, <coc-quotes>Z</coc-quotes>]
-------------------------------
X;  -- Since X is not in the ring-bound memory of R, 
    -- it is not destroyed.  It was *dependent* on the ring R,
    -- so the base ring of R has been given the new name R#5.
R#5 :: Ideal(x, y)
-------------------------------
ENV.R.Y;  -- this variable was destroyed along with R
ERROR: Unknown record field R
CONTEXT: ENV.R.Y
-------------------------------
RingEnvs();
[<coc-quotes>Q</coc-quotes>, <coc-quotes>Qt</coc-quotes>, <coc-quotes>R#5</coc-quotes>, <coc-quotes>S</coc-quotes>, <coc-quotes>Z</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>ring-bound memory</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Commands and Functions for Memory</title>
        <type>1</type>

        <description>
The following are commands and functions for memory:
<commands_and_functions_for type="memory"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for memory</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="9">
      <chapter_name>CoCoA Packages</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <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 <coderef>Source</coderef> 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 (made using the
<coderef>Define</coderef> command), labeled with a long prefix.  A function from a
package is referred to by the package prefix plus the function name.
The user may type the full prefix, but the usual method is to create a
short alias for the prefix.  Details are provided below, starting with
a short example.
    </description>

        <key>introduction to packages</key>
        <see>Define</see>

        <see>Source</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <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 <code>one.cpkg</code>.


        
<example>
Package $contrib/toypackage

Define IsOne(N)
  If N = 1 Then Return TRUE Else Return FALSE EndIf;
EndDefine;

Define Test(N)
  If $.IsOne(N) Then
    Print <coc-quotes>The number 1.</coc-quotes>
  Else
    Print <coc-quotes>Not the number 1.</coc-quotes>
  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(<coc-quotes>one.cpkg</coc-quotes>);
Test(1);  -- error here because the function <coc-quotes>Test</coc-quotes> is not defined

-------------------------------
ERROR: Unknown operator Test
CONTEXT: Test(1)
-------------------------------
$contrib/toypackage.Test(1); -- this is the name of the function
                             -- we are looking for
The number 1.
-------------------------------
Alias Toy := $contrib/toypackage;  -- use an alias to save typing
Toy.Test(3);                     
Not the number 1.
-------------------------------
Toy.IsOne(3);
FALSE
------------------------------- 
</example>

Once the package is read, the user can choose a <em>substitute prefix</em>
using the <coderef>Alias</coderef> command and in that way avoid conflicts between
functions in various packages and save on typing.

<par/>
Note one other thing: the function <code>IsOne</code> is used in the definition
of <code>Test</code>.  In that case, it is referred to as <code>$.IsOne</code>.  Otherwise,
CoCoA would look for a global function, outside of the package, called
<code>IsOne</code>.  Forgetting this kind of reference is a common source of
errors when constructing a package.
    </description>

        <key>first example of a package</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <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 <code>contrib/subject</code> is typical.

<par/>
In between the <code>Package</code> declaration and its <code>EndPackage</code> one may: (1)
declare Aliases (see below), (2) define functions, and (3) make
comments (please).

<par/>
If a function F in the package appears in the definition of another
function within the package, it must be referred to as <code>$.F</code> (or
<code>$PackageName.F</code>, or using a local alias, see below).

<par/>
Typically, the user will read in the package using the <coderef>Source</coderef>
command.  After that, to save on typing, the user will
choose a global alias with which to refer to the package using the
syntax:

<verbatim>
    Alias ShortName := $PackageName;
</verbatim>

where ShortName is any convenient string, hopefully not conflicting
with other global aliases.  (A list of the global aliases is returned
by the function <coderef>Aliases</coderef>.)

<par/>
A package function, F, is then called using the name <code>ShortName.F</code>.
    </description>

        <key>package essentials</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Package Sourcing and Autoloading</title>
        <type>1</type>

        <description>
As mentioned above, packages are usually saved in files and then read
into a CoCoA session using the command <coderef>Source</coderef>.  

<par/>
(I) Full path name, ordinary file sourcing.
<verbatim>
package name: $mypackage
   file name: this/is/my/stuff.cpkg
</verbatim>
Suppose the name of your package is <code>$mypackage</code> and is kept in the
file with full pathname <code>this/is/my/stuff.cpkg</code>.  Then the package can
be loaded into the session as usual with the command:
<verbatim>
Source(<coc-quotes>this/is/my/stuff.cpkg</coc-quotes>);
</verbatim>
Functions can then be called from the package using the package name,
<code>$mypackage</code>, as a prefix (or using aliases).

<par/>
(II) The standard package path, <code>$</code>-shortcut.
<verbatim>
package name: $mypackage
   file name: packages/mypackages/stuff.cpkg (relative to cocoa directory)
</verbatim>
A package is in the <em>standard package path</em> if its file is kept in the
<em>packages</em> directory inside the cocoa directory.  Suppose your package has
name <code>$mypackage</code> and is kept in the file with pathname (relative to
the cocoa directory) <code>packages/mypackages/stuff.pkg</code>.  Then the package can
be read by passing this pathname to <coderef>Source</coderef>, as above, but there are
the following shortcuts:
<verbatim>
Source(<coc-quotes>$mypackages/stuff</coc-quotes>);
&lt;&lt;<coc-quotes>$mypackages/stuff</coc-quotes>;
&lt;&lt;$mypackages/stuff;   -- quotes are optional in this case
</verbatim>

<par/>
In other words, the prefix <code>$</code> is taking the place of <code>packages/</code> and the
suffix <code>.cpkg</code> is (and must be) left off.  Functions can then be called
as in the previous case.

<par/>
(III) Autoloading.
<verbatim>
package name: $mypackages/stuff
   file name: packages/mypackages/stuff.cpkg (relative to cocoa directory)
</verbatim>
Now suppose that the package is in the standard package path, as
above, in the file with pathname (relative to the cocoa directory)
<code>packages/mypackages/stuff.cpkg</code>.  However, now assume that the name of the
package is <code>$mypackages/stuff</code>, i.e., that it matches the name of its
file (without <code>packages/</code> and <code>.cpkg</code>).  Then, if any function from the
package is called, say <code>$mypackages/stuff.MyFunction</code>, the package
will automatically be loaded.  Of course, one may also source the
package using either method I or II, from above.

<par/>
* Initialize *
NOTE: As explained in the section entitled <ref>Package Initialization</ref>,
below, no matter which method is used to source a package, any
function in the package named <code>Initialize</code> will automatically be
executed when the package is loaded.
    </description>

        <key>package sourcing and autoloading</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Global Aliases</title>
        <type>1</type>

        <description>
A global alias for a package is formed by using the command <coderef>Alias</coderef>
during a CoCoA session.  (Local aliases are formed with the same
command, but are declared inside a package.  They are for use only
within the package.)  The syntax for <coderef>Alias</coderef> is

  Alias binding, ..., binding;

where a <em>binding</em> has the form
<verbatim>
  identifier := $PackageName
</verbatim>
The function <coderef>Aliases</coderef> prints a list of the global aliases.

        
<example>
Aliases();

H      = $help
IO     = $io
GB     = $gb
HP     = $hp
HL     = $hilop
List   = $list
Mat    = $mat
Latex  = $latex
LaTeX  = $latex
Toric  = $toric
Coclib = $coclib
TT     = $abc
-------------------------------
Alias  My := $my_package, 
      Old := $my_package/old_version;
Aliases();

HP      = $hp
BinRepr = $binrepr
SpPoly  = $sppoly
HL      = $hilop
H       = $help
My      = $my_package
Old     = $my_package/old_version
------------------------------- 
</example>
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.  For example, <code>$gb.Step(M)M</code> is a
valid statement inside a function, but not <code>GB.Step(M)</code>.
    </description>

        <key>global aliases</key>
        <see>Alias</see>

        <see>Aliases</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Local Aliases</title>
        <type>1</type>

        <description>
A local alias is an alias declared inside a package, for use only
within the package.  A local alias can have the same identifier as a
global alias.  Only local aliases are recognized within packages.  

<par/>
There are two uses for local aliases.  First, recall that if the
definition of function in a package uses another function, F, also
defined in the package, then F must be referred to using the package
name as a prefix or, for short, <code>$.F</code>.  In this way, <code>$</code>, is an
automatically a local alias for the package itself.  One may choose
another alias, say <code>DD</code>, and write <code>DD.F</code>, instead.  A second use for
a local alias is to refer to a separate package.  In that way, one may
refer to functions from that package inside the current package
without typing out the full package name.

<par/>
Keep in mind that these aliases are used only to save typing.
Examples appear below.
    </description>

        <key>local aliases</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>More Examples of Packages</title>
        <type>1</type>

        <description>
Here is a simple package for printing lists.

        
<example>
Package $contrib/list

Define About()
  Return <coc-quotes>
    Author: Antonio
    Version: 1.0
    Date: 18 July 1997
  </coc-quotes>
EndDefine;

Define PrintList(L)
  Foreach X In L Do
    PrintLn X
  EndForeach
EndDefine;

EndPackage; 
</example>
Here is another package that takes a pair of objects and turns the
pair into a list.  Note the local alias used to reference the previous
package.
        
<example>
Package $contrib/pair

Alias L := $contrib/list; -- Local alias for another package.
                          -- This alias does not affect global
                          -- aliases.
Define Make(A,B) 
  Return [A,B];
EndDefine;

Define First(P) 
  Return P[1];
EndDefine;

Define Second(P)
  Return P[2];
EndDefine;

Define PrintPairOfLists(P)
  PrintLn <coc-quotes>First list:</coc-quotes>;
  L.PrintList($.First(P));  -- The local alias, L, is used here,
  PrintLn <coc-quotes>Second list:</coc-quotes>;
  L.PrintList($.Second(P))  -- and here.  <code>$</code> refers to a function
EndDefine;                        -- defined in the current package. 

EndPackage;  
</example>
USING THE PACKAGES.  After reading in the packages using <coderef>Source</coderef> one may proceed as follows to use them:

        
<example>
Alias P := $contrib/pair;
X := P.Make([x^2,x],[x,y,z]);
P.PrintPairOfLists(X);
First list:
x^2
x
Second list:
x
y
z
------------------------------- 
</example>
Note: suppose a package with identifier <code>$contrib/newlist</code> prints lists
in another format.  To switch to this format in <code>$contrib/pair</code>, one
need only change the alias for L from <code>$contrib/list</code> to
<code>$contrib/newlist</code>.
    </description>

        <key>more examples of packages</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>Package Initialization</title>
        <type>1</type>

        <description>
Packages are often stored in files and read into a CoCoA session
using the <coderef>Source</coderef> command.  When a package is loaded, any function
whose name is <code>Initialize</code> will automatically be executed.  For
example, this feature may be used to print a message or initialized
global variables when the package is read into a session.

<par/>
(Note: following this rule, if the first time you access package
PKG is to make an explicit call to the function PKG.Initialize() then
the function will be called twice!)

        
<example>
Package $example
  Define Initialize() 
    Print <coc-quotes>CALLED INITIALIZE</coc-quotes>;
    MEMORY.MyVar := 17;
  EndDefine;
EndPackage;
CALLED INITIALIZE
-------------------------------
MEMORY.MyVar;
17
------------------------------- 
</example>
    </description>

        <key>package initialization</key>
        <see>User Initialization</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="9">
        <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 <code>cocoa at dima.unige.it</code>.

<par/>
Include comments in the package that: 

<par/>
  * explain the use of the package

<par/>
  * list functions that are meant to be seen by the user

<par/>
  * give the syntax for these functions.  (What are the arguments?
    What values are returned?)

<par/>
  * describe what each function does

<par/>
  * provide examples of the use of each function.
    </description>

        <key>sharing your package</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="10">
        <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>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for packages</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="11">
        <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/>
The supported packages are:
<verbatim>
    algmorph.cpkg    -- K-algebra homomorphisms
    CantStop         -- the first game in CoCoA  ;-)
    conductor.cpkg   -- conductor sequence of points
    galois.cpkg      -- computing in a cyclic extension
    intprog.cpkg     -- integer programming
    invariants.cpkg  -- generators of an algebra of invariants
    matrixnormalform.cpkg  -- Smith normal form of a matrix
    primary.cpkg     -- primary ideals
    specvar.cpkg     -- special varieties
    stat.cpkg        -- statistics, design of experiment
    thmproving.cpkg  -- geometrical theorem proving
    typevectors.cpkg -- typevectors for ideals of points
</verbatim>
All of these packages are included in /packages/contrib of the distribution
of CoCoA.  The packages are likely to be updated more often than
CoCoA, itself, and new packages may appear; so it may be worth
checking at the CoCoA distribution sites, e.g.,
<code>http://cocoa.dima.unige.it/</code>.

<par/>
HOW TO USE A SUPPORTED PACKAGE
(1) save the package in /packages/contrib/, if necessary;
(2) to get the syntax, description, and examples of the main functions
   and a suggested alias for the package, type
       <code>$contrib/<coc-quotes>package_name</coc-quotes>.Man();</code>
(3) to know the author and version number, type
       <code>$contrib/<coc-quotes>package_name</coc-quotes>.About();</code>

<par/>
or just XX.Man(); XX.About()
where XX is a defined alias (type <code>Aliases();</code> to get the list)

<par/>
NOTE: The packages will load automatically when one of their functions
is called (see <ref>Package Sourcing and Autoloading</ref>) for more
information. 

<par/>
See below for more details about specific supported packages.
    </description>

        <key>supported packages</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="12">
        <title>K-Algebra Homomorphisms</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : algmorph.cpkg
DESCRIPTION : CoCoA package for computing  K-algebra homomorphisms 
              and subalgebras
AUTHOR      : A. Bigatti
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/algmorph.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/algmorph.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>algmorph</key>
        <key>k-algebra homomorphisms</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="13">
        <title>Galois Package</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : galois.cpkg
DESCRIPTION : CoCoA package for computing in a cyclic algebraic
              extension 
AUTHOR      : A. Bigatti, D.La Macchia, F.Rossi
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/galois.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/galois.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>algebraic extension</key>
        <key>cyclic extension</key>
        <key>galois group</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="14">
        <title>Integer Programming</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : intprog.cpkg
DESCRIPTION : CoCoA package for applying toric ideals to integer
              programming 
AUTHOR      : A. Bigatti 
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/intprog.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/intprog.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>integer programming</key>
        <key>intprog</key>
        <key>test set</key>
        <key>testset</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="15">
        <title>Algebra of Invariants</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<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
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/invariants.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/invariants.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>algebra of invariants</key>
        <key>invariance</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="16">
        <title>Primary Ideals</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : primary.cpkg
DESCRIPTION : CoCoA package for applying toric ideals to integer
              programming 
AUTHORS     : A. Bigatti, L. Robbiano

LOADING INSTRUCTIONS
-- Enter 
       $contrib/primary.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/primary.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>initial ideal</key>
        <key>primary</key>
        <key>primary ideals</key>
        <key>tangent cone</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="17">
        <title>Special Varieties</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : specvar.cpkg
DESCRIPTION : CoCoA package for computing the Hilbert-Poincare
              series of special varieties (Segre, Veronese, Rees).
AUTHORS     : A. Bigatti, L. Robbiano

LOADING INSTRUCTIONS
-- Enter 
       $contrib/specvar.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/specvar.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>rees</key>
        <key>segre</key>
        <key>special varieties</key>
        <key>veronese</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="18">
        <title>Statistics</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : stat.cpkg
DESCRIPTION : package for design of experiments in statistics
AUTHOR      : M. Caboara 

LOADING INSTRUCTIONS
-- Enter 
       $contrib/stat.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/stat.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>design of experiments</key>
        <key>statistics</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="19">
        <title>Geometrical Theorem-Proving</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : thmproving.cpkg
DESCRIPTION : CoCoA package for geometrical theorem-proving in euclidean space
AUTHOR      : L. Bazzotti, G. Dalzotto

LOADING INSTRUCTIONS
-- Enter
       $contrib/thmproving.Man();
   to get a complete description of the package including a suggested alias.
-- Enter
       $contrib/thmproving.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>geometrical theorem-proving</key>
        <key>hypothesis</key>
        <key>thesis</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="20">
        <title>Typevectors</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : typevectors.cpkg
DESCRIPTION : CoCoA package for computing typevectors associated to
              Hilbert functions of ideals of points
AUTHOR      : E.Carlini, M.Stewart
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/typevectors.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/typevectors.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>typevectors</key>
        <key>hilbert functions of points</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="21">
        <title>Conductor</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : conductor.cpkg
DESCRIPTION : CoCoA package for computing conductor sequence of points
AUTHOR      : L.Bazzotti
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/conductor.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/conductor.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>conductor</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="22">
        <title>Matrix Normal Form</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : matrixnormalform.cpkg
DESCRIPTION : CoCoA package for computing normal forms of a matrix
AUTHOR      : S.DeFrancisci
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/matrixnormalform.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/matrixnormalform.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>matrixnormalform</key>
        <key>smith</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="23">
        <title>CantStop</title>
        <type>2</type>

        <description>
Supported CoCoA Package
<verbatim>
TITLE       : CantStop.cpkg
DESCRIPTION : CoCoA package for playing Can't Stop and studying strategies
AUTHOR      : A.Bigatti
 
LOADING INSTRUCTIONS
-- Enter 
       $contrib/CantStop.Man();
   to get a complete description of the package including a suggested alias.
-- Enter 
       $contrib/CantStop.About();
   to find the version number.  You may want to check the CoCoA
   homepage for the latest version.
</verbatim>
    </description>

        <key>cantstop</key>
        <key>game</key>
        <key>play</key>
      </section>

    </chapter>


  </part>


  <part number="4">
    <name>Doing Mathematics with CoCoA</name>
<!-- ===  CHAPTER  =============================================== -->
    <chapter number="1">
      <chapter_name>Booleans</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Booleans</title>
        <type>1</type>

        <description>


The two boolean constants are <code>TRUE</code> and <code>FALSE</code>.  They are mainly used
with the commands <coderef>If</coderef> and <coderef>While</coderef>, etc., inside CoCoA programs.  The
relational operators 
<verbatim>
    =  &lt;&gt;  &lt;  &lt;=  &gt;  &gt;=
</verbatim>
return boolean constants (see <ref>Relational Operators</ref>).  The boolean
operators are
<verbatim>
    Not  And  Or  IsIn
</verbatim>
and return boolean constants and are described below.

    </description>

        <key>introduction to booleans</key>
        <key>true</key>
        <key>false</key>
        <see>Relational Operators</see>

        <see>Boolean Operators</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Booleans</title>
        <type>1</type>

        <description>
The following are commands and functions for booleans:
<commands_and_functions_for type="boolean"></commands_and_functions_for>

<par/>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for booleans</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="2">
      <chapter_name>Numbers</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Numbers</title>
        <type>1</type>

        <description>
There are three types of numbers recognized by CoCoA: integers (type
<code>INT</code>), rationals (type <code>RAT</code>), and modular integers (type <code>ZMOD</code>).  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 (<code>+</code>), subtraction (<code>-</code>),
multiplication (<code>*</code>), division (<code>/</code>), exponentiation (<code>^</code>), and negation
(<code>-</code>)---behave as one would expect.  Be careful, two adjacent minus
signs, <code>--</code>, start a comment in CoCoA.

        
<example>
N := 3;
-N;
-3
-------------------------------
--N; 
</example>
The last line in the above example does not return 3; it is
interpreted as a comment.
    </description>

        <key>introduction to numbers</key>
        <key>integers</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Rationals</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/5;
3/5
-------------------------------
3.8;
19/5
-------------------------------
N := 4/8;
N;
1/2
------------------------------- 
</example>
    </description>

        <key>rationals</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Numerators and Denominators for Rational Numbers</title>
        <type>3</type>

        <description>
If F is a variable holding a fraction, then <code>F.Num</code> and <code>F.Den</code> are the
numerator and denominator, respectively.  The functions <code>Num</code> and
<code>Den</code>, respectively, return the same.

        
<example>
F := 3/5;
F.Num;
3
-------------------------------
F.Den;
5
-------------------------------
Den(F);
5
-------------------------------
1.75;
7/4
-------------------------------
It.Num;
7
------------------------------- 
</example>
    </description>

        <key>numerators and denominators for rational numbers</key>
        <see>Den</see>

        <see>Num</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Modular Integers</title>
        <type>2</type>

        <description>
Let A and B be integers.  The expression <code>A%B</code> has type <code>ZMOD</code> and
represents the class of A modulo B.  The integer B should be greater
than 0 and less then <formula>32767 = 2^<ocb/>15<ccb/> - 1</formula>.  

<par/>
When a modular integer is evaluated by CoCoA, it is reduced to a
canonical form <code>A%B</code> with <formula>-B/2 &lt; A <less_eq/> B/2</formula>.

<par/>
Two modular integers of the form <code>A%C</code> and <code>B%C</code> are said to be
<em>compatible</em>, and the usual arithmetical operations are applicable.

        
<example>
3%7;
3 % 7
-------------------------------
4%7;
-3 % 7
-------------------------------
2%5 + 4%5;
1 % 5
-------------------------------
Type(3%11);
ZMOD
-------------------------------
3%11 = 14%11;
TRUE
-------------------------------
3%11 = 3;
FALSE
------------------------------- 
</example>
Use the functions <coderef>Div</coderef> and <coderef>Mod</coderef> for quotients and remainders.
    </description>

        <key>modular integers</key>
        <see>Div</see>
        <see>Mod</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Commands and Functions for Numbers</title>
        <type>1</type>

        <description>
The following are commands and functions for numbers:

<par/>
INTEGERS
<commands_and_functions_for type="integer"></commands_and_functions_for>
RATIONALS
<commands_and_functions_for type="rat"></commands_and_functions_for>
MODULAR INTEGERS
<commands_and_functions_for type="zmod"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for numbers</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="3">
      <chapter_name>Strings</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Strings</title>
        <type>1</type>

        <description>
A string constant consists of a sequence of characters between double 
quotes (<code><coc-quotes> </coc-quotes></code>).
For backward compatibility also single quotes (<code>&apos; &apos;</code>) are allowed, but
this syntax is now deprecated.

        
<example>
Print <coc-quotes>This is a string.</coc-quotes>;
This is a string.
-------------------------------
&apos;So is this.&apos;  -- deprecated
So is this.
------------------------------- 
</example>
One may not, however, start a string with a single quote and end with
a double quote, or vice versa.
    </description>

        <key>introduction to strings</key>
        <see>Concatenation</see>

        <see>Concat</see>
        <see>ConcatLists</see>

        <see>Substrings</see>

        <see>Quotes Within Strings</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Concatenation</title>
        <type>2</type>

        <description>
Strings may be concatenated using <code>+</code> or using the list function
<coderef>Concat</coderef>.

        
<example>
L := <coc-quotes>hello </coc-quotes>;
M := <coc-quotes>world</coc-quotes>;
L + M;
hello world
-------------------------------
Concat(L,M);
hello world
------------------------------- 
</example>
    </description>

        <key>concatenation</key>
        <see>Concat</see>
        <see>ConcatLists</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Substrings</title>
        <type>2</type>

        <description>
If L is a string and N is an integer, then L[N] is the N-th character
of L.

        
<example>
L := <coc-quotes>hello world</coc-quotes>;
L[2];
e
------------------------------- 
</example>

The operator <coderef>IsIn</coderef> can be used to test if one string is a substring
of another.

        
<example>
L := <coc-quotes>hello world</coc-quotes>;
<coc-quotes>hello</coc-quotes> IsIn L;     -- one may also write IsIn(<coc-quotes>hello</coc-quotes>,L)
TRUE
------------------------------- 
</example>
    </description>

        <key>substrings</key>
        <see>IsIn</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Quotes Within Strings</title>
        <type>2</type>

        <description>
Strings are delimited using single quotes or double quotes (but not
mixed).  One may directly use quotes inside a string if they are not
of the same type as the delimiters.  To get quotes inside a string
which *are* of the same type as the delimiters, the quotes must be
doubled.

        
<example>
Print <coc-quotes>This string <coc-quotes><coc-quotes>contains</coc-quotes></coc-quotes> quotes of &apos;various&apos; styles.</coc-quotes>;
This string <coc-quotes>contains</coc-quotes> quotes of &apos;various&apos; styles.
-------------------------------
Print &apos;This string also <coc-quotes>contains</coc-quotes> quotes of &apos;&apos;various&apos;&apos; styles.&apos;; --deprecated
This string also <coc-quotes>contains</coc-quotes> quotes of &apos;various&apos; styles.
------------------------------- 
</example>
Imagine the difficulties in writing this section of the online manual
within a CoCoA package. <formula>;&gt;</formula>
    </description>

        <key>quotes within strings</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Commands and Functions for Strings</title>
        <type>1</type>

        <description>
The following are commands and functions for strings:
<commands_and_functions_for type="string"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for strings</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="4">
      <chapter_name>Lists</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Lists</title>
        <type>1</type>

        <description>
A CoCoA list is a sequence of CoCoA objects between brackets.  In
particular, a list may contain other lists.  The empty list is <code>[]</code>.  If
L is a list and N is an integer, then L[N] is the N-th component of
L.  If L contains sublists, then        <code>L[N_1,N_2,...,N_s]</code>
is shorthand for <code>L[N_1][N_2]...[N_s]</code> (see the example below).  Lists
are often used to build structured objects of type <code>MAT</code>, <code>VECTOR</code>, <code>IDEAL</code>,
and <code>MODULE</code>.

        
<example>
Use R ::= Q[t,x,y,z];
L := [34x+y^2,<coc-quotes>a string</coc-quotes>,[],[TRUE,FALSE]]; -- a list
L[1];  -- the list&apos;s 1st component
y^2 + 34x
-------------------------------
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,<coc-quotes>a</coc-quotes>]+[2,<coc-quotes>b</coc-quotes>];  -- Note: one may add lists if their components are
[3, <coc-quotes>ab</coc-quotes>]         -- compatible (see <coc-quotes>Algebraic Operators</coc-quotes>).  
-------------------------------
L := [x^2-y,ty^2-z^3];
I := Ideal(L);
I;
Ideal(x^2 - y, ty^2 - z^3)
------------------------------- 
</example>
    </description>

        <key>introduction to lists</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Lists</title>
        <type>1</type>

        <description>
CoCoA provides a variety of commands for manipulating lists.  Note in
particular the command <coderef>In</coderef> which is useful for building lists.

<par/>
The following are commands and functions for lists:
<commands_and_functions_for type="list"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for lists</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="5">
      <chapter_name>Records</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Records</title>
        <type>1</type>

        <description>
A record is a data type in CoCoA representing a list of bindings of
the form <em>name --<formula>&gt;</formula> object</em>.  

        
<example>
Use R ::= Q[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.F;
x^2 + y
-------------------------------
P.Misc;
[1, 3, 4]
-------------------------------
P.Misc[2];
3
-------------------------------
P.Date := <coc-quotes>1/1/98</coc-quotes>;
P;
Record[Date = <coc-quotes>1/1/98</coc-quotes>, F = x^2 + y, I = Ideal(x, y^2 - z), Misc = [1, 3, 4]]
-------------------------------
P[<coc-quotes>I</coc-quotes>];  -- equivalent to P.I
Ideal(x, y^2 - z)
-------------------------------
P[<coc-quotes>Misc</coc-quotes>,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; <coc-quotes>C</coc-quotes> Then Q.Var(F) := P.Var(F) EndIf; -- <coc-quotes>Q.F</coc-quotes> would not work here
EndForeach;
P := Q;
Delete Q;  -- get rid of the variable Q

P;
 Record[A = 2, B = 3, D = 7]
------------------------------- 
</example>
    </description>

        <key>introduction to records</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Records</title>
        <type>1</type>

        <description>
The following are commands and functions for records:
<commands_and_functions_for type="record"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for records</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="6">
      <chapter_name>Vectors</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Vectors</title>
        <type>1</type>

        <description>
An object of type VECTOR in CoCoA represents a vector of
polynomials.  If V is a vector and F is a polynomial, then the
following are also vectors:
<verbatim>
   +V, -V, F*V, V*F.
</verbatim>
If V and W are vectors with the same number of components, then one
may add and subtract V and W componentwise:
<verbatim>
    V+W, V-W.
</verbatim>
        
<example>
Use R ::= Q[x,y];
V := Vector(x+1,y,xy^2);
V;
Vector(x + 1, y, xy^2)
-------------------------------
-V;
Vector(-x - 1, -y, -xy^2)
-------------------------------
x*V;
Vector(x^2 + x, xy, x^2y^2)
-------------------------------
W := Vector(x,y,x^2y^2-y);
x*V-W;
Vector(x^2, xy - y, y)
------------------------------- 
</example>
    </description>

        <key>introduction to vectors</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Vectors</title>
        <type>1</type>

        <description>
The following are commands and functions for vectors:
<commands_and_functions_for type="vector"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for vectors</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="7">
      <chapter_name>Matrices</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Matrices</title>
        <type>1</type>

        <description>
An m x n matrix is represented in CoCoA by the list of its rows
<verbatim>
Mat(R_1,...,R_m)
</verbatim>
where each <code>R_i</code> is of type <code>LIST</code> and has length n.  A matrix has type
<code>MAT</code>.  The (A,B)-th entry of a matrix M is given by <code>M[A][B]</code> or <code>M[A,B]</code>.

        
<example>
Use R ::= Q[x,y,z];
M := Mat([[x,y,xy^2],[y,z^2,2+x]]);
M;
Mat([
  [x, y, xy^2],
  [y, z^2, x + 2]
])
-------------------------------
M[1][3];
xy^2
-------------------------------
M[1,3];
xy^2
------------------------------- 
</example>

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 or rational function, with the obvious restrictions on the
dimensions of the matrices involved.

        
<example>
Use R ::= Q[x,y];
N := Mat([[1,2],[3,4]]);
N^2;
Mat([
  [7, 10],
  [15, 22]
])
-------------------------------
x/y * N;
Mat([
  [x/y, 2x/y],
  [3x/y, 4x/y]
])
-------------------------------
N + Mat([[x,x],[y,y]]);
Mat([
  [x + 1, x + 2],
  [y + 3, y + 4]
])
------------------------------- 
</example>
    </description>

        <key>introduction to matrices</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Matrices</title>
        <type>1</type>

        <description>
The following are commands and functions for matrices:
<commands_and_functions_for type="matrix"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for matrices</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="8">
      <chapter_name>Rings</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Rings</title>
        <type>1</type>

        <description>
Polynomial rings play a central role in CoCoA. Indeed, every object
in CoCoA is defined over a base ring which is a polynomial ring. The
user can define many rings, but at any time a <em>current ring</em> is
active within the system.  Most commands use the current ring as the
base ring.

<par/>
Once a ring has been defined, the system can handle the following
mathematical objects defined over that ring:
<verbatim>
 * numbers (integers, rationals, modular integers);
 * polynomials;
 * vectors of polynomials;
 * rational functions;
 * ideals;
 * modules (submodules of a free module);
 * lists of objects;
 * matrices of objects.
</verbatim>
Variables containing ring-dependent objects such as polynomials,
ideals, and modules are <em>labeled</em> by their ring.  Variables
containing objects such as integers which are not dependent on a
particular ring are not labeled.

<par/>
IMPORTANT NOTE: Starting with CoCoA 3.5, variables are no longer local
to specific rings, i.e., all variables are accessible from all rings.

<par/>
The next sections explains how to create a ring.
    </description>

        <key>introduction to rings</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>New Rings</title>
        <type>1</type>

        <description>
CoCoA starts with the default ring R = Q[t,x,y,z].  The command for
building a new ring is:
<verbatim>
          I ::= C[X:INDETS]
</verbatim>
or
<verbatim>
          I ::= C[X:INDETS], M_1, ... , M_n
</verbatim>

where I is the identifier of a CoCoAL variable, C: RING is an
expression defining a coefficient ring (Z, Q or Z/(N)), X is an
expression that defines the indeterminates, and the <code>M_i</code> are
<em>modifiers</em>.  Each of these components is discussed in separate
sections, below.

<par/>
The modifiers are used to modify the default settings of the base
ring. The modifiers are of three classes: term-orderings, weights,
term orderings for modules.  These classes are discussed in separate
sections below.  It is possible to have no modifiers.  The default
values are: DegRevLex for the term-ordering, 1 for the weight of each
indeterminate, and ToPos for the module term-ordering.

<par/>
After the ring is defined using the above syntax, it can be made to be
the current ring with the command <coderef>Use</coderef> or it can be accessed
temporarily from within the current ring with the command
<coderef>Using</coderef>.  See these two commands for more information.  There are also
several examples of ring-building in the tutorial.

        
<example>
Use R ::= Q[x,y,z];  -- define and use the ring R
S ::= Z/(103)[x,y], Lex; -- define the ring S with Lex term-ordering
CurrentRing();  -- the current ring is still R
Q[x,y,z]
-------------------------------
Use S; -- now the ring S is the current ring
Z/(103)[x,y]
-------------------------------
Using R Do X:=z^2-3 End;  -- define a variable in R (not the current
                          -- ring)
Y := R::x^2+y^2+z^2;  -- another way of defining a variable in R while
                      -- S is the current ring
T ::= Q[x[1..4],y[1..5,1..5]], Elim(y[1..5,1]), ToPos; -- a more
                                            -- complicated ring 
</example>
    </description>

        <key>new rings</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Coefficient Rings</title>
        <type>2</type>

        <description>
As mentioned above, the coefficient ring for a CoCoA polynomial ring
may be:
<verbatim>
 1. Z: (arbitrarily large) integer numbers;
 2. Q: (arbitrarily large) rational numbers;
 3. Z/(N): (see <coderef>CocoaLimits</coderef>) integers modulo N, 
</verbatim>
The first two types of coefficients are based on the GNU-gmp library.
When integers modulo N are used, the system checks whether N is a
prime number and, if it is not, a warning message is given.  However
non-prime integers are accepted.  Hence it is possible to do some work
with polynomials whose coefficients are not in a field, but it is up
to the user to ensure that no illegal operation will be attempted.  To
find the upper limit for the characteristic in the third case, see the
field <code>MaxChar</code> returned by the function <coderef>CocoaLimits</coderef>; <formula>N <less_eq/> 32767</formula> is
typical.  (Note: 32003 is prime)

<par/>
IMPORTANT NOTE: Presently the implementation of the Buchberger
algorithm for computing Groebner bases operates correctly only if
polynomials have coefficients in a field. So the high level operations
on ideals and modules (and the polynomial GCD) involving Groebner
bases computations work only if polynomials have coefficients in a
field.  Otherwise it is very likely that the user will run into
trouble.

<par/>
<code>CoeffRing</code>: When creating a new ring, the word <code>CoeffRing</code> may be
used to refer to the current coefficient ring.  Examples below
illustrate its use.

        
<example>
Use R ::= Q[x,y];  -- coefficient ring is Q
S ::= Z/(5)[t]; -- coefficient ring is the field with 5 elements
T ::= Z[u,v]; -- A warning is issued if the coefficient ring
              -- is not a field.
-- WARNING: Coeffs are not in a field
-- GBasis-related computations could fail to terminate or be wrong
-------------------------------
Use R ::= Z/(2)[x,y,z]; CurrentRing();  -- these examples show the usage
                                        -- of <coc-quotes>CoeffRing</coc-quotes>
Z/(2)[x,y,z]                           
-------------------------------
Use S ::= CoeffRing[a,b]; CurrentRing();
Z/(2)[a,b]
------------------------------- 
</example>
    </description>

        <key>coefficient rings</key>
        <key>coeffring</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Indeterminates</title>
        <type>2</type>

        <description>
An <em>indeterminate</em> is represented by a name consisting of either a
single lower case letter or a lower case letter followed by one or
more indices. For example, <code>x</code>, <code>x[1]</code>, <code>x[1,2,3]</code> are legal (and different)
indeterminates, as is <code>x[2I,2I+1]</code> if I is an integer variable.

<par/>
When creating a ring the indeterminates are listed, optionally
separated by commas: lack of separating commas is now deprecated and
might be unacceptable in future versions.  
Indeterminates with indices are formed with the syntax: <code>x[R_1,...,R_n]</code>,
where <code>x</code> stands for any lower case letter and each <code>R_i</code>
has the form <code>A..B</code> for integers <code>A &lt;= B</code>.

        
<example>
Use R ::= Q[xyz];  -- deprecated
Use R ::= Q[x,y,z];

Use R ::= Q[x[1..2,4..8],y[1..3],u,v];
Indets();
[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>

        <key>indeterminates</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Weights Modifier</title>
        <type>2</type>

        <description>
In forming a ring, one of the possible modifiers that may be added
has one of the forms: 
<par/>
(i) <code>Weights(W_1,...,W_n)</code> where <code>W_i</code> is a
positive integer specifying the weight of the i-th indeterminate (the
number of weights listed must be equal to the number of
indeterminates)  
<par/>
(ii) <code>Weights(M)</code> where M is a matrix with as many
columns as there are indeterminates.  In the latter case, the i-th
indeterminate has the multi-degree given by the i-th column of M.  
<par/>
NB: Because of a choice in the early design (oriented to single
gradings), the first row of the matrix M *must* have all positive
entries.  CoCoA-5, with a cleaner mathematical foundation, will not
have this limitation.

<par/>
If the weights are not specified the default value is 1 for all indeterminates.

        
<example>
Use S ::= Q[a,b,c], Weights(1,2,3);
Deg(b);
2
-------------------------------
L := [1,2,3];
Use S ::= Q[a,b,c], Weights(L);
Deg(b);
2
-------------------------------
W := Mat([[1,2,3],[4,5,6]]);
Use S ::= Q[a,b,c], Weights(W);
Deg(b);
2
-------------------------------
MDeg(b);  -- the multi-degree of b
[2, 5]
-------------------------------
Deg(b^3+a^2c);
6
-------------------------------
MDeg(b^3+a^2c);
[6, 15]
-------------------------------
WeightsMatrix();
Mat([
  [1, 2, 3],
  [4, 5, 6]
])
-------------------------------
WeightsList(); -- returns the first row of the Weights Matrix
[1, 2, 3]
------------------------------- 
</example>
    </description>

        <key>weights modifier</key>

        <see>Deg</see>

        <see>MDeg</see>
        <see>PositiveGrading4</see>

        <see>WeightsList</see>

        <see>WeightsMatrix</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <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.  Some commands temporarily change the
term-ordering in order to make a computation.  The various
possibilities are discussed more fully, below.

<par/>
The command <coderef>Ord</coderef> can be used both as a modifier to set the ordering
of the ring and as a way to view the matrix defining the current
term-ordering.

        
<example>
Use R ::= Q[x,y,z], Lex;  -- lexicographic term-ordering (predefined)
Use S ::= Q[u,v], Ord([[1,1],[2,-3]]);  -- custom term-ordering
Ord(R);  -- the matrix defining the term-ordering for R
Mat([
  [1, 0, 0],
  [0, 1, 0],
  [0, 0, 1]
])
-------------------------------
Ord(S);  -- the matrix defining the term-ordering for S
Mat([
  [1, 1],
  [2, -3]
])
------------------------------- 
</example>
    </description>

        <key>orderings</key>
        <see>Ord</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Predefined Term-Orderings</title>
        <type>3</type>

        <description>
The predefined term-orderings are:

<par/>
 * degree reverse lexicographic: <code>DegRevLex</code>  (the default ordering)

<par/>
 * degree lexicographic: <code>DegLex</code> 

<par/>
 * pure lexicographic: <code>Lex</code> 

<par/>
 * pure xel: <code>Xel</code> 

<par/>
 * elimination term-ordering: <code>Elim(X:INDETS)</code> 

<par/>
The first two term-orderings use the weights of the indeterminates for
computing the degree of a monomial. If the indeterminates are given in
the order <code>x_1, ..., x_n</code>, then <code>x_1 &gt; ... &gt; x_n</code> with respect to Lex, but
<code>x_1 &lt; ... &lt; x_n</code> with respect to Xel.

<par/>
In the last ordering, X specifies the variables that are to be
eliminated.  It may be a single indeterminate or a range of
indeterminates.  However, X may not be an arbitrary list of
indeterminates; for that, see the command <coderef>Elim</coderef> (as opposed to the
modifier <coderef>Elim</coderef> being discussed here).  A range of indeterminates can
be specified using the syntax <code>&lt; first-indet &gt;..&lt; last-indet &gt;</code>.
Another shortcut: if there are indexed variables of the form, say,  <code>x[i,j]</code>,
then <code>Elim(x)</code> specifies a term-ordering for eliminating all of the
<code>x[i,j]</code>.

        
<example>
Use R ::= Q[x,y,z], Lex;
x+y+z;
x + y + z
-------------------------------
Use R ::= Q[x,y,z], Xel;
x+y+z;
z + y + x
-------------------------------
Use R ::= Q[t,x,y,z], Elim(t);
I := Ideal(t-x,t-y^2,t^2-xz^3);
GBasis(I);
[t - x, -y^2 + x, xz^3 - x^2]
-------------------------------
Use R ::= Q[x[1..5],y,z], Elim(x); -- term-ordering for eliminating all
                                   -- of the x[i,j]&apos;s
Ord();
Mat([
  [1, 1, 1, 1, 1, 0, 0],
  [0, 0, 0, 0, 0, 1, 1],
  [0, 0, 0, 0, 0, 0, -1],
  [0, 0, 0, 0, -1, 0, 0],
  [0, 0, 0, -1, 0, 0, 0],
  [0, 0, -1, 0, 0, 0, 0],
  [0, -1, 0, 0, 0, 0, 0]
])
------------------------------- 
</example>
    </description>

        <key>degrevlex</key>
        <key>deglex</key>
        <key>lex</key>
        <key>predefined term-orderings</key>
        <key>xel</key>
        <see>Elim</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>Temporary Term-Orderings</title>
        <type>3</type>

        <description>
For computations which temporarily require a different term-ordering
(for example, to eliminate variables or to homogenize ideals), the
system automatically changes the term-ordering to a more suitable one,
performs the computation, and then restores the initial term-ordering
and gives its output with respect to this one. In this way the user
never has to deal with temporary changes.

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(t-x,y-z,t-z);
Elim(y,I);
Ideal(t - z, -x + z)
------------------------------- 
</example>
    </description>

        <key>temporary term-orderings</key>
        <see>Elim</see>

        <see>Homogenized</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="9">
        <title>Custom Term-Orderings</title>
        <type>3</type>

        <description>
For special purposes, the user can enter a custom ordering.  We recall
that each ordering <code>&gt;</code> on the set of the terms of a polynomial ring
in n variables corresponds to a (not uniquely determined)
array <code>(u_1,...,u_s)</code> of vectors of the real vector
space <formula>R^n</formula>.  More precisely if <formula>a = (a_1,
... ,a_n)</formula> and <formula>b = (b_1, ... ,b_n)</formula> 
are the n-tuples of the exponents of two terms t and t&apos;, then

<par/>
<formula>t &gt; t&apos; &lt;=&gt; (a . u_1, ..., a . u_s) &gt;_{lex} (b . u_1, ..., b . u_s)</formula>

<par/>
where <formula>&gt;_{lex}</formula> is the ordering on <formula>R^s</formula> given by: <formula>(c_1,...,c_s)&gt;_{lex}</formula>
<formula>(d_1,...,d_s)</formula> if and only if the first (leftmost) non-zero coordinate of
<formula>(c_1-d_1,...,c_s-d_s)</formula> is positive.

<par/>
CoCoA accepts orderings defined by means of n x n matrices of integers.
This is not a real restriction if one is interested, for instance, in
finding all possible Groebner bases of a given ideal.

<par/>
Moreover <formula>&gt;</formula> is a term-ordering if and only if the matrix whose rows are
the vectors <formula>(u_1,...,u_s)</formula> has maximal rank and is such that the first
non-zero element in each column is positive.

<par/>
To compute a Groebner basis a term-ordering is needed.

        
<example>
-- The following CoCoA command defines S to be a polynomial ring and
-- orders the terms of S using the term-ordering corresponding to the
-- vectors (1,1,0,0),(0,-1,0,0),(0,0,1,1),(0,0,0,-1):
Use S ::= Q[x,y,z,t], Ord( Mat([[1, 1, 0, 0],
                                [0,-1, 0, 0],
                                [0, 0, 1, 1],
                                [0, 0, 0,-1]]) ); 
</example>
    </description>

        <key>custom term-orderings</key>
        <see>Ord</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="10">
        <title>Module Orderings</title>
        <type>2</type>

        <description>
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 <code>T, T_1, T_2</code> 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 <code>ToPos</code> (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 <code>PosTo</code> 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 ::= Q[x,y],ToPos;
LT(Vector(x,y^2));
Vector(0, y^2)
-------------------------------
Use R ::= Q[x,y],PosTo;
LT(Vector(x,y^2));
Vector(x, 0)
------------------------------- 
</example>
    </description>

        <key>module orderings</key>
        <key>posto</key>
        <key>topos</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="11">
        <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.  First of all, unlike CoCoA 3.4, starting with CoCoA
3.5, variables are usually assigned to a <em>working memory</em> accessible
from all rings. (The only exceptions are variables prefixed by
<code>MEMORY</code>.  See the chapter entitled <ref>Memory Management</ref> for further
information.)  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.  If a variable contains
a ring-dependent object such as a polynomial, an ideal, or a module,
the variable becomes labeled by the ring in which it was defined.
Built-in CoCoA functions should be smart enough to take into account
the rings on which their arguments depend (if you find an exception,
please send a message to <code>cocoa at dima.unige.it</code>).

<par/>
To access rings outside of the current ring, one may of course use the
command <coderef>Use</coderef> to change the current ring.  Some other ways of
interacting with outside rings:

<par/>
(1) The <code>::</code> construction.  This construction can be used to define
variables or perform operations in rings outside of the current ring.

        
<example>
Use R ::= Q[x,y,z];
I := Ideal(x,y,z)^3;
I;
Ideal(x^3, x^2y, x^2z, xy^2, xyz, xz^2, y^3, y^2z, yz^2, z^3)
-------------------------------
Use S ::= Z/(5)[a,b];
I;  -- I is labeled by its ring, R
R :: Ideal(x^3, x^2y, x^2z, xy^2, xyz, xz^2, y^3, y^2z, yz^2, z^3)
-------------------------------
RingEnv(I);  -- the name of the ring on which I is dependent
R
-------------------------------
R:: Poincare(R/I);  -- To be sure, one may prefix any operation 
                    -- on I by <coc-quotes>R::</coc-quotes>  although this should not 
                    -- be necessary
(1 + 3a + 6a^2)
-------------------------------
R:: (x+y)^2;  -- S is still the active ring, but we can perform
              -- operations in R
R :: x^2 + 2xy + y^2
-------------------------------
J := R :: Ideal(x^2-y);  -- while S is active, one may define an
                         -- object dependent on R.  This variable
                         -- becomes part of the working memory.
J;
R :: Ideal(x^2 - y)
-------------------------------
Use R;
J;  -- the label is not used if R is active
Ideal(x^2 - y)
------------------------------- 
</example>

(2) <coderef>Using</coderef>.  From within the current ring one may temporarily perform
commands in an another ring using the command <coderef>Using</coderef>.  A brief
example appears below.  For more information, see the online help
entry for <coderef>Using</coderef>.

        
<example>
Use R ::= Q[x,y];
S ::= Z/(5)[a,b]; -- the current ring is still R
Using S Do  
  X := (a+b)^5;  -- assign a value to a variable in another ring  
EndUsing;
X;
S :: a^5 + b^5
-------------------------------
Use S;
X;
a^5 + b^5
------------------------------- 
</example>

(3) <coderef>Image</coderef>.  To map objects from one ring to another, one may use the
command <coderef>Image</coderef>.  An introduction to this command appears in the
following section and more details can be found in the online help
entry, <coderef>Image</coderef>.

<par/>
(4) <code>QZP</code>, <code>ZPQ</code>.  The commands <code>QZP</code> and <code>ZPQ</code> can sometimes be used to
quickly map a polynomial or ideal from an outside ring into the
current ring.  See the online help entry, <coderef>QZP, ZPQ</coderef>, for details.

<par/>
(5) <coderef>BringIn</coderef>. This is the easiest function, but may be
	slow, to map objects from one ring to another.
    </description>

        <key>accessing other rings</key>
        <see>Image</see>

        <see>QZP, ZPQ</see>

        <see>Use</see>

        <see>Using</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="12">
        <title>Ring Mappings: the Image Function</title>
        <type>1</type>

        <description>
The function <coderef>Image</coderef> implements a ring homomorphism.  Suppose S is
the current ring and R is another ring.  If X is an object in R, the
function <coderef>Image</coderef> may be used to substitute polynomials in S for the
indeterminates in X.  An example is given below and complete details
are given in the online help entry for <coderef>Image</coderef>. 

<par/>
To make substitutions within a single ring, one would usually use
<coderef>Eval</coderef> or <coderef>Subst</coderef> rather than <coderef>Image</coderef>.  To map a polynomial or ideal
from an outside ring into the current ring, the functions <code>QZP</code> and
<code>ZPQ</code> are sometimes useful.  To map a polynomial or rational function
(or a list, matrix, or vector of these) from R to S without changing
indeterminates, use the function <coderef>BringIn</coderef>.  (<code>BringIn</code> is only
applicable if the indeterminates of the object to be mapped are a
subset of those in S.)

        
<example>
Use R ::= Q[a,b,c];
X := a+b-3c;
Use S ::= Q[x,y]; 
F := RMap(x^2,2,y^2);  -- syntax for defining a map: the n-th
             -- indeterminate in the domain will be mapped to
             -- the n-th element listed in RMap.
X; -- X lives in the ring R
R :: a + b - 3c
-------------------------------
Image(X,F); -- the image of E under the map F
x^2 - 3y^2 + 2
-------------------------------
Image(R:: (a+b)^2,F);
x^4 + 4x^2 + 4
------------------------------- 
</example>
    </description>

        <key>ring mappings: the image function</key>
        <see>BringIn</see>

        <see>Image</see>

        <see>Eval</see>

        <see>QZP, ZPQ</see>

        <see>Subst</see>

        <see>Using</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="13">
        <title>Quotient Rings</title>
        <type>1</type>

        <description>
If <code>R</code> is a ring identifier and I is an ideal defined
in <code>R</code>, 
then <code>R/I</code> represents the corresponding quotient ring.  
It has type <code>TAGGED(<coc-quotes>Quotient</coc-quotes>)</code>.

        
<example>
Use R ::= Q[x,y];
I := Ideal(y-x^2);
Q := R/I;
Hilbert(Q);  -- the Hilbert function for Q
H(0) = 1
H(x) = 2   for x &gt;= 1
------------------------------- 
</example>
    </description>

        <key>quotient rings</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="14">
        <title>Commands and Functions for Rings</title>
        <type>1</type>

        <description>
The following are commands and functions controlling rings:
<commands_and_functions_for type="ring"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for rings</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="9">
      <chapter_name>Polynomials</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Polynomials</title>
        <type>1</type>

        <description>
An object of type POLY in CoCoA represents a polynomial.  To fix
terminology: 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>
The following are CoCoA polynomials:

Use R ::= Q[x,y,z];
F := 3xyz + xy^2;
F;
xy^2 + 3xyz
-------------------------------
Use R ::= Q[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.

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 ::= Q[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>

        <key>introduction to polynomials</key>
        <key>power-product</key>
        <key>world peace</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Evaluation of Polynomials</title>
        <type>1</type>

        <description>
Polynomials may be evaluated using the function <coderef>Subst</coderef>.  More
generally, <coderef>Subst</coderef> 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 <coderef>Eval</coderef>.  For more general substitutions, see <coderef>Image</coderef>.

        
<example>
Use R ::= Q[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 <code>Subst</code>
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>

        <key>evaluation of polynomials</key>
        <see>Eval</see>

        <see>Image</see>

        <see>Subst</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Commands and Functions for Polynomials</title>
        <type>1</type>

        <description>
The following are commands and functions for polynomials:
<commands_and_functions_for type="polynomial"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for polynomials</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="10">
      <chapter_name>Rational Functions</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Rational Functions</title>
        <type>1</type>

        <description>
An object of type RATFUN in CoCoA represents a rational function,
i.e., a quotient of polynomials.  Each rational function is
represented as P/Q where P and Q are polynomials (of type POLY) and
<formula>deg(Q) &gt; 0</formula>.  Common factors of the numerator and denominator are
automatically simplified.  At present, rational functions in CoCoA are
only available over a field.

        
<example>
Use R ::= Q[x,y];
F := x/(x+y);  -- a rational function
F*(x+y);
x
-------------------------------
(x^2-y^2)/(x+y);  -- the result here is a polynomial
x - y
------------------------------- 
</example>

The following algebraic operations on rational functions are supported:
<verbatim>
  F^N, +F, -F, F*G, F/G, F+G, F-G,
</verbatim>
where F, G are rational functions and N is an integer.

For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>introduction to rational functions</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Numerators and Denominators for Rational Functions</title>
        <type>2</type>

        <description>
If F is a variable holding a rational function, then F.Num and F.Den
are the numerator and denominator, respectively.  The functions <coderef>Num</coderef>
and <coderef>Den</coderef>, respectively, return the same.

        
<example>
F := x/(x+y);
F.Num;
x
-------------------------------
F.Den;
x+y
-------------------------------
Den(F);
x + y
------------------------------- 
</example>
    </description>

        <key>numerators and denominators for rational functions</key>
        <see>Den</see>

        <see>Num</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Commands and Functions for Rational Functions</title>
        <type>1</type>

        <description>
The following are commands and functions for rational functions:
<commands_and_functions_for type="ratfun"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for rational functions</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="11">
      <chapter_name>Ideals</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Ideals</title>
        <type>1</type>

        <description>
An object of type IDEAL in CoCoA represents an ideal. An ideal is
formed using the command <code>Ideal(P_1,...,P_n)</code> where the <code>P_i</code> are
generators for the ideal.

        
<example>
Use R ::= Q[x,y];
I := Ideal(x,y^2,2+xy^2); 
</example>

The following algebraic operations yield ideals:
<verbatim>
  I^N, I+J, E*F, P:Q
</verbatim>
where: I and J are ideals; N is a non-negative integer; E,F are either
both ideals or one is an ideal and the other is a polynomial; and the
pair (P,Q) has the form (IDEAL,POLY), (IDEAL,IDEAL),
(MODULE,VECTOR), (MODULE,MODULE).

        
<example>
Use R ::= Q[x,y];
I := Ideal(x,y^2,2+xy^2);
I^2;
Ideal(x^2, xy^2, x^2y^2 + 2x, y^4, xy^4 + 2y^2, x^2y^4 + 4xy^2 + 4)
-------------------------------
J := Ideal(y);
I+J;
Ideal(x, y^2, xy^2 + 2, y)
-------------------------------
I*J;
Ideal(xy, y^3, xy^3 + 2y)
------------------------------- 
</example>
    </description>

        <key>introduction to ideals</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Ideals</title>
        <type>1</type>

        <description>
The following are commands and functions for ideals:
<commands_and_functions_for type="ideal"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for ideals</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="12">
      <chapter_name>Modules</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Modules</title>
        <type>1</type>

        <description>
An object of type MODULE in CoCoA represents a submodule of a free
module.  A module is represented by its generators as:
<verbatim>
  Module(V_1,...,V_n)
</verbatim>
Each <code>V_i</code> has the form <code>[P_1,...P_r]</code> or 
<code>Vector(P_1,...P_r)</code>, where r is the rank of the free
module containing the given module and each <code>P_j</code> is of type POLY.

<par/>
As with ideals, information about a module can be accessed using the
same syntax as for records.

<par/>
CoCoA supports quotient modules and modules, as described in the next
section.  Shifts have been disabled in CoCoA 4.

        
<example>
Use S ::= Q[x,y];
M := Module([x,y^2,2+x^2y],[x,0,y]);  -- define the submodule of S^3
                          -- generated by (x,y^2,2+x^2y) and (x,0,y)
GBasis(M);
[Vector(x, 0, y), Vector(x, y^2, x^2y + 2)]
-------------------------------
Describe M;
Record[Type = MODULE, Value = Record[Gens = [[x, y^2, x^2y + 2], [x,
0, y]], MRC = 1, GBasis = [[x, 0, y], [x, y^2, x^2y + 2]]]]
-------------------------------
M.GBasis;
[Vector(x, 0, y), Vector(x, y^2, x^2y + 2)]
-------------------------------
M.Gens[1];
Vector(x, y^2, x^2y + 2)
-------------------------------
M.NumComps;  -- M is a submodule of a free module of rank 3
3
------------------------------- 
</example>
    </description>

        <key>introduction to modules</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Quotient Modules</title>
        <type>1</type>

        <description>
If M is a CoCoA module which is a submodule of the free module <formula>R^k</formula>
for some ring <formula>R</formula>, then <formula>R^k/M</formula> represents a quotient module.  It has type
TAGGED(<coc-quotes>Quotient</coc-quotes>).

        
<example>
Use R ::= Q[x,y];
M:= Module([x-y,x^2-y^2,x^3+xy^2],[y,x^2,x^2y]);
Q := R^3/M; 
</example>
    </description>

        <key>quotient modules</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Shifts</title>
        <type>1</type>

        <description>

<verbatim>
           ===========================================
              THIS FACILITY IS DISABLED IN COCOA 4

           (See the new function <code>GB.GetNthSyzShifts</code>;
            read below for an explanation of shifts.)
           ===========================================
</verbatim>

One creates a shifted module in CoCoA using the <coderef>Shifts</coderef> modifier:
<verbatim>
    Module(Shifts([P_1,...,P_r]),V_1,...,V_n)
</verbatim>
where the <code>P_i</code>&apos;s are integers or monomials in the current ring and, as
usual, the <code>V_i</code>&apos;s are lists of polynomials, each with length r.  This
object represents the submodule, generated by <code>V_1,...,V_n</code>, of the free
module of rank r which is the direct sum of <code>R(P_1),...,R(P_r)</code>.  Here,
<code>R(P_i)</code> is the ring R with shifted degrees.  To explain these shifts,
recall that in a CoCoA ring, the weights of the indeterminates are
given by a weights matrix, say W.  The (multi)weight of the i-th
indeterminate is given by the i-th column of W.  By default, the
weights matrix is a single row of 1s.  If <code>P_i</code> is an integer, then the
homogeneous part of <code>R(P_i)</code> of degree d is the homogeneous part of R of
degree <code>d+P_i</code>.  If <code>P_i</code> is a monomial, then the homogeneous part of
<code>R(P_i)</code> in multidegree d is the homogeneous part of R in multidegree
<code>d+deg_W(P_i)</code>.

        
<example>
Use R ::= Q[x,y,z];
M := Module([x,y,z],[x^2,y,0]);
LT(M.Gens[1]);
Vector(x, 0, 0)
-------------------------------
Deg(M.Gens[1]);
1
-------------------------------
Ss := Shifts([-3,-5,-2]);
M := Module(Ss,[x,y,z],[x^2,y,0]);
M;
Module(Shifts([-3, -5, -2]), [x, y, z], [x^2, y, 0])
-------------------------------
LT(M.Gens[1]);  -- the leading term changes in the shifted module
Vector(0, y, 0)
-------------------------------
Deg(M.Gens[1]);
6
-------------------------------
Use S ::= Q[x,y,z],Weights(Mat([[1,2,3],[4,5,6]]));
M := Module(Shifts([xy, xz]), [x, y], [x,z]);
LT(M.Gens[1]);
Vector(0, y)
-------------------------------
MDeg(M.Gens[1]);  -- multidegree of y in R(xz), i.e. of (xz)y in R
[6, 15]
------------------------------- 
</example>
    </description>

        <key>shifts</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Commands and Functions for Modules</title>
        <type>1</type>

        <description>
The following are commands and functions for modules:
<commands_and_functions_for type="module"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for modules</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="13">
      <chapter_name>Groebner Bases and Related Computations</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Groebner Bases in CoCoA</title>
        <type>1</type>

        <description>
The heart of the CoCoA system is a implementation of Buchberger&apos;s
algorithm for computing Groebner bases for ideals and modules over
polynomial rings with coefficients in a field.  CoCoA&apos;s Groebner basis
engine can be used to compute Groebner bases, syzygies, free
resolutions, Hilbert functions and Poincare series, and to eliminate
variables and find minimal sets of generators.  Considerable control
over the computations is provided through CoCoA&apos;s <ref>The Interactive
Groebner Framework</ref>.  

<par/>
Groebner bases can be calculated over Q, but large calculations
depending on Groebner bases will take much less time over finite
fields.  A common tactic is to work mod large primes to get an idea
of behavior expected over Q.

<par/>
It would eventually be nice to have descriptions within this online
help system of the specific algorithms used by CoCoA.  For now, see
<ref>Pointers to the Literature</ref> for references.
    </description>

        <key>introduction to groebner bases in cocoa</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Commands and Functions for Groebner-Type Computations</title>
        <type>2</type>

        <description>
The following are the commands and functions for computations based
on Groebner bases.  In addition to these, there are many commands that
provide finer control over the computations (see the next section:
<ref>The Interactive Groebner Framework</ref>).
<commands_and_functions_for type="groebner"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for groebner-type computations</key>
        <see>The Interactive Groebner Framework</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>The Interactive Groebner Framework</title>
        <type>1</type>

        <description>
For the following computations:
<verbatim>
  * Groebner bases
  * minimal generators
  * syzygies
  * free resolutions
  * elimination of variables
</verbatim>
CoCoA provides the following features:
<verbatim>
  * step-by-step computation
  * monitoring of the execution (verbose mode)
  * various types of truncation (degree, resolution length, or regularity)
  * customization of algorithms (through the GROEBNER panel and P-Series).
</verbatim>
It works like this: instead of using one of the normal Groebner
basis-type commands (listed in the previous section), start the
computation with one of the commands,
<verbatim>
  * GB.Start_GBasis -- start interactive Groebner basis computation
  * GB.Start_MinGens -- start interactive minimal generator calculation 
  * GB.Start_Res -- start interactive resolution computation
  * GB.Start_Syz -- start interactive syzygy computation
</verbatim>
After starting the computation, the following commands are available:
<verbatim>
  * GB.Complete -- Complete an interactive Groebner-type calculation
  * GB.GetBettiMatrix -- returns the Betti matrix computed so far
  * GB.GetNthSyz -- returns the part of the Nth syzygy module computed so far
  * GB.GetNthSyzShifts -- shifts of the Nth syzygy module computed so far
  * GB.GetRes -- returns the resolution computed so far
  * GB.GetResLen -- returns the length of the resolution computed so far
  * GB.ResReport -- status of an interactive resolution calculation
  * GB.Stats -- status of an interactive Groebner-type calculation
  * GB.Step, GB.Steps -- take steps in an interactive Groebner-type calculation
  * ReducedGBasis -- compute a reduced Groebner basis
</verbatim>
Almost all of these functions report more information if you set the
Verbose flag in the GROEBNER panel by typing
<verbatim>
  Set Verbose;
</verbatim>
(to unset, enter <code>Unset Verbose</code>).  For more possibilities, see
<ref>Options in the GROEBNER Panel</ref>.

Use of the Interactive Groebner Framework is illustrated in the
examples below.
    </description>

        <key>the interactive groebner framework</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Example: Interactive Groebner Basis Computation</title>
        <type>2</type>

        <description>

        
<example>
Use R ::= Q[t,x,y,z];
I := Ideal(t^3-x,t^4-y,t^5-z);
GB.Start_GBasis(I);  -- start the interactive framework
I.GBasis;  -- the Groebner basis is initially empty
Null
-------------------------------
GB.Step(I); -- a single step of the computation
I.GBasis;
I.GBasis;
[t^3 - x]
-------------------------------
GB.Steps(I,4); -- 4 more steps
I.GBasis;
[t^3 - x, -tx + y, t^2y - x^2]
-------------------------------
GB.Complete(I); -- complete the computation
I.GBasis;
[t^3 - x, -tx + y, -ty + z, -y^2 + xz, -x^2 + tz, t^2z - xy]
-------------------------------
ReducedGBasis(I);
[t^3 - x, tx - y, ty - z, y^2 - xz, x^2 - tz, t^2z - xy]
------------------------------- 
</example>

Note that Groebner bases calculated in the interactive framework may
not be reduced, as illustrated in the final step of the example.
    </description>

        <key>example: interactive groebner basis computation</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Example: Verbose Mode</title>
        <type>2</type>

        <description>
The following example illustrates the use of <code>Verbose</code> mode.  For
more information, see <ref>Verbose</ref>.

        
<example>
Set Verbose;
Use R ::= Q[t,x,y,z];
I := Ideal(t^3-x,t^4-y,t^5-z);
G := GBasis(I);
..................18
------------------------------------
 IPs  IVs Gens GBases MinGens MinDeg 
------------------------------------
   0    0    3      6       0     -1 
------------------------------------
Betti numbers: 
18 steps of computation

-------------------------------
Describe I;  -- more information, (it would help to <code>Set Indentation</code>)
Record[Type = IDEAL, Value = Record[Gens = [t^3 - x, t^4 - y, t^5 -
z], GBasis = [t^3 - x, -tx + y, -ty + z, -y^2 + xz, -x^2 + tz, t^2z -
xy], IVs = [ ], Rules = [t^3 - x, t^4 - y, t^5 - z, -tx + y, t^2y -
x^2, x^3 - ty^2, -ty + z, -y^2 + xz, -x^2 + tz, t^2z - xy],
Discrepancy = -1, KFL = [1, 7, 14, 4, 16, 9, 10, 20, 22, 23, 28, 18,
0, 39, 42]]]
------------------------------- 
</example>
    </description>

        <key>example: verbose mode</key>
        <see>Describe</see>

        <see>Verbose</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Example: Interactive Resolution Computation</title>
        <type>2</type>

        <description>
In this example we compute the minimal free resolution of the ideal I
generated by the 2 by 2 minors of a catalecticant matrix, A, using the
interactive environment of the system. We define the ideal I, and
start the computation of its minimal free resolution using the
Hilbert-driven algorithm described in

<par/>
     A. Capani, G. De Dominicis, G. Niesi, L. Robbiano,
     <em>Computing Minimal Finite Free Resolutions</em>,
     J. Pure Appl. Algebra, Vol. 117--118, Pages 105--117, 1997.

        
<example>
Use R ::= Z/(32003)[z[0..3,0..3,0..3]]; -- set up the ring
A := Mat([                              -- define the ideal
  [z[3,0,0], z[2,1,0], z[2,0,1]],
  [z[2,1,0], z[1,2,0], z[1,1,1]],
  [z[2,0,1], z[1,1,1], z[1,0,2]],
  [z[1,2,0], z[0,3,0], z[0,2,1]],
  [z[1,1,1], z[0,2,1], z[0,1,2]],
  [z[1,0,2], z[0,1,2], z[0,0,3]]
]);
I := Ideal(Minors(2,A));
GB.Start_Res(I);                        -- start interactive framework

GB.Steps(I,1000);                       -- first 1000 steps
GB.GetRes(I);
0 --&gt; R^176(-5) --&gt; R^189(-4) --&gt; R^105(-3) --&gt; R^27(-2)
-------------------------------
GB.ResReport(I);
--------------------------------------------------------------
Minimal Pairs,             :   650
  Groebner Pairs           :    14
  Minimal (Type S)         :   636
      H-Killed (Type S0)   :     9
--------------------------------------------------------------
-------------------------------
GB.Complete(I);                        -- complete the calculation
GB.GetRes(I);
0 --&gt; R(-9) --&gt; R^27(-7) --&gt; R^105(-6) --&gt; R^189(-5) --&gt; 
   R^189(-4) --&gt; R^105(-3) --&gt; R^27(-2)
-------------------------------
GB.ResReport(I);
--------------------------------------------------------------
Minimal Pairs,             :   730
  Groebner Pairs           :    25
  Minimal (Type S)         :   705
    Minimal (Type Smin)    :   616
    Minimal (Type S0)      :    89
      H-Killed (Type S0)   :    78
      Hard (Type S0)       :    11
--------------------------------------------------------------
------------------------------- 
</example>
    </description>

        <key>example: interactive resolution computation</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Example: Truncations</title>
        <type>2</type>

        <description>
The user may assign one or more of three different truncation
conditions to a module: DegTrunc, ResTrunc and RegTrunc; in this case
the execution will stop when a bound is reached (see the examples,
below).

<par/>
DEGREE TRUNCATION:

        
<example>
Use R ::= Z/(32003)[a,b,c,d,e];
I := Ideal(a+b+c+d, ab+bc+cd+da, abc+bcd+cda, abcd-e^4);
I.DegTrunc := 3;
GB.Start_GBasis(I);
GB.Complete(I);
LT(I.GBasis);
[a, b^2, bc^2]
-------------------------------
I.DegTrunc := 6;
GB.Complete(I);
LT(I.GBasis);
[a, b^2, bc^2, bcd^2, c^2d^2, cd^4, be^4, d^2e^4]
------------------------------- 
</example>

RESOLUTION TRUNCATION:

        
<example>
Use R ::= Z/(32003)[x[1..10]];
I := Ideal(Indets());
I.ResTrunc := 4;
GB.Start_Res(I);
GB.Complete(I);
GB.GetRes(I);
0 --&gt; R^252(-5) --&gt; R^210(-4) --&gt; R^120(-3) --&gt; R^45(-2) --&gt; R^10(-1)
------------------------------- 
</example>

REGULARITY TRUNCATION:
We know that the Castelnuovo regularity of I in the following example
is 6.  

        
<example>
Set Verbose;
Use R_Gen ::= Z/(5)[x,y,z,t];
M := 3; N := 4;
D := DensePoly(2);
P := Mat([ [ Randomized(D) | J In 1..N ] | I In 1.. M]);
I := Ideal(Minors(2,P));
GB.Start_Res(I);
GB.Complete(I);
-- text suppressed --
Betti numbers: 17 48 48 18 
318 steps of computation

I := Ideal(Minors(2,P));
GB.Start_Res(I);
I.RegTrunc := 6; -- here we store the Castelnuovo Regularity
GB.Complete(I);
...
Betti numbers: 17 48 48 18 
281 steps of computation

GB.GetBettiMatrix(I);
-------------------
   0    0    0    0 
   0    0    0    0 
   0    0    0    0 
   0    0    0   18 
   0    0   16    0 
   0    0   32    0 
   0   48    0    0 
  17    0    0    0 
------------------- 
</example>
    </description>

        <key>example: truncations</key>
        <key>truncate</key>
        <key>truncations</key>
        <key>degtrunc</key>
        <key>regtrunc</key>
        <key>restrunc</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>Hilbert-Driven Computations</title>
        <type>1</type>

        <description>
CoCoA Groebner basis algorithms will use knowledge of a Poincare
series to improve efficiency.

        
<example>
Use R ::= Q[w,x,y,z];
PS := HP.PSeries(1 + 2w + 3w^2 + 4w^3 + 5w^4 + 6w^5 + 5w^6 +
 4w^7 + 3w^8 + 2w^9 + w^10,2);
PS;
(1 + 2w + 3w^2 + 4w^3 + 5w^4 + 6w^5 + 5w^6 + 4w^7 + 3w^8 + 2w^9 + w^10) / (1-w)^2
-------------------------------
I := Ideal((xy-zw)^3,(xz-yw)^3);
I.PSeries := PS; -- this is how to let CoCoA know about the Poincare series
G := GBasis(I); 
</example>
    </description>

        <key>hilbert-driven computations</key>
      </section>

    </chapter>


  </part>
  <part number="5">
    <name>Working the System</name>
<!-- ===  CHAPTER  =============================================== -->
    <chapter number="1">
      <chapter_name>CoCoA Panels</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Introduction to Panels</title>
        <type>1</type>

        <description>
The user can customize some features of CoCoA by setting (or
unsetting) some boolean options (ON/OFF) which are grouped in three
panels.  The function <coderef>Panels</coderef> returns the list of panel names, and
the settings in a particular panel can be seen using the function
<coderef>Panel</coderef> as illustrated in the example below.

        
<example>
Panels();
[<coc-quotes>GENERAL</coc-quotes>, <coc-quotes>GROEBNER</coc-quotes>]
-------------------------------
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
------------------------------- 
</example>
    </description>

        <key>introduction to panels</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Setting Options</title>
        <type>2</type>

        <description>
Each option name is unique, not just among the options in a
particular panel, but among the options from all panels.  The command
<code>Set</code> followed by an option name (without parentheses or quotes) sets
the corresponding option to TRUE.  Similarly, <code>Unset</code> sets the option
to FALSE.  In addition, one may use the <code>Set</code> command to set an option
either true or false using the syntax: <code>Set option-name := TRUE</code> or
<code>Set option-name := TRUE</code>. 

        
<example>
Use R ::= Q[x,y,z];
L := [(x+y)^N | N In 1..3];
Set Indentation;  -- print each component on a separate line
L;
L;
[
  x + y,
  x^2 + 2xy + y^2,
  x^3 + 3x^2y + 3xy^2 + y^3]
-------------------------------
Unset Indentation; 
</example>


The function <coderef>Option</coderef> takes as parameter an option name and
returns the (boolean) value of the option.  It is particularly useful
within user-defined functions as illustrated in the example below:

        
<example>
Define Print_UnIndented(X)
  Opt := Option(Indentation);
  Unset Indentation;
  Print(X);
  Set Indentation := Opt;
EndDefine;

R := Record[X=<coc-quotes>test</coc-quotes>,L=[1,2,3]];
Set Indentation;
Print_UnIndented(R);
Record[L = [1, 2, 3], X = <coc-quotes>test</coc-quotes>]
-------------------------------
UnSet Indentation;
Print_UnIndented(R);
Record[L = [1, 2, 3], X = <coc-quotes>test</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>setting options</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Options in the GENERAL Panel</title>
        <type>2</type>

        <description>
The options in the GENERAL panel and their default settings are as
follows:

        
<example>
Panel(GENERAL);

Echo............... : FALSE
Timer.............. : FALSE
Trace.............. : FALSE
Indentation........ : FALSE
TraceSources....... : FALSE
SuppressWarnings... : FALSE
ComputationStack... : FALSE
-------------------------------

They are discussed separately, below. 
</example>
    </description>

        <key>options in the general panel</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Echo</title>
        <type>3</type>

        <description>
If the Echo option is on, then the system echoes every command at the
top level.  When logging a CoCoA session, one would set Echo to TRUE
in order to log both the input as well as the output in a CoCoA
session (see <coderef>OpenLog</coderef>).

        
<example>
1+1;
2
-------------------------------
Set Echo;
1+1;
1 + 1
2
-------------------------------
L := [1,2,3];
L := [1, 2, 3]
Unset Echo;
SET(Echo, FALSE)
L := [4,5,6];
------------------------------- 
</example>
    </description>

        <key>echo</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="5">
        <title>Timer</title>
        <type>3</type>

        <description>
If the Timer option is on, then the system displays the execution
time of each command submitted at top-level.

        
<example>
Use R ::= Z/(32003)[t,x,y,z],Lex;
N:=31;
I := Ideal(t^N+t^6+t-x, t^5-t-y, t^9-t-z);
Set Timer;
Null
-------------------------------
T := GBasis(I);
Cpu time = 2.88, User time = 30
-------------------------------

To time a single command, use <coderef>Time</coderef>.  For example, above, we could
have written <code>Time T := GBasis(I)</code> instead of setting the timer. 
</example>
    </description>

        <key>time</key>
        <key>timer</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="6">
        <title>Trace</title>
        <type>3</type>

        <description>
If the Trace option is on, then the system echoes every command at
every level.  This is useful for debugging programs.  The following
(toy) user-defined function returns the same error message for N = 3
and N = 6.  Turning the Trace option on makes the sources of the
trouble clear.

        
<example>
Define T(N)
  M := 1/(N-3);
  If N = 6 Then N := 3 EndIf;
  M := 1/(N-3);
  Return M;
EndDefine;
T(3);

-------------------------------
ERROR: Division by zero
CONTEXT: 1 / (N - 3)
-------------------------------
T(6);

-------------------------------
ERROR: Division by zero
CONTEXT: 1 / (N - 3)
-------------------------------
Set Trace;
T(3);
T(3)
M := 1 / (N - 3); IF N = 6 THEN N := 3 END; M := 1 / (N - 3); Return(M); 
M := 1 / (N - 3)

-------------------------------
ERROR: Division by zero
CONTEXT: 1 / (N - 3)
-------------------------------
T(6);
T(6)
M := 1 / (N - 3); IF N = 6 THEN N := 3 END; M := 1 / (N - 3); Return(M); 
M := 1 / (N - 3)
IF N = 6 THEN N := 3 END
N := 3
M := 1 / (N - 3)

-------------------------------
ERROR: Division by zero
CONTEXT: 1 / (N - 3)
------------------------------- 
</example>
    </description>

        <key>trace</key>
        <see>ComputationStack</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="7">
        <title>Indentation</title>
        <type>3</type>

        <description>
If the Indentation option is on, then the system performs some
indentation on outputs.  For example, each entry of a matrix will be
printed on a new line.

        
<example>
Use R ::= Q[xyz]
T := GBasis(Ideal(x^2-xy+z^3,xz-y^4,x^3+y^3+xyz+z^5));
T;
[z^3 + x^2 - xy, -y^4 + xz, x^2z^2 - xyz^2 - x^3 - y^3 - xyz, x^4 -
2x^3y + x^2y^2 + x^3z + y^3z + xyz^2]
-------------------------------
Set Indentation;
T;
[
  z^3 + x^2 - xy,
  -y^4 + xz,
  x^2z^2 - xyz^2 - x^3 - y^3 - xyz,
  x^4 - 2x^3y + x^2y^2 + x^3z + y^3z + xyz^2]
------------------------------- 
</example>
    </description>

        <key>indentation</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="8">
        <title>TraceSources</title>
        <type>3</type>

        <description>
If the TraceSources option is on, then the name of every file read
with the <coderef>Source</coderef> command will be echoed.
    </description>

        <key>tracesources</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="9">
        <title>SuppressWarnings</title>
        <type>3</type>

        <description>
If the SuppressWarnings option is on, then the system suppress warning
statements.

        
<example>
Use Z/(4);
-- WARNING: Coeffs are not in a field
-- GBasis-related computations could fail to terminate or be wrong
-------------------------------

-------------------------------
Set SuppressWarnings;
Use Z/(4); 
</example>
    </description>

        <key>suppresswarnings</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="10">
        <title>ComputationStack</title>
        <type>3</type>

        <description>
If the ComputationStack option is on, a special variable named
<code>ComputationStack</code> contains a list tracing errors that occur during
the execution of CoCoA commands.  This option is useful for debugging
programs.

        
<example>
Define Test(X)
  If X&gt;=0 Then PrintLn(1/X) EndIf;
EndDefine;

Set ComputationStack;
Test(0);


-------------------------------
ERROR: Division by zero
CONTEXT: 1 / X
-------------------------------
S := ComputationStack;  -- to save typing later
S[1];  -- the command that produced the error
PrintLn(1 / X)
-------------------------------
S[2];  -- S[1] was part of an If-statement
IF X &gt;= 0 THEN PrintLn(1 / X) END
-------------------------------
S[3];  -- the command issued by the user 
IF X &gt;= 0 THEN PrintLn(1 / X) END; 
------------------------------- 
</example>
    </description>

        <key>computationstack</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="11">
        <title>Options in the GROEBNER Panel</title>
        <type>2</type>

        <description>
The options in the GROEBNER panel and their default settings are as
follows:
        
<example>
Panel(GROEBNER);

Sugar........... : TRUE
FullRed......... : TRUE
SingleStepRed... : FALSE
Verbose......... : FALSE
------------------------------- 
</example>
    </description>

        <key>options in the groebner panel</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="12">
        <title>Sugar</title>
        <type>3</type>

        <description>
If the Sugar option is on, as it is by default, then the critical
pairs are processed by using the <em>sugar</em> strategy: the pairs are
processed in an order which is as close as possible to the order which
would have been chosen if the polynomials had been homogeneous.  For
details, see the article:

<par/>
A. Giovini, T. Mora, G. Niesi, L. Robbiano, C. Traverso, 
 <em>`One sugar cube, please&apos; 
   or selection strategies in the Buchberger algorithm,</em> 
In Proc. ISSAC`91, 49--54 (1991), Stephen M. Watt, editor, New York, 
ACM Press.
    </description>

        <key>sugar</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="13">
        <title>FullRed</title>
        <type>3</type>

        <description>
If FullRed is set to TRUE, then when a normal form is required in any
Groebner-type computation, CoCoA will reduce all monomials in a
polynomial; if FullRed is FALSE, only the leading terms will be
reduced.  The default is to have FullRed set to TRUE.

        
<example>
UnSet FullRed;
Use R ::= Q[x,y];
Interreduced([xy^3+y^2+x,x]);
[x, y^2 + x]
-------------------------------
Set FullRed;
Interreduced([xy^3+y^2+x,x]);
[x, y^2]
------------------------------- 
</example>
    </description>

        <key>fullred</key>
        <see>Interreduced</see>

      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="14">
        <title>SingleStepRed</title>
        <type>3</type>

        <description>
Sorry: documentation not yet available.
    </description>

        <key>singlestepred</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="15">
        <title>Verbose</title>
        <type>3</type>

        <description>
Sorry: documentation not yet available.
    </description>

        <key>verbose</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="16">
        <title>Commands and Functions for Panels</title>
        <type>1</type>

        <description>
The following are commands and functions for panels:
<commands_and_functions_for type="panels"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.
    </description>

        <key>commands and functions for panels</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="2">
      <chapter_name>CoCoA&apos;s Help System</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>Online Help</title>
        <type>1</type>

        <description>
CoCoA&apos;s online help is roughly divided into two parts: a manual and a
list of commands.  The manual includes a tutorial which can be started
by entering

<par/>
  ?tutorial

<par/>
If you are a new user of CoCoA, the tutorial is a good place to start.
To see the titles of the sections of the online manual, enter
<code>H.Toc()</code>; to see a list of commands, enter <code>H.Commands(<coc-quotes></coc-quotes>)</code>.

<par/>
Each section of the manual and each command is uniquely identified by
a set of keywords.  The set of keywords always includes the title of
the section or the title of the command.  The online help command <code>?</code>
takes a string from the user and searches for a match among the
keywords.  For instance, <code>?gbasis</code> will display information
about the function <coderef>GBasis</coderef>.  Note that when using <code>?</code>, the keyword
does not appear in quotes.  Also, a semicolon is not required.

<par/>
The command <code>??</code> will return a list of entries in the manual that
contain a given keyword.  For instance, <code>??gbasis</code> returns
<verbatim>
    See:
      GB.Start_GBasis
      GBasis
      ReducedGBasis
    -------------------------------
</verbatim>
Each command is associated with a list of topics.  (This applies only
to commands, not to sections of the manual.)  The online help function
<code>H.Commands</code> 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, <code>H.Commands(<coc-quotes>poly</coc-quotes>)</code>
will find all commands having to do with polynomials.  Information
about a specific command can then be retrieved with <code>?</code>.  A list of
topics is provided by <code>H.Commands()</code>, with no argument.

<par/>
IMPORTANT NOTE: Searches are case insensitive and your keyword need
only be a substring to make a match.

<par/>
For a thorough description of the search function <code>?</code>, type <code>? ?</code> with
a space between the two questions marks.

<par/>
Tips on using online help and summary of the online help functions
appear below.  Enter <code>H.Browse();</code> to see the next section.
    </description>

        <key>online help</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>Quick Tips for Using Online Help</title>
        <type>2</type>

        <description>
Here are some tips for using the online help system:

<par/>
1. Searches are case insensitive and your search string need only be a
substring of a keyword to make a match.  Thus, for instance, to find
the section of the manual entitled <ref>Commands and Functions for Polynomials</ref>, it is enough to type: <code>?for poly</code>.

<par/>
2. In general, it is best to start with short keywords in order to
maximize the number of matches.  

<par/>
3. If you cannot find a match using <code>?</code>, try using <code>H.Command</code> to
search by type.  For example, suppose you are looking for a command
that will give the remainder of the division of one polynomial into
another.  Trying <code>?remainder</code> produces no matches.  You know
that the command you are looking for operates on polynomials, so try
<code>H.Command(<coc-quotes>poly</coc-quotes>)</code>.  It produces a list of a little over 30 commands,
among which will be listed:

<par/>
  * DivAlg -- division algorithm.

<par/>
4.  The command <code>??keyword</code>, with two question marks, will list all
matches even if <em>keyword</em> exactly matches a keyword for the online
help system.
    </description>

        <key>quick tips for using online help</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
        <title>Commands and Functions for Online Help</title>
        <type>2</type>

        <description>
The following are commands and functions for CoCoA online help:
<commands_and_functions_for type="help"></commands_and_functions_for>
For details look up each item by name.  Online, try
<code>?ItemName</code> or <code>H.Syntax(<coc-quotes>ItemName</coc-quotes>)</code>.  A good place to start is
with the command, <code>?</code>, itself. To see more information about <code>?</code>,
enter <code>? ?</code> (with a space between the two question marks)
    </description>

        <key>commands and functions for online help</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="4">
        <title>Other Help</title>
        <type>1</type>

        <description>
1. A user may provide help and sometimes (rarely) get help for a
user-defined function using the <code>Help</code> feature of the <coderef>Define</coderef>
command.

        
<example>
Help();
Type Help &lt; Op &gt; to get help on operator &lt; Op &gt;
-------------------------------
Help(<coc-quotes>GBasis</coc-quotes>);  -- note the typical response, one of the main
                 -- motivations for the author of the online manual.
No help available for GBasis
------------------------------- 
</example>

2. The command, <coderef>Describe</coderef>, can be used to find more information about
functions.   

        
<example>
Describe Function(<coc-quotes>Insert</coc-quotes>);
DEFINE Insert(L,I,O)
  $list.Insert(L,I,O)
END
-------------------------------
Describe Function(<coc-quotes><code>$list.Insert</code></coc-quotes>);
DEFINE Insert(L,I,O)
  IF NOT(Type(L) = LIST) THEN 
    Return(Error(ERR.BAD_PARAMS, <coc-quotes>: expected LIST</coc-quotes>))
  ELSIF I = Len(L) + 1 THEN 
    Append(L,O)
  ELSIF I &gt; Len(L) THEN 
    Return(Error(ERR.INDEX_TOO_BIG,I))
  ELSIF I &lt;= 0 THEN 
    Return(Error(ERR.INDEX_NEG,I))
  ELSE 
    L := Concat([L[J]|J IN 1..(I - 1)],[O],[L[J]|J IN I..Len(L)]); 
  END; 
END
------------------------------- 
</example>


3. The function, <coderef>Functions</coderef>, may be used to list all functions
defined in a package.  
Note: <code>Functions(<coc-quotes>$user</coc-quotes>)</code>
lists all current user-defined functions.  

        
<example>
Functions(<coc-quotes>$mat</coc-quotes>);
[About(), Man(), Identity(N), Transposed(M), Submat(M,Rows,Cols),
Jacobian(S), Resultant(F,G,X), DirectSum(M1,M2), BlockMatrix(LL),
ColumnVectors(M), Complement(M,I,J), Bip(M,J), Pfaffian(M),
Sylvester(F,G,X), ExtendRows(M,N), PushRows(M,N), ConcatRows(L),
PkgName()]
------------------------------- 
</example>

The list of packages is given by <code>Packages()</code>.

<par/>
4. The function <code>Starting(S)</code> where S is a string returns a list of all
functions starting with the string S.

        
<example>
Starting(<coc-quotes>Su</coc-quotes>);
[<coc-quotes>SubstPoly</coc-quotes>, <coc-quotes>SubSet</coc-quotes>, <coc-quotes>Submat</coc-quotes>, <coc-quotes>Sum</coc-quotes>, <coc-quotes>Subst</coc-quotes>, <coc-quotes>Support</coc-quotes>]
------------------------------- 
</example>
    </description>

        <key>other help</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="3">
      <chapter_name>Fine Tuning At Start-up</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>User Initialization</title>
        <type>1</type>

        <description>
At the beginning of a CoCoA session, CoCoA reads in a file called
<code>init.coc</code>.  This file performs certain initialization routines, reads
in standard packages, and sets up global aliases for the packages.  It
also reads in a file called <code>userinit.coc</code>.  It is in this latter file
that users should put their own commands to be run when CoCoA starts.

<par/>
For example, suppose a user wants a file called <code>MyFile.coc</code>---
containing function definitions, variable assignments, etc.---to
automatically be read into the CoCoA system on start-up.  It suffices
to add the following line to <code>userinit.coc</code>:
<verbatim>
Source(<coc-quotes>MyFile.coc</coc-quotes>);
</verbatim>
To load the package with identifier <code>$contrib/mypackage</code>, contained in a
file <code>MyPackage.cpkg</code> and use MP as an alias, it suffices to add the
following lines to <code>userinit.coc</code> (you may want to look at the section
of the manual entitled <ref>Package Sourcing and Autoloading</ref> for more details):
<verbatim>
Source(<coc-quotes>MyPackage.cpkg</coc-quotes>);
Alias MP := $contrib/mypackage;
</verbatim>
    </description>

        <key>user initialization</key>
      </section>

    </chapter>


<!-- ===  CHAPTER  =============================================== -->
    <chapter number="4">
      <chapter_name>CoCoA Interfaces</chapter_name>
<!-- ===  SECTION  =============================================== -->
      <section number="1">
        <title>CoCoA on a Macintosh</title>
        <type>1</type>

        <description>
The CoCoA user interface on the Macintosh OS 9 is based on Mel Park&apos;s
PlainText (v.1.6) which handles very large text files (larger than
32K).  It uses standard Macintosh editing techniques, so Macintosh
users should be familiar with its basic operations.

<par/>
Double-clicking on the CoCoA icon or on the icon of a CoCoA document
will start up the system. The system draws the menu bar, opens a text
editing window and loads the CoCoA packages and then possibly user&apos;s
packages (via the <code>userinit.coc</code> file).

<par/>
After the system is started, it is ready to receive and execute
commands.  To execute a CoCoA command, type it into the window, ending
it with a semicolon, then press the <em>enter</em> key. If the command
occupies more than one line then highlight the whole command using the
mouse and then press the <em>enter</em> key. 

<par/>
At this point the following part of the text of the active window is
taken as being the <em>current command</em>:

<par/>
 * if there is no selection (the cursor is blinking somewhere), then
   the row containing the cursor is taken as current command;

<par/>
 * if there is a non-null selection range, then the whole selection is
   taken as current command (in this way the system can process multiline
   commands).

<par/>
The editor uses all the standard Macintosh editing techniques as well as
some special ones:

<par/>
 * Double-clicking on a word select the entire word.
 * Triple-clicking anywhere in a line selects the whole line.
 * Double-clicking on or just before a parenthesis, a bracket, or a
   brace, i.e. one of following symbols <code>(</code> , <code>)</code> , <code>[</code> , <code>]</code> , <code>{</code> ,
   <code>}</code> causes all the text between that symbol and its matching symbol
   to become selected.

<par/>
IMPORTANT NOTE. Devices of type FILE are not yet available with the
Macintosh interface.
    </description>

        <key>cocoa on a macintosh</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="2">
        <title>CoCoA under Unix</title>
        <type>1</type>

        <description>
Probably the best way to run CoCoA under Unix is through the editor,
emacs, in shell-mode.  In that way, one may easily edit or repeat
commands.  From within emacs, issue the command <code>META-x shell</code>.  You
will be presented with a Unix prompt within emacs.  Change to the
CoCoA directory, and start CoCoA.  For more information about
shell-mode, issue the emacs command <code>Control-h m</code> after the shell is
started.  (You may want to use the emacs command: 
<code>META-x set-variable comint-scroll-show-maximum-output</code>
to set the variable comint-scroll-show-maximum-output to the value 1.)

<par/>
If running CoCoA in an xterm, it may be best to first start the xterm
with the command <code>xterm -sb -sl 512</code> (scroll bar enabled, saving 512
lines).  In addition, you may want to increase the vertical size of
your window, e.g., <code>xterm -sb -sl 512 -geometry 80x40</code>.  In that way,
output that scrolls off of the screen is captured and easily reviewed.

<par/>
At any rate, complicated CoCoA command sequences or any sequences that
you may want to repeat should be saved in a text editor.  The commands
can then be executed by copying and pasting into a CoCoA window or
using the <coderef>Source</coderef> command.  In addition, you may want to keep a log
of your CoCoA session using the command <coderef>OpenLog</coderef>.
    </description>

        <key>cocoa under unix</key>
      </section>

<!-- ===  SECTION  =============================================== -->
      <section number="3">
          <title>CoCoA under Windows/DOS</title>
          <type>1</type>

          <description>
Sorry this section is still under construction.  Probably the best
advice I could give is to repartition your disk and install Linux. ;&gt;
          </description>

          <key>cocoa under windows/dos</key>
        </section>

    </chapter>


  </part>
</manual_parts>

</help>
<!--  LocalWords:  CoCoA adjoints indeterminates equidimensional towards
 -->

