diff --git a/books/Makefile b/books/Makefile
new file mode 100644
index 0000000..d91e0ea
--- /dev/null
+++ b/books/Makefile
@@ -0,0 +1,205 @@
+AXIOM=/usr/local/axiom/mnt/fedora5
+TANGLE=${AXIOM}/bin/lib/notangle
+WEAVE=${AXIOM}/bin/lib/noweave 
+LATEX=latex
+MAKEINDEX=makeindex
+DVIPS=dvips -Ppdf
+PS2PDF=ps2pdf
+RM=rm -f
+
+all: 
+
+remake: bookvol0 bookvol1 bookvol2 bookvol3 bookvol4 bookvol5 bookvol6 \
+        bookvol7 bookvol8 bookvol9 bookvol10 bookvol11 bookvol12 toc
+
+toc:
+	@echo "\\documentclass{book}" >toc.tex
+	@echo "\\begin{document}" >>toc.tex
+	@echo "{\\bf Volume ~ 0}: Axiom {\\sl Jenks and Sutor}\\\\" >toc.toc
+	@echo "{\\bf Volume ~ 1}: Axiom {\\sl Tutorial}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 2}: Axiom {\\sl Users Guide}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 3}: Axiom {\\sl Programmers Guide}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 4}: Axiom {\\sl Developers Guide}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 5}: Axiom {\\sl Interpreter}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 6}: Axiom {\\sl Command}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 7}: Axiom {\\sl Hyperdoc}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 8}: Axiom {\\sl Graphics}\\\\" >>toc.toc
+	@echo "{\\bf Volume ~ 9}: Axiom {\\sl Compiler}\\\\" >>toc.toc
+	@echo "{\\bf Volume 10}: Axiom {\\sl Algebra}\\\\" >>toc.toc
+	@echo "{\\bf Volume 11}: Axiom {\\sl Browser}\\\\" >>toc.toc
+	@echo "{\\bf Volume 12}: Axiom {\\sl Crystal}\\\\" >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\tableofcontents" >>toc.tex
+	@echo "\\end{document}" >>toc.tex
+	@echo "\\section*{Volume 0: Axiom Jenks and Sutor}" >>toc.toc
+	@cat bookvol0.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 1: Axiom Tutorial}" >>toc.toc
+	@cat bookvol1.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 2: Axiom Users Guide}" >>toc.toc
+	@cat bookvol2.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 3: Axiom Programmers Guide}" >>toc.toc
+	@cat bookvol3.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 4: Axiom Developers Guide}" >>toc.toc
+	@cat bookvol4.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 5: Axiom Interpreter}" >>toc.toc
+	@cat bookvol5.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 6: Axiom Command}" >>toc.toc
+	@cat bookvol6.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 7: Axiom Hyperdoc}" >>toc.toc
+	@cat bookvol7.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 8: Axiom Graphics}" >>toc.toc
+	@cat bookvol8.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 9: Axiom Compiler}" >>toc.toc
+	@cat bookvol9.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 10: Axiom Algebra}" >>toc.toc
+	@cat bookvol10.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 11: Axiom Browser}" >>toc.toc
+	@cat bookvol11.toc >>toc.toc
+	@echo "\\newpage" >>toc.toc
+	@echo "\\section*{Volume 12: Axiom Crystal}" >>toc.toc
+	@cat bookvol12.toc >>toc.toc
+	@${LATEX} toc.tex
+	@${DVIPS} toc.dvi 2>/dev/null
+	@${PS2PDF} toc.ps >/dev/null
+	@${RM} -f *.toc toc.aux toc.dvi toc.log toc.ps toc.tex toc.toc
+
+bookvol0: 
+	@${LATEX} bookvol0.pamphlet
+	@${LATEX} bookvol0.pamphlet >/dev/null
+	@${DVIPS} bookvol0.dvi 2>/dev/null
+	@${PS2PDF} bookvol0.ps >/dev/null
+	@${RM} bookvol0.aux bookvol0.dvi bookvol0.log bookvol0.ps \
+               bookvol0.idx bookvol0.tex
+
+bookvol1:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol1.pamphlet >bookvol1.tex)
+	@${LATEX} bookvol1.tex
+	@${LATEX} bookvol1.tex >/dev/null
+	@${DVIPS} bookvol1.dvi 2>/dev/null
+	@${PS2PDF} bookvol1.ps >/dev/null
+	@${RM} bookvol1.aux bookvol1.dvi bookvol1.log bookvol1.ps \
+               bookvol1.idx bookvol1.tex
+
+bookvol2:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol2.pamphlet >bookvol2.tex)
+	@${LATEX} bookvol2.tex
+	@${LATEX} bookvol2.tex >/dev/null
+	@${DVIPS} bookvol2.dvi 2>/dev/null
+	@${PS2PDF} bookvol2.ps >/dev/null
+	@${RM} bookvol2.aux bookvol2.dvi bookvol2.log bookvol2.ps \
+               bookvol2.idx bookvol2.tex
+
+bookvol3:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol3.pamphlet >bookvol3.tex)
+	@${LATEX} bookvol3.tex
+	@${LATEX} bookvol3.tex >/dev/null
+	@${DVIPS} bookvol3.dvi 2>/dev/null
+	@${PS2PDF} bookvol3.ps >/dev/null
+	@${RM} bookvol3.aux bookvol3.dvi bookvol3.log bookvol3.ps \
+               bookvol3.idx bookvol3.tex
+
+bookvol4:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol4.pamphlet >bookvol4.tex)
+	@${LATEX} bookvol4.tex
+	@${LATEX} bookvol4.tex >/dev/null
+	@${DVIPS} bookvol4.dvi 2>/dev/null
+	@${PS2PDF} bookvol4.ps >/dev/null
+	@${RM} bookvol4.aux bookvol4.dvi bookvol4.log bookvol4.ps \
+               bookvol4.idx bookvol4.tex
+
+bookvol5:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol5.pamphlet >bookvol5.tex)
+	@${LATEX} bookvol5.tex
+	@${LATEX} bookvol5.tex >/dev/null
+	@${DVIPS} bookvol5.dvi 2>/dev/null
+	@${PS2PDF} bookvol5.ps >/dev/null
+	@${RM} bookvol5.aux bookvol5.dvi bookvol5.log bookvol5.ps \
+               bookvol5.idx bookvol5.tex
+
+bookvol6:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol6.pamphlet >bookvol6.tex)
+	@${LATEX} bookvol6.tex
+	@${LATEX} bookvol6.tex >/dev/null
+	@${DVIPS} bookvol6.dvi 2>/dev/null
+	@${PS2PDF} bookvol6.ps >/dev/null
+	@${RM} bookvol6.aux bookvol6.dvi bookvol6.log bookvol6.ps \
+               bookvol6.idx bookvol6.tex
+
+bookvol7:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol7.pamphlet >bookvol7.tex)
+	@${LATEX} bookvol7.tex
+	@${LATEX} bookvol7.tex >/dev/null
+	@${DVIPS} bookvol7.dvi 2>/dev/null
+	@${PS2PDF} bookvol7.ps >/dev/null
+	@${RM} bookvol7.aux bookvol7.dvi bookvol7.log bookvol7.ps \
+               bookvol7.idx bookvol7.tex
+
+bookvol8:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol8.pamphlet >bookvol8.tex)
+	@${LATEX} bookvol8.tex
+	@${LATEX} bookvol8.tex >/dev/null
+	@${DVIPS} bookvol8.dvi 2>/dev/null
+	@${PS2PDF} bookvol8.ps >/dev/null
+	@${RM} bookvol8.aux bookvol8.dvi bookvol8.log bookvol8.ps \
+               bookvol8.idx bookvol8.tex
+
+bookvol9:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol9.pamphlet >bookvol9.tex)
+	@${LATEX} bookvol9.tex
+	@${LATEX} bookvol9.tex >/dev/null
+	@${DVIPS} bookvol9.dvi 2>/dev/null
+	@${PS2PDF} bookvol9.ps >/dev/null
+	@${RM} bookvol9.aux bookvol9.dvi bookvol9.log bookvol9.ps \
+               bookvol9.idx bookvol9.tex
+
+bookvol10:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol10.pamphlet >bookvol10.tex)
+	@${LATEX} bookvol10.tex
+	@${LATEX} bookvol10.tex >/dev/null
+	@${DVIPS} bookvol10.dvi 2>/dev/null
+	@${PS2PDF} bookvol10.ps >/dev/null
+	@${RM} bookvol10.aux bookvol10.dvi bookvol10.log bookvol10.ps \
+	       bookvol10.idx bookvol10.tex
+
+bookvol11:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol11.pamphlet >bookvol11.tex)
+	@${LATEX} bookvol11.tex
+	@${LATEX} bookvol11.tex >/dev/null
+	@${DVIPS} bookvol11.dvi 2>/dev/null
+	@${PS2PDF} bookvol11.ps >/dev/null
+	@${RM} bookvol11.aux bookvol11.dvi bookvol11.log bookvol11.ps \
+	       bookvol11.idx bookvol11.tex
+
+bookvol12:
+	@(export AXIOM=${AXIOM} && \
+	  ${WEAVE} -delay bookvol12.pamphlet >bookvol12.tex)
+	@${LATEX} bookvol12.tex
+	@${LATEX} bookvol12.tex >/dev/null
+	@${DVIPS} bookvol12.dvi 2>/dev/null
+	@${PS2PDF} bookvol12.ps >/dev/null
+	@${RM} bookvol12.aux bookvol12.dvi bookvol12.log bookvol12.ps \
+	       bookvol12.idx bookvol12.tex
+
+
diff --git a/books/axiom.sty b/books/axiom.sty
new file mode 100755
index 0000000..3581b97
--- /dev/null
+++ b/books/axiom.sty
@@ -0,0 +1,1026 @@
+% axiom.sty -- LaTeX support for Axiom
+% DON'T edit this file!  Use src/doc/axiom.sty.pamphlet instead.
+
+\usepackage{alltt}
+
+\newenvironment{chunk}[1]{%   we need the chunkname as an argument
+\noindent%                    make sure we are in column 1
+{\small $<<${#1}$>>=$}%       <<some random string>>=
+\begin{alltt}%                use the verbatim
+\small}%                      with a small font
+{\end{alltt}%                 the end{chunk} ends the verbatim
+\par{}%                       we add a newline
+\noindent{}%                  start in column 1
+@%                            put an @
+\par%                         and a newline
+\normalsize}%                 and return to the rest of the document
+
+{\obeyspaces\AtBeginDocument{\global\let =\ }} % from texbook, p 381
+\def\nwopt@nomargintag{\let\nwmargintag=\@gobble}
+\def\nwopt@margintag{%
+  \def\nwmargintag##1{\leavevmode\llap{##1\kern\nwmarginglue\kern\codemargin}}}
+\def\nwopt@margintag{%
+  \def\nwmargintag##1{\leavevmode\kern-\codemargin\nwthemargintag{##1}\kern\codemargin}}
+\def\nwthemargintag#1{\llap{#1\kern\nwmarginglue}}
+\nwopt@margintag
+\newdimen\nwmarginglue
+\nwmarginglue=0.3in
+\def\nwtagstyle{\footnotesize\Rm}
+% make \hsize in code sufficient for 88 columns
+\setbox0=\hbox{\tt m}
+\newdimen\codehsize
+\codehsize=91\wd0 % 88 columns wasn't enough; I don't know why
+\newdimen\codemargin
+\codemargin=0pt
+\newdimen\nwdefspace
+\nwdefspace=\codehsize
+% need to use \textwidth in {\LaTeX} to handle styles with
+% non-standard margins (David Bruce).  Don't know why we sometimes
+% wanted \hsize.  27 August 1997.
+%% \advance\nwdefspace by -\hsize\relax
+\ifx\textwidth\undefined
+  \advance\nwdefspace by -\hsize\relax
+\else
+  \advance\nwdefspace by -\textwidth\relax
+\fi
+\chardef\other=12
+\def\setupcode{%
+  \chardef\\=`\\
+  \chardef\{=`\{
+  \chardef\}=`\}
+  \catcode`\$=\other
+  \catcode`\&=\other
+  \catcode`\#=\other
+  \catcode`\%=\other
+  \catcode`\~=\other
+  \catcode`\_=\other
+  \catcode`\^=\other
+  \catcode`\"=\other    % fixes problem with german.sty
+  \obeyspaces\Tt
+}
+\let\nwlbrace=\{
+\let\nwrbrace=\}
+\def\nwendquote{\relax\ifhmode\spacefactor=1000 \fi}
+{\catcode`\^^M=\active % make CR an active character
+  \gdef\newlines{\catcode`\^^M=\active % make CR an active character
+         \def^^M{\par\startline}}%
+  \gdef\eatline#1^^M{\relax}%
+}
+%%% DON'T   \gdef^^M{\par\startline}}% in case ^^M appears in a \write
+\def\startline{\noindent\hskip\parindent\ignorespaces}
+\def\nwnewline{\ifvmode\else\hfil\break\leavevmode\hbox{}\fi}
+\def\setupmodname{%
+  \catcode`\$=3
+  \catcode`\&=4
+  \catcode`\#=6
+  \catcode`\%=14
+  \catcode`\~=13
+  \catcode`\_=8
+  \catcode`\^=7
+  \catcode`\ =10
+  \catcode`\^^M=5
+  \let\{\nwlbrace
+  \let\}\nwrbrace
+  % bad news --- don't know what catcode to give "
+  \Rm}
+\def\LA{\begingroup\maybehbox\bgroup\setupmodname\It$\langle$}
+\def\RA{\/$\rangle$\egroup\endgroup}
+\def\code{\leavevmode\begingroup\setupcode\newlines}
+\def\edoc{\endgroup}
+\let\maybehbox\relax
+\newbox\equivbox
+\setbox\equivbox=\hbox{$\equiv$}
+\newbox\plusequivbox
+\setbox\plusequivbox=\hbox{$\mathord{+}\mathord{\equiv}$}
+% \moddef can't have an argument because there might be \code...\edoc
+\def\moddef{\leavevmode\kern-\codemargin\LA}
+\def\endmoddef{\RA\ifmmode\equiv\else\unhcopy\equivbox\fi
+               \nobreak\hfill\nobreak}
+\def\plusendmoddef{\RA\ifmmode\mathord{+}\mathord{\equiv}\else\unhcopy\plusequivbox\fi
+               \nobreak\hfill\nobreak}
+\def\chunklist{%
+\errhelp{I changed \chunklist to \nowebchunks.  
+I'll try to avoid such incompatible changes in the future.}%
+\errmessage{Use \string\nowebchunks\space instead of \string\chunklist}}
+\def\nowebchunks{\message{<Warning: You need noweave -x to use \string\nowebchunks>}}
+\def\nowebindex{\message{<Warning: You need noweave -index to use \string\nowebindex>}}
+% here is support for the new-style (capitalized) font-changing commands
+% thanks to Dave Love
+\ifx\documentstyle\undefined
+  \let\Rm=\rm \let\It=\it \let\Tt=\tt       % plain
+\else\ifx\selectfont\undefined
+  \let\Rm=\rm \let\It=\it \let\Tt=\tt       % LaTeX OFSS
+\else                                       % LaTeX NFSS
+  \def\Rm{\reset@font\rm}
+  \def\It{\reset@font\it}
+  \def\Tt{\reset@font\tt}
+  \def\Bf{\reset@font\bf}
+\fi\fi
+\ifx\reset@font\undefined \let\reset@font=\relax \fi
+\def\noweboptions#1{%
+  \def\@nwoptionlist{#1}%
+  \@for\@nwoption:=\@nwoptionlist\do{%
+    \@ifundefined{nwopt@\@nwoption}{%
+        \@latexerr{There is no such noweb option as '\@nwoption'}\@eha}{%
+        \csname nwopt@\@nwoption\endcsname}}}
+\codemargin=10pt
+\advance\codehsize by \codemargin       % make room for indentation of code
+\advance\nwdefspace by \codemargin      % and fix adjustment for def/use
+\def\setcodemargin#1{%
+  \advance\codehsize by -\codemargin       % make room for indentation of code
+  \advance\nwdefspace by -\codemargin   % and fix adjustment for def/use
+  \codemargin=#1
+  \advance\codehsize by \codemargin       % make room for indentation of code
+  \advance\nwdefspace by \codemargin    % and fix adjustment for
+                                        % def/use
+}
+\def\nwopt@shift{%
+  \dimen@=-0.8in
+  \if@twoside                 % Values for two-sided printing:
+     \advance\evensidemargin by \dimen@
+  \else                       % Values for one-sided printing:
+     \advance\evensidemargin by \dimen@
+     \advance\oddsidemargin by \dimen@
+  \fi
+%  \advance \marginparwidth -\dimen@
+}
+\let\nwopt@noshift\@empty
+\def\nwbegincode#1{%
+  \begingroup
+    \topsep \nwcodetopsep
+    \@beginparpenalty \@highpenalty
+    \@endparpenalty -\@highpenalty
+  \@begincode }
+\def\nwendcode{\endtrivlist \endgroup \filbreak} % keeps code on 1 page
+
+\newenvironment{webcode}{%
+  \@begincode
+}{%
+  \endtrivlist}
+\def\@begincode{%
+    \trivlist \item[]%
+    \leftskip\@totalleftmargin \advance\leftskip\codemargin
+    \rightskip\hsize \advance\rightskip -\codehsize
+    \parskip\z@ \parindent\z@ \parfillskip\@flushglue
+  \linewidth\codehsize
+    \@@par
+    \def\par{\leavevmode\null \@@par \penalty\nwcodepenalty}%
+    \obeylines
+    \@noligs   \ifx\verbatim@nolig@list\undefined\else
+                 \let\do=\nw@makeother \verbatim@nolig@list \do@noligs\`
+               \fi
+    \setupcode \frenchspacing \@vobeyspaces
+  \nowebsize \setupcode
+  \let\maybehbox\mbox }
+  \newskip\nwcodetopsep \nwcodetopsep = 3pt plus 1.2pt minus 1pt
+  \let\nowebsize=\normalsize
+  \def\nwopt@tinycode{\let\nowebsize=\tiny}
+  \def\nwopt@footnotesizecode{\let\nowebsize=\footnotesize}
+  \def\nwopt@scriptsizecode{\let\nowebsize=\scriptsize}
+  \def\nwopt@smallcode{\let\nowebsize=\small}
+  \def\nwopt@normalsizecode{\let\nowebsize=\normalsize}
+  \def\nwopt@largecode{\let\nowebsize=\large}
+  \def\nwopt@Largecode{\let\nowebsize=\Large}
+  \def\nwopt@LARGEcode{\let\nowebsize=\LARGE}
+  \def\nwopt@hugecode{\let\nowebsize=\huge}
+  \def\nwopt@Hugecode{\let\nowebsize=\Huge}
+\newcount\nwcodepenalty  \nwcodepenalty=\@highpenalty
+\def\nw@makeother#1{\catcode`#1=12 }
+\def\nwbegindocs#1{\ifvmode\noindent\fi}
+\let\nwenddocs=\relax
+\let\nwdocspar=\filbreak
+\raggedbottom
+\def\code{\leavevmode\begingroup\setupcode\@vobeyspaces\obeylines}
+\let\edoc=\endgroup
+\newdimen\@original@textwidth
+\def\ps@noweb{%
+  \@original@textwidth=\textwidth
+  \let\@mkboth\@gobbletwo
+  \def\@oddfoot{}\def\@evenfoot{}%       No feet.
+  \if@twoside         % If two-sided printing.
+    \def\@evenhead{\hbox to \@original@textwidth{%
+           \Rm \thepage\qquad{\Tt\leftmark}\hfil\today}}%        Left heading.
+    \def\@oddhead{\hbox to \@original@textwidth{%
+           \Rm \today\hfil{\Tt\leftmark}\qquad\thepage}}% Right heading.
+  \else               % If one-sided printing.
+    \def\@oddhead{\hbox to \@original@textwidth{%
+           \Rm \today\hfil{\Tt\leftmark}\qquad\thepage}}% Right heading.
+    \let\@evenhead\@oddhead
+  \fi
+  \let\chaptermark\@gobble
+  \let\sectionmark\@gobble
+  \let\subsectionmark\@gobble
+  \let\subsubsectionmark\@gobble
+  \let\paragraphmark\@gobble
+  \let\subparagraphmark\@gobble
+  \def\nwfilename{\begingroup\let\do\@makeother\dospecials
+                \catcode`\{=1 \catcode`\}=2 \nw@filename}
+  \def\nw@filename##1{\endgroup\markboth{##1}{##1}\let\nw@filename=\nw@laterfilename}%
+}
+\def\nw@laterfilename#1{\endgroup\clearpage \markboth{#1}{#1}}
+\let\nwfilename=\@gobble
+\def\nwcodecomment#1{\@@par\penalty\nwcodepenalty
+    \if@firstnwcodecomment
+      \vskip\nwcodecommentsep\penalty\nwcodepenalty\@firstnwcodecommentfalse
+    \fi%
+    \hspace{-\codemargin}{%
+        \rightskip=0pt plus1in
+        \interlinepenalty\nwcodepenalty
+        \let\\\relax\footnotesize\Rm #1\@@par\penalty\nwcodepenalty}}
+\def\@nwalsodefined#1{\nwcodecomment{\@nwlangdepdef\ \nwpageprep\ \@pagesl{#1}.}}
+\def\@nwused#1{\nwcodecomment{\@nwlangdepcud\ \nwpageprep\ \@pagesl{#1}.}}
+\def\@nwnotused#1{\nwcodecomment{\@nwlangdeprtc.}}
+\def\nwoutput#1{\nwcodecomment{\@nwlangdepcwf\ {\Tt \@stripstar#1*\stripped}.}}
+\def\@stripstar#1*#2\stripped{#1}
+\providecommand{\nwprevdefptr}[1]{%
+  \mbox{$\mathord{\triangleleft}\,\mathord{\mbox{\subpageref{#1}}}$}}
+\providecommand{\nwnextdefptr}[1]{%
+  \mbox{$\mathord{\mbox{\subpageref{#1}}}\,\mathord{\triangleright}$}}
+
+\providecommand{\@nwprevnextdefs}[2]{%
+  {\nwtagstyle
+  \ifx\relax#1\else ~~\nwprevdefptr{#1}\fi
+  \ifx\relax#2\else ~~\nwnextdefptr{#2}\fi}}
+\providecommand{\@nwusesondefline}[1]{{\nwtagstyle~~(\@pagenumsl{#1})}}
+\providecommand{\@nwstartdeflinemarkup}{\nobreak\hskip 1.5em plus 1fill\nobreak}
+\providecommand{\@nwenddeflinemarkup}{\nobreak\hskip \nwdefspace minus\nwdefspace\nobreak}
+\def\nwopt@longxref{%
+  \let\nwalsodefined\@nwalsodefined
+  \let\nwused\@nwused
+  \let\nwnotused\@nwnotused
+  \let\nwprevnextdefs\@gobbletwo
+  \let\nwusesondefline\@gobble
+  \let\nwstartdeflinemarkup\relax
+  \let\nwenddeflinemarkup\relax
+}
+\def\nwopt@shortxref{%
+  \let\nwalsodefined\@gobble
+  \let\nwused\@gobble
+  \let\nwnotused\@gobble
+  \let\nwprevnextdefs\@nwprevnextdefs
+  \let\nwusesondefline\@nwusesondefline
+  \let\nwstartdeflinemarkup\@nwstartdeflinemarkup
+  \let\nwenddeflinemarkup\@nwenddeflinemarkup
+}
+\def\nwopt@noxref{%
+  \let\nwalsodefined\@gobble
+  \let\nwused\@gobble
+  \let\nwnotused\@gobble
+  \let\nwprevnextdefs\@gobbletwo
+  \let\nwusesondefline\@gobble
+  \let\nwstartdeflinemarkup\relax
+  \let\nwenddeflinemarkup\relax
+}
+\nwopt@shortxref % to hell with backward compatibility!
+\newskip\nwcodecommentsep \nwcodecommentsep=3pt plus 1pt minus 1pt
+\newif\if@firstnwcodecomment\@firstnwcodecommenttrue
+\newcount\@nwlopage\newcount\@nwhipage  % range lo..hi-1
+\newcount\@nwlosub              % subpage of lo
+\newcount\@nwhisub              % subpage of hi
+\def\@nwfirstpage#1#2#3{% subpage page xref-tag
+  \@nwlopage=#2 \@nwlosub=#1
+  \def\@nwloxreftag{#3}%
+  \advance\@nwpagecount by \@ne
+  \@nwhipage=\@nwlopage\advance\@nwhipage by \@ne }
+\def\@nwnextpage#1#2#3{% subpage page xref-tag
+  \ifnum\@nwhipage=#2 
+    \advance\@nwhipage by \@ne 
+    \advance\@nwpagecount by \@ne
+    \@nwhisub=#1 
+    \def\@nwhixreftag{#3}\else
+  \ifnum#2<\@nwlopage \advance\@nwhipage by \m@ne
+                      \ifnum\@nwhipage=\@nwlopage
+                           \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                              {\@nwloxreftag}}}%
+                      \else
+                        \count@=\@nwhipage \advance\count@ by \m@ne
+                        \ifnum\count@=\@nwlopage % consecutive pages
+                            \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                              {\@nwloxreftag}}%
+                                          \noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                                              {\@nwhixreftag}}}%
+                        \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                                \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+                                \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                                  \count@=\@nwlopage \divide\count@ by 100
+                                  \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+                                  \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                                    \multiply\@nwpagetemp by 100
+                                    \advance \@nwhipage by -\@nwpagetemp
+                                    \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                                  \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                                  \fi
+                                \fi
+                              \fi%
+                        \fi
+                      \fi%
+                      \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa\@nwfirstpage{#1}{#2}{#3}\else
+  \ifnum#2>\@nwhipage \advance\@nwhipage by \m@ne
+                      \ifnum\@nwhipage=\@nwlopage
+                           \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                              {\@nwloxreftag}}}%
+                      \else
+                        \count@=\@nwhipage \advance\count@ by \m@ne
+                        \ifnum\count@=\@nwlopage % consecutive pages
+                            \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                              {\@nwloxreftag}}%
+                                          \noexpand\noexpand\noexpand\\%
+                                             {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                                              {\@nwhixreftag}}}%
+                        \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                                \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+                                \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                                  \count@=\@nwlopage \divide\count@ by 100
+                                  \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+                                  \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                                    \multiply\@nwpagetemp by 100
+                                    \advance \@nwhipage by -\@nwpagetemp
+                                    \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                                  \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                                  \fi
+                                \fi
+                              \fi%
+                        \fi
+                      \fi%
+                      \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa\@nwfirstpage{#1}{#2}{#3}\else
+    \@nwlosub=0 \@nwhisub=0
+  \fi\fi\fi
+  }
+\newcount\@nwpagetemp
+\newcount\@nwpagecount
+\def\@nwfirstpagel#1{% label
+  \@ifundefined{r@#1}{\@warning{Reference `#1' on page \thepage \space undefined}%
+                      \nwix@cons\nw@pages{\\{\bf ??}}}{%
+    \edef\@tempa{\noexpand\@nwfirstpage\subpagepair{#1}{#1}}\@tempa}}
+\def\@nwnextpagel#1{% label
+  \@ifundefined{r@#1}{\@warning{Reference `#1' on page \thepage \space undefined}%
+                      \nwix@cons\nw@pages{\\{\bf ??}}}{%
+    \edef\@tempa{\noexpand\@nwnextpage\subpagepair{#1}{#1}}\@tempa}}
+\def\@pagesl#1{%  list of labels
+  \gdef\nw@pages{}\@nwpagecount=0
+  \def\\##1{\@nwfirstpagel{##1}\let\\=\@nwnextpagel}#1%
+  \advance\@nwhipage by \m@ne
+  \ifnum\@nwhipage=\@nwlopage
+       \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}}%
+  \else
+    \count@=\@nwhipage \advance\count@ by \m@ne
+    \ifnum\count@=\@nwlopage % consecutive pages
+        \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}%
+                      \noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                          {\@nwhixreftag}}}%
+    \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+            \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+            \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+              \count@=\@nwlopage \divide\count@ by 100
+              \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+              \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                \multiply\@nwpagetemp by 100
+                \advance \@nwhipage by -\@nwpagetemp
+                \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \fi
+            \fi
+          \fi%
+    \fi
+  \fi%
+  \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa\def\\##1{\@nwhyperpagenum##1}%
+  \ifnum\@nwpagecount=1 \nwpageword \else \nwpagesword\fi~\commafy{\nw@pages}}
+\def\@nwhyperpagenum#1#2{\nwhyperreference{#2}{#1}}
+
+\def\@pagenumsl#1{%  list of labels -- doesn't include word `pages', commas, or `and'
+  \gdef\nw@pages{}\@nwpagecount=0
+  \def\\##1{\@nwfirstpagel{##1}\let\\=\@nwnextpagel}#1%
+  \advance\@nwhipage by \m@ne
+  \ifnum\@nwhipage=\@nwlopage
+       \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}}%
+  \else
+    \count@=\@nwhipage \advance\count@ by \m@ne
+    \ifnum\count@=\@nwlopage % consecutive pages
+        \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}%
+                      \noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                          {\@nwhixreftag}}}%
+    \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+            \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+            \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+              \count@=\@nwlopage \divide\count@ by 100
+              \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+              \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                \multiply\@nwpagetemp by 100
+                \advance \@nwhipage by -\@nwpagetemp
+                \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \fi
+            \fi
+          \fi%
+    \fi
+  \fi%
+  \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa%
+  \def\\##1{\@nwhyperpagenum##1\let\\=\@nwpagenumslrest}\nw@pages}
+\def\@nwpagenumslrest#1{~\@nwhyperpagenum#1}
+\def\subpages#1{% list of {{subpage}{page}}
+  \gdef\nw@pages{}\@nwpagecount=0
+  \def\\##1{\edef\@tempa{\noexpand\@nwfirstpage##1{}}\@tempa
+            \def\\####1{\edef\@tempa{\noexpand\@nwnextpage####1}\@tempa}}#1%
+  \advance\@nwhipage by \m@ne
+  \ifnum\@nwhipage=\@nwlopage
+       \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}}%
+  \else
+    \count@=\@nwhipage \advance\count@ by \m@ne
+    \ifnum\count@=\@nwlopage % consecutive pages
+        \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                          {\@nwloxreftag}}%
+                      \noexpand\noexpand\noexpand\\%
+                         {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                          {\@nwhixreftag}}}%
+    \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+            \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+            \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+              \count@=\@nwlopage \divide\count@ by 100
+              \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+              \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                \multiply\@nwpagetemp by 100
+                \advance \@nwhipage by -\@nwpagetemp
+                \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+              \fi
+            \fi
+          \fi%
+    \fi
+  \fi%
+  \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa\def\\##1{\@firstoftwo##1}%
+  \ifnum\@nwpagecount=1 \nwpageword \else \nwpagesword\fi~\commafy{\nw@pages}}
+\def\@nwaddrange{\advance\@nwhipage by \m@ne
+                 \ifnum\@nwhipage=\@nwlopage
+                      \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                        {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                         {\@nwloxreftag}}}%
+                 \else
+                   \count@=\@nwhipage \advance\count@ by \m@ne
+                   \ifnum\count@=\@nwlopage % consecutive pages
+                       \edef\@tempa{\noexpand\noexpand\noexpand\\%
+                                        {{\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
+                                         {\@nwloxreftag}}%
+                                     \noexpand\noexpand\noexpand\\%
+                                        {{\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}
+                                         {\@nwhixreftag}}}%
+                   \else \ifnum\@nwlopage<110 \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                           \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
+                           \ifnum\count@=\@nwlopage \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}\else
+                             \count@=\@nwlopage \divide\count@ by 100
+                             \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
+                             \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
+                               \multiply\@nwpagetemp by 100
+                               \advance \@nwhipage by -\@nwpagetemp
+                               \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                             \else \edef\@tempa{\noexpand\noexpand\noexpand\\{{\number\@nwlopage--\number\@nwhipage}{}}}%
+                             \fi
+                           \fi
+                         \fi%
+                   \fi
+                 \fi%
+                 \edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa}
+\def\nwpageword{\@nwlangdepchk}  % chunk, was page
+\def\nwpagesword{\@nwlangdepchks}  % chunk, was page
+\def\nwpageprep{\@nwlangdepin}     % in, was on
+\providecommand\nw@genericref[2]{% what to do, name of ref
+  \expandafter\nw@g@nericref\csname r@#2\endcsname#1{#2}}
+\providecommand\nw@g@nericref[3]{% control sequence, what to do, name
+  \ifx#1\relax
+    \ref{#3}% trigger the standard `undefined ref' mechanisms
+  \else
+    \expandafter#2#1.\\%
+  \fi}
+\def\nw@selectone#1#2#3\\{#1}
+\def\nw@selecttwo#1#2#3\\{#2}
+\def\nw@selectonetwo#1#2#3\\{{#1}{#2}}
+\providecommand{\subpageref}[1]{%
+  \nwhyperreference{#1}{\nw@genericref\@subpageref{#1}}}
+\def\@subpageref#1#2#3\\{%
+  \@ifundefined{2on#2}{#2}{\nwthepagenum{#1}{#2}}}
+\providecommand{\subpagepair}[1]{%  % produces {subpage}{page}
+  \@ifundefined{r@#1}%
+    {{0}{0}}%
+    {\nw@genericref\@subpagepair{#1}}}
+\def\@subpagepair#1#2#3\\{%
+  \@ifundefined{2on#2}{{0}{#2}}{{#1}{#2}}}
+\providecommand{\sublabel}[1]{%
+  \@bsphack
+  \nwblindhyperanchor{#1}%
+  \if@filesw {\let\thepage\relax
+   \def\protect{\noexpand\noexpand\noexpand}%
+   \edef\@tempa{\write\@auxout{\string
+      \newsublabel{#1}{{}{\thepage}}}}%
+   \expandafter}\@tempa
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+\providecommand{\nosublabel}[1]{%
+  \@bsphack\if@filesw {\let\thepage\relax
+   \def\protect{\noexpand\noexpand\noexpand}%
+   \edef\@tempa{\write\@auxout{\string
+      \newlabel{#1}{{0}{\thepage}}}}%
+   \expandafter}\@tempa
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+\providecommand\newsublabel{%
+  \nw@settrailers
+  \global\let\newsublabel\@newsublabel
+  \@newsublabel}
+\providecommand{\@newsublabel}[2]{%
+  \edef\this@page{\@cdr#2\@nil}%
+  \ifx\this@page\last@page\else
+    \sub@page=\z@
+  \fi
+  \edef\last@page{\this@page}
+  \advance\sub@page by \@ne
+  \ifnum\sub@page=\tw@
+    \global\@namedef{2on\this@page}{}%
+  \fi
+  \pendingsublabel{#1}%
+  \edef\@tempa##1{\noexpand\newlabel{##1}%
+    {{\number\sub@page}{\this@page}\nw@labeltrailers}}%
+  \pending@sublabels
+  \def\pending@sublabels{}}
+\providecommand\nw@settrailers{% -- won't work on first run
+  \@ifpackageloaded{nameref}%
+     {\gdef\nw@labeltrailers{{}{}{}}}%
+     {\gdef\nw@labeltrailers{}}}
+\renewcommand\nw@settrailers{% 
+  \@ifundefined{@secondoffive}%
+     {\gdef\nw@labeltrailers{}}%
+     {\gdef\nw@labeltrailers{{}{}{}}}}
+\providecommand{\nextchunklabel}[1]{%
+  \nwblindhyperanchor{#1}%   % looks slightly bogus --- nr
+  \@bsphack\if@filesw {\let\thepage\relax
+      \edef\@tempa{\write\@auxout{\string\pendingsublabel{#1}}}%
+      \expandafter}\@tempa
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+\providecommand\pendingsublabel[1]{%
+  \def\@tempa{\noexpand\@tempa}%
+  \edef\pending@sublabels{\noexpand\@tempa{#1}\pending@sublabels}}
+\def\pending@sublabels{}
+\def\last@page{\relax}
+\newcount\sub@page
+\def\@alphasubpagenum#1#2{#2\ifnum#1=0 \else\@alph{#1}\fi}
+\def\@nosubpagenum#1#2{#2}
+\def\@numsubpagenum#1#2{#2\ifnum#1=0 \else.\@arabic{#1}\fi}
+\def\nwopt@nosubpage{\let\nwthepagenum=\@nosubpagenum\nwopt@nomargintag}
+\def\nwopt@numsubpage{\let\nwthepagenum=\@numsubpagenum}
+\def\nwopt@alphasubpage{\let\nwthepagenum=\@alphasubpagenum}
+\nwopt@alphasubpage
+\newcount\@nwalph@n
+\let\@nwalph@d\@tempcnta
+\let\@nwalph@bound\@tempcntb
+\def\@nwlongalph#1{{%
+  \@nwalph@n=#1\advance\@nwalph@n by-1
+  \@nwalph@bound=26
+  \loop\ifnum\@nwalph@n<\@nwalph@bound\else
+     \advance\@nwalph@n by -\@nwalph@bound
+     \multiply\@nwalph@bound by 26
+  \repeat
+  \loop\ifnum\@nwalph@bound>1
+    \divide\@nwalph@bound by 26
+    \@nwalph@d=\@nwalph@n\divide\@nwalph@d by \@nwalph@bound
+    % d := d * bound ; n -:= d; d := d / bound --- saves a temporary
+    \multiply\@nwalph@d by \@nwalph@bound
+    \advance\@nwalph@n by -\@nwalph@d
+    \divide\@nwalph@d by \@nwalph@bound
+    \advance\@nwalph@d by 1 \@alph{\@nwalph@d}%
+  \repeat
+}}
+\newcount\nw@chunkcount
+\nw@chunkcount=\@ne
+\providecommand{\weblabel}[1]{%
+  \@bsphack
+  \nwblindhyperanchor{#1}%
+  \if@filesw {\let\thepage\relax
+   \def\protect{\noexpand\noexpand\noexpand}%
+   \edef\@tempa{\write\@auxout{\string
+      \newsublabel{#1}{{}{\number\nw@chunkcount}}}}%
+   \expandafter}\@tempa
+   \global\advance\nw@chunkcount by \@ne
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+\def\nwopt@webnumbering{%
+  \let\sublabel=\weblabel
+  \def\nwpageword{chunk}\def\nwpagesword{chunks}%
+  \def\nwpageprep{in}}
+% \nwindexdefn{printable name}{identifying label}{label of chunk}
+% \nwindexuse{printable name}{identifying label}{label of chunk}
+
+\def\nwindexdefn#1#2#3{\@auxix{\protect\nwixd}{#2}{#3}}
+\def\nwindexuse#1#2#3{\@auxix{\protect\nwixu}{#2}{#3}}
+
+\def\@auxix#1#2#3{% {marker}{id label}{subpage label}
+   \@bsphack\if@filesw {\let\nwixd\relax\let\nwixu\relax
+   \def\protect{\noexpand\noexpand\noexpand}%
+   \edef\@tempa{\write\@auxout{\string\nwixadd{#1}{#2}{#3}}}%
+   \expandafter}\@tempa
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+% \nwixadd{marker}{idlabel}{subpage label}
+\def\nwixadd#1#2#3{%
+  \@ifundefined{nwixl@#2}%
+    {\global\@namedef{nwixl@#2}{#1{#3}}}%
+    {\expandafter\nwix@cons\csname nwixl@#2\endcsname{#1{#3}}}}
+\def\@nwsubscriptident#1#2{\mbox{$\mbox{#1}_{\mathrm{\subpageref{#2}}}$}}
+\def\@nwnosubscriptident#1#2{#1}
+\def\@nwhyperident#1#2{\leavevmode\nwhyperreference{#2}{#1}}
+\def\nwopt@subscriptidents{%
+  \let\nwlinkedidentq\@nwsubscriptident
+  \let\nwlinkedidentc\@nwsubscriptident
+}
+\def\nwopt@nosubscriptidents{%
+  \let\nwlinkedidentq\@nwnosubscriptident
+  \let\nwlinkedidentc\@nwnosubscriptident
+}
+\def\nwopt@hyperidents{%
+  \let\nwlinkedidentq\@nwhyperident
+  \let\nwlinkedidentc\@nwhyperident
+}
+\def\nwopt@nohyperidents{%
+  \let\nwlinkedidentq\@nwnosubscriptident
+  \let\nwlinkedidentc\@nwnosubscriptident
+}
+\def\nwopt@subscriptquotedidents{%
+  \let\nwlinkedidentq\@nwsubscriptident
+}
+\def\nwopt@nosubscriptquotedidents{%
+  \let\nwlinkedidentq\@nwnosubscriptident
+}
+\def\nwopt@hyperquotedidents{%
+  \let\nwlinkedidentq\@nwhyperident
+}
+\def\nwopt@nohyperquotedidents{%
+  \let\nwlinkedidentq\@nwnosubscriptident
+}
+\nwopt@hyperidents
+\newcount\@commacount
+\def\commafy#1{%
+  {\nwix@listcount{#1}\@commacount=\nwix@counter
+   \let\@comma@each=\\%
+   \ifcase\@commacount\let\\=\@comma@each\or\let\\=\@comma@each\or
+     \def\\{\def\\{ \@nwlangdepand\ \@comma@each}\@comma@each}\else
+     \def\\{\def\\{, %
+                   \advance\@commacount by \m@ne
+                   \ifnum\@commacount=1 \@nwlangdepand~\fi\@comma@each}\@comma@each}\fi
+   #1}}
+\def\nwix@cons#1#2{% {list}{\marker{element}}
+  {\toks0=\expandafter{#1}\def\@tempa{#2}\toks2=\expandafter{\@tempa}%
+   \xdef#1{\the\toks0 \the\toks2 }}}
+\def\nwix@uses#1{% {label}
+  \def\nwixu{\\}\let\nwixd\@gobble\@nameuse{nwixl@#1}}
+\def\nwix@defs#1{% {label}
+  \def\nwixd{\\}\let\nwixu\@gobble\@nameuse{nwixl@#1}}
+\newcount\nwix@counter
+\def\nwix@listcount#1{% {list with \\}
+  {\count@=0
+   \def\\##1{\advance\count@ by \@ne }%
+   #1\global\nwix@counter=\count@ }}
+\def\nwix@usecount#1{\nwix@listcount{\nwix@uses{#1}}}
+\def\nwix@defcount#1{\nwix@listcount{\nwix@defs{#1}}}
+\def\nwix@id@defs#1{% index pair
+  {{\Tt \@car#1\@nil}%
+  \def\\##1{~\subpageref{##1}}\nwix@defs{\@cdr#1\@nil}}}
+\def\nwidentuses#1{% list of index pairs
+  \nwcodecomment{\@nwlangdepuss\ \let\\=\nwix@id@defs\commafy{#1}.}}
+\def\nwix@totaluses#1{% list of index pairs
+  {\count@=0
+   \def\\##1{\nwix@usecount{\@cdr##1\@nil}\advance\count@ by\nwix@counter}%
+   #1\global\nwix@counter\count@ }}
+\def\nwix@id@uses#1#2{% {ident}{label}
+  \nwix@usecount{#2}\ifnum\nwix@counter>0
+    {\advance\leftskip by \codemargin
+     \nwcodecomment{{\Tt #1}, \@nwlangdepusd\ \nwpageprep\ \@pagesl{\nwix@uses{#2}}.}}%
+  \else
+    \ifnw@hideunuseddefs\else
+      {\advance\leftskip by \codemargin \nwcodecomment{{\Tt #1}, \@nwlangdepnvu.}}%
+    \fi
+  \fi}
+\def\nwidentdefs#1{% list of index pairs
+  \ifnw@hideunuseddefs\nwix@totaluses{#1}\else\nwix@listcount{#1}\fi
+  \ifnum\nwix@counter>0
+    \nwcodecomment{\@nwlangdepdfs:}%
+    {\def\\##1{\nwix@id@uses ##1}#1}%
+  \fi}
+\newif\ifnw@hideunuseddefs\nw@hideunuseddefsfalse
+\def\nwopt@hideunuseddefs{\nw@hideunuseddefstrue}
+\def\nwopt@noidentxref{%
+  \let\nwidentdefs\@gobble
+  \let\nwidentuses\@gobble}
+\def\nw@underlinedefs{% {list with \nwixd, \nwixu}
+  \let\\=\relax\def\nw@comma{, }
+  \def\nwixd##1{\\\underline{\subpageref{##1}}\let\\\nw@comma}%
+  \def\nwixu##1{\\\subpageref{##1}\let\\\nw@comma}}
+
+\def\nw@indexline#1#2{%
+   {\indent {\Tt #1}: \nw@underlinedefs\@nameuse{nwixl@#2}\par}}
+
+\newenvironment{thenowebindex}{\parindent=-10pt \parskip=\z@ 
+        \advance\leftskip by 10pt 
+        \advance\rightskip by 0pt plus1in\par\@afterindenttrue
+    \def\\##1{\nw@indexline##1}}{}
+\def\nowebindex{%
+  \@ifundefined{nwixs@i}%
+     {\@warning{The \string\nowebindex\space is empty}}%
+     {\begin{thenowebindex}\@nameuse{nwixs@i}\end{thenowebindex}}}
+\def\nowebindex@external{%
+  {\let\nwixadds@c=\@gobble
+   \def\nwixadds@i##1{\nw@indexline##1}%
+   \def\nwixaddsx##1##2{\@nameuse{nwixadds@##1}{##2}}%
+   \begin{thenowebindex}\@input{\jobname.nwi}\end{thenowebindex}}}
+\def\nwixlogsorted#1#2{% list data
+   \@bsphack\if@filesw 
+     \toks0={#2}\immediate\write\@auxout{\string\nwixadds{#1}{\the\toks0}}
+   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
+\def\nwixadds#1#2{%
+  \@ifundefined{nwixs@#1}%
+    {\global\@namedef{nwixs@#1}{\\{#2}}}%
+    {\expandafter\nwix@cons\csname nwixs@#1\endcsname{\\{#2}}}}
+\let\nwixaddsx=\@gobbletwo
+\def\nwopt@externalindex{%
+  \ifx\nwixadds\@gobbletwo % already called
+  \else
+    \let\nwixaddsx=\nwixadds \let\nwixadds=\@gobbletwo
+    \let\nowebindex=\nowebindex@external
+    \let\nowebchunks=\nowebchunks@external
+  \fi}
+\def\nowebchunks{%
+  \@ifundefined{nwixs@c}%
+     {\@warning{The are no \string\nowebchunks}}%
+     {\begin{thenowebchunks}\@nameuse{nwixs@c}\end{thenowebchunks}}}
+\def\nowebchunks@external{%
+  {\let\nwixadds@i=\@gobble
+   \def\nwixadds@c##1{\nw@onechunk##1}%
+   \def\nwixaddsx##1##2{\@nameuse{nwixadds@##1}{##2}}%
+   \begin{thenowebchunks}\@input{\jobname.nwi}\end{thenowebchunks}}}
+    \@namedef{r@nw@notdef}{{0}{(\@nwlangdepnvd)}}
+\def\nw@chunkunderlinedefs{% {list of labels with \nwixd, \nwixu}
+  \let\\=\relax\def\nw@comma{, }
+  \def\nwixd##1{\\\underline{\subpageref{##1}}\let\\\nw@comma}%
+  \def\nwixu##1{\\\subpageref{##1}\let\\\nw@comma}}
+\def\nw@onechunk#1#2#3{% {name}{label of first definition}{list with \nwixd, \nwixu}
+  \@ifundefined{r@#2}{}{%
+    \indent\LA #1~{\nwtagstyle\subpageref{#2}}\RA 
+    \if@nwlongchunks{~\nw@chunkunderlinedefs#3}\fi\par}}
+\newenvironment{thenowebchunks}{\vskip3pt
+  \parskip=\z@\parindent=-10pt \advance\leftskip by 10pt
+  \advance\rightskip by 0pt plus10pt \@afterindenttrue
+  \def\\##1{\nw@onechunk##1}}{}
+\newif\if@nwlongchunks
+\@nwlongchunksfalse
+\let\nwopt@longchunks\@nwlongchunkstrue
+\providecommand\@nw@hyper@ref{\hyperreference} % naras
+\providecommand\@nw@hyper@anc{\blindhyperanchor} % naras
+\providecommand\@nw@hyperref@ref[2]{\hyperlink{noweb.#1}{#2}}  % nr
+\providecommand\@nw@hyperref@anc[1]{\hypertarget{noweb.#1}{\relax}}  % nr
+%%\renewcommand\@nw@hyperref@ref[2]{{#2}}  % nr
+%%\renewcommand\@nw@hyperref@anc[1]{}  % nr
+\providecommand\nwhyperreference{%
+  \@ifundefined{hyperlink}
+    {\@ifundefined{hyperreference}
+       {\global\let\nwhyperreference\@gobble}
+       {\global\let\nwhyperreference\@nw@hyper@ref}}
+    {\global\let\nwhyperreference\@nw@hyperref@ref}%
+  \nwhyperreference
+}
+
+\providecommand\nwblindhyperanchor{%
+  \@ifundefined{hyperlink}
+    {\@ifundefined{hyperreference}
+       {\global\let\nwblindhyperanchor\@gobble}
+       {\global\let\nwblindhyperanchor\@nw@hyper@anc}}
+    {\global\let\nwblindhyperanchor\@nw@hyperref@anc}%
+  \nwblindhyperanchor
+}
+\providecommand\nwanchorto{%
+  \begingroup\let\do\@makeother\dospecials
+     \catcode`\{=1 \catcode`\}=2 \nw@anchorto}
+\providecommand\nw@anchorto[1]{\endgroup\def\nw@next{#1}\nw@anchortofin}
+\providecommand\nw@anchortofin[1]{#1\footnote{See URL \texttt{\nw@next}.}}
+\let\nwanchorname\@gobble
+\newif\ifhtml
+\htmlfalse
+\let\nwixident=\relax
+\def\nwbackslash{\char92}
+\def\nwlbrace{\char123}
+\def\nwrbrace{\char125}
+\def\nwopt@english{%
+  \def\@nwlangdepdef{This definition is continued}%
+  \def\@nwlangdepcud{This code is used}%
+  \def\@nwlangdeprtc{Root chunk (not used in this document)}%
+  \def\@nwlangdepcwf{This code is written to file}%
+  \def\@nwlangdepchk{chunk}%
+  \def\@nwlangdepchks{chunks}%
+  \def\@nwlangdepin{in}%
+  \def\@nwlangdepand{and}%
+  \def\@nwlangdepuss{Uses}%
+  \def\@nwlangdepusd{used}%
+  \def\@nwlangdepnvu{never used}%
+  \def\@nwlangdepdfs{Defines}%
+  \def\@nwlangdepnvd{never defined}%
+}
+\let\nwopt@american\nwopt@english
+\def\nwopt@portuges{%
+  \def\@nwlangdepdef{Defini\c{c}\~ao continuada em}%
+  % This definition is continued
+  \def\@nwlangdepcud{C\'odigo usado em}%
+  % This code is used
+  \def\@nwlangdeprtc{Fragmento de topo (sem uso no documento)}%
+  % Root chunk (not used in this document)
+  \def\@nwlangdepcwf{Este c\'odigo foi escrito no ficheiro}%
+  % This code is written to file
+  \def\@nwlangdepchk{fragmento}%
+  % chunk
+  \def\@nwlangdepchks{fragmentos}%
+  % chunks
+  \def\@nwlangdepin{no(s)}%
+  % in
+  \def\@nwlangdepand{e}%
+  % and
+  \def\@nwlangdepuss{Usa}%
+  % Uses
+  \def\@nwlangdepusd{usado}%
+  % used
+  \def\@nwlangdepnvu{nunca usado}%
+  % never used
+  \def\@nwlangdepdfs{Define}%
+  % Defines
+  \def\@nwlangdepnvd{nunca definido}%
+  % never defined
+}
+\def\nwopt@frenchb{%
+  \def\@nwlangdepdef{Cette d\'efinition suit}%
+  % This definition is continued
+  \def\@nwlangdepcud{Ce code est employ\'e}%
+  % This code is used
+  \def\@nwlangdeprtc{Morceau racine (pas employ\'e dans ce document)}%
+  % Root chunk (not used in this document)
+  \def\@nwlangdepcwf{Ce code est \'ecrit aux fichier}%
+  % This code is written to file
+  \def\@nwlangdepchk{le morceau}%
+  % chunk
+  \def\@nwlangdepchks{les morceaux}%
+  % chunks
+  \def\@nwlangdepin{dans}%
+  % in
+  \def\@nwlangdepand{et}%
+  % and
+  \def\@nwlangdepuss{Il emploie}%
+  % Uses
+  \def\@nwlangdepusd{employ\'{e}}%
+  % used
+  \def\@nwlangdepnvu{jamais employ\'{e}}%
+  % never used
+  \def\@nwlangdepdfs{Il d\'{e}fine}%
+  % Defines
+  % Cannot use the accent here: \def\@nwlangdepnvd{jamais d\'{e}fini}%
+  \def\@nwlangdepnvd{jamais defini}%
+  % never defined
+}
+\let\nwopt@french\nwopt@frenchb
+\def\nwopt@german{%
+  \def\@nwlangdepdef{Diese Definition wird fortgesetzt}%
+  % This definition is continued
+  \def\@nwlangdepcud{Dieser Code wird benutzt}%
+  % This code is used
+  \def\@nwlangdeprtc{Hauptteil (nicht in diesem Dokument benutzt)}%
+  % Root chunk (not used in this document)
+  \def\@nwlangdepcwf{Dieser Code schreibt man zum File}%
+  % This code is written to file
+  \def\@nwlangdepchk{Teil}%
+  % chunk
+  \def\@nwlangdepchks{Teils}%
+  % chunks
+  \def\@nwlangdepin{im}%
+  % in
+  \def\@nwlangdepand{und}%
+  % and
+  \def\@nwlangdepuss{Benutztt}%
+  % Uses
+  \def\@nwlangdepusd{benutzt}%
+  % used
+  \def\@nwlangdepnvu{nicht benutzt}%
+  % never used
+  \def\@nwlangdepdfs{Definiert}%
+  % Defines
+  \def\@nwlangdepnvd{nicht definiert}%
+  % never defined
+}
+\let\nwopt@ngerman\nwopt@german
+\ifx\languagename\undefined % default is English
+  \noweboptions{english}
+\else
+  \@ifundefined{nwopt@\languagename}
+     {\noweboptions{english}}
+     {\expandafter\noweboptions\expandafter{\languagename}}
+\fi
+% Final names for the system and its components were in doubt so
+% Language is used throughout the book to specify what the system is named.
+\providecommand{\Language}{AXIOM}
+
+% HyperName was used to specify the name of the browser
+\providecommand{\HyperName}{HyperDoc}
+
+% This is nothing more than inline math mode in Tex but has additional
+% meaning within the browser.
+\providecommand{\spad}[1]{${#1}$}
+
+% This is a way to say 8th, 100th, etc.
+% We use providecommand so it doesn't clash with amsmath package
+\providecommand{\eth}[1]{{#1}-th}
+
+% add the binom function for combfunc
+\providecommand{\binom}[2]{\left(\begin{array}{c}#1\\#2\end{array}\right)}
+
+% spadcommands are the actual text that you type at the axiom prompt
+\providecommand{\spadcommand}[1]%
+{\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm }
+
+% spadgraph are the actual text that you type at the axiom prompt for draw
+\providecommand{\spadgraph}[1]%
+{\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm }
+
+%% spadsig gives the standard -> notation for signatures
+\providecommand{\spadsig}[2]{{\sf #1 $\rightarrow$ #2}}
+
+% returnType is the type signature returned by the axiom interpreter
+\providecommand{\returnType}[1]%
+{\begin{flushright}{\tt #1}\end{flushright}\vskip .1cm}
+
+%%% Axiom commands are set off in a special boxed area. 
+%%% This is used to draw a line around that boxed area.
+\providecommand\boxed[2]{%
+\begin{center}
+\begin{tabular}{|c|}
+\hline
+\begin{minipage}{#1}
+\normalsize
+{#2}
+\end{minipage}\\
+\hline
+\end{tabular}
+\end{center}}
+
+% The book begins with some introductory material that is not really
+% listed as a chapter. This creates a header similar to \chapter.
+\providecommand{\pseudoChapter}[1]%
+{\vskip .5in \noindent {\Huge{\bf #1}}\vskip .5in}
+
+% The book begins with some introductory material that is not really
+% listed as a section. This creates a header similar to \section.
+\providecommand{\pseudoSection}[1]%
+{\vskip .25in \noindent {\large{\bf #1}}\vskip .25in}
+
+% spadofFrom records the operation in the index and the domain in the index
+\providecommand{\spadopFrom}[2]{\index{library!operations!#1 @\begingroup \string\tt{} #1 \endgroup}\index{#2}``{\tt #1}''}
+
+% spadfunFrom records the function name and domain in the index
+\providecommand{\spadfunFrom}[2]{{\bf #1}\index{#1 @\begingroup \string\bf{} #1 \endgroup}\index{#2}}
+
+% These are special markers within the text for Hypertex keywords
+% They have no particular meaning in the book form.
+\providecommand{\spadfun}[1]{{\it #1}}
+\providecommand{\spadgloss}[1]{{\it #1}}
+\providecommand{\spadkey}[1]{\index{#1 @\begingroup \string\tt{} #1 \endgroup}}
+ 
+% spadtype records the domain in the index
+\providecommand{\spadtype}[1]{{\bf #1}\index{#1 @\begingroup \string\bf{} #1 \endgroup}}
+
+% This is used to create a caption on an included image
+\providecommand{\simpleCaption}[1]{\def\thefigure{\@arabic\c@figure}\caption{#1}}
+
+% This is the name of the ``glossy'' pages in the physical book.
+\providecommand{\Gallery}{\Language{} Images}
+
+% spadofFrom records the operation in the index and the domain in the index
+\providecommand{\spadopFrom}[2]{\index{library!operations!#1 @\begingroup \string\tt{} #1 \endgroup}\index{#2}``{\tt #1}''}
+
+%% typeset e.g. and i.e.
+\providecommand{\eg}{\emph{e.g.}}
+\providecommand{\ie}{\emph{i.e.}}
+
+%% Typeset in-line code.
+\providecommand{\Code}[1]{\texttt{#1}}
+
+%% Typeset a file name
+\providecommand{\File}[1]{{\itshape{#1}}}
+
+%% Typeset a tool name, e.g. Axiom
+\providecommand{\Tool}[1]{{\bfseries\sffamily{#1}}}
+\providecommand\AXIOM{\vskip\parindent\indent{\bf AXIOM}\vskip\parindent\noindent\ignorespaces}
+\providecommand\maxima{\vskip\parindent\noindent{\bf MAXIMA}\vskip\parindent\noindent\ignorespaces}
+\providecommand\yacas{\vskip\parindent\noindent{\bf YACAS}\vskip\parindent\noindent\ignorespaces}
diff --git a/books/bookvol0.pamphlet b/books/bookvol0.pamphlet
new file mode 100644
index 0000000..8de7c52
--- /dev/null
+++ b/books/bookvol0.pamphlet
@@ -0,0 +1,67732 @@
+\documentclass{book}
+%\usepackage{axiom}
+\usepackage{graphicx}
+% struggle with latex figure-floating behavior
+\renewcommand\floatpagefraction{.9}
+\renewcommand\topfraction{.9}
+\renewcommand\bottomfraction{.9}
+\renewcommand\textfraction{.1}
+\setcounter{totalnumber}{50}
+\setcounter{topnumber}{50}
+\setcounter{bottomnumber}{50}
+
+% spadcommands are the actual text that you type at the axiom prompt
+\newcommand{\spadcommand}[1]%
+{\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm }
+
+% spadgraph are the actual text that you type at the axiom prompt for draw
+\newcommand{\spadgraph}[1]%
+{\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm }
+
+% returnType is the type signature returned by the axiom interpreter
+\newcommand{\returnType}[1]%
+{\begin{flushright}{\tt #1}\end{flushright}\vskip .1cm}
+
+% spadsig gives the standard -> notation for signatures
+\newcommand{\spadsig}[2]{{\sf #1 $\rightarrow$ #2}}
+
+% The book begins with some introductory material that is not really
+% listed as a chapter. This creates a header similar to \chapter.
+\newcommand{\pseudoChapter}[1]%
+{\vskip .5in \noindent {\Large{\bf #1}}\vskip .5in}
+
+% The book begins with some introductory material that is not really
+% listed as a section. This creates a header similar to \section.
+\newcommand{\pseudoSection}[1]%
+{\vskip .25in \noindent {\large{\bf #1}}\vskip .25in}
+
+% spadofFrom records the operation in the index and the domain in the index
+\newcommand{\spadopFrom}[2]{\index{library!operations!#1 @\begingroup \string\tt{} #1 \endgroup}\index{#2}``{\tt #1}''}
+
+% spadfunFrom records the function name and domain in the index
+\newcommand{\spadfunFrom}[2]{{\bf #1}\index{#1 @\begingroup \string\bf{} #1 \endgroup}\index{#2}}
+
+% special meanings for math characters
+\newcommand{\N}{\mbox{\bbold N}}
+\newcommand{\Natural}{\mbox{\bbold N}}
+\newcommand{\Z}{\mbox{\bbold Z}}
+\newcommand{\Integer}{\mbox{\bbold Z}}
+\newcommand{\Rational}{\mbox{\bbold Q}}
+\newcommand{\Q}{\mbox{\bbold Q}}
+\newcommand{\Complex}{\mbox{\bbold C}}
+\newcommand{\C}{{\mathcal C}}
+\newcommand{\Real}{\mbox{\bbold R}}
+\newcommand{\F}{{\mathcal F}}
+\newcommand{\R}{{\mathcal R}}
+
+% draw a box around a text block
+\newcommand\boxed[2]{%
+\begin{center}
+\begin{tabular}{|c|}
+\hline
+\begin{minipage}{#1}
+\normalsize
+{#2}
+\end{minipage}\\
+\hline
+\end{tabular}
+\end{center}}
+
+\newcommand{\optArg}[1]{{{\tt [}{#1}{\tt ]}}}
+\newcommand{\argDef}[1]{{\tt ({#1})}}
+\newcommand{\funSyntax}[2]{{\bf #1}{\tt ({\small\it{#2}})}}
+\newcommand{\funArgs}[1]{{\tt ({\small\it {#1}})}\newline}
+
+\newcommand{\condata}[4]{{\bf #1} {\bf #2} {\bf #3} {\bf #4}}
+
+\def\glossaryTerm#1{{\bf #1}\index{#1}}
+\def\glossaryTermNoIndex#1{{\bf #1}}
+\def\glossarySyntaxTerm#1{{\tt #1}\index{#1}}
+\long\def\ourGloss#1#2{\par\pagebreak[3]{#1}\newline{#2}}
+\def\csch{\mathop{\rm csch}\nolimits}
+
+\def\erf{\mathop{\rm erf}\nolimits}
+
+\def\zag#1#2{
+  {{\hfill \left. {#1} \right|}
+   \over
+   {\left| {#2} \right. \hfill}
+  }
+}
+
+
+% these bitmaps are used by HyperDoc
+\newdimen\commentWidth 
+\commentWidth=11pc
+\newdimen\colGutterWidth 
+\colGutterWidth=1pc
+\newdimen\baseLeftSkip
+\baseLeftSkip=\commentWidth \advance\baseLeftSkip by \colGutterWidth
+\newcommand\ExitBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/exit.ps}\end{picture}}}
+\newcommand\ReturnBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/home.ps}\end{picture}}}
+\newcommand\HelpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/help.ps}\end{picture}}}
+\newcommand\UpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/up.ps}\end{picture}}}
+\newcommand{\tpd}[5]{{\setlength{\unitlength}{0.01in}\begin{picture}(#1,#2)(#3,#4)\special{psfile=#5}\end{picture}}}
+
+\begin{document}
+\begin{titlepage}
+\center{\includegraphics{ps/axiomfront.ps}}
+\vskip 0.1in
+\includegraphics{ps/bluebayou.ps}\\
+\vskip 0.1in
+{\Huge{The 30 Year Horizon}}
+\vskip 0.1in
+$$
+\begin{array}{lll}
+Manuel\ Bronstein      & William\ Burge   & Timothy\ Daly \\
+James\ Davenport       & Michael\ Dewar   & Martin\ Dunstan \\
+Albrecht\ Fortenbacher & Patrizia\ Gianni & Johannes\ Grabmeier \\
+Jocelyn\ Guidry        & Richard\ Jenks   & Larry\ Lambe \\
+Michael\ Monagan       & Scott\ Morrison  & William\ Sit \\
+Jonathan\ Steinbach    & Robert\ Sutor    & Barry\ Trager \\
+Stephen\ Watt          & Jim\ Wen         & Clifton\ Williamson
+\end{array}
+$$
+\center{\large{Volume 0: Axiom Jenks and Sutor}}
+\end{titlepage}
+\pagenumbering{roman}
+\tableofcontents
+\vfill
+\eject
+\setlength{\parindent}{0em}
+\setlength{\parskip}{1ex}
+{\Large{\bf New Foreword}}
+\vskip .25in
+
+On October 1, 2001 Axiom was withdrawn from the market and ended
+life as a commercial product.
+On September 3, 2002 Axiom was released under the Modified BSD
+license, including this document.
+On August 27, 2003 Axiom was released as free and open source
+software available for download from the Free Software Foundation's
+website, Savannah.
+
+Work on Axiom has had the generous support of the Center for 
+Algorithms and Interactive Scientific Computation (CAISS) at
+City College of New York. Special thanks go to Dr. Gilbert 
+Baumslag for his support of the long term goal.
+
+This document is a complete ``re-implementation'' of the original Axiom
+book by Jenks and Sutor. Virtually every line has been reviewed and
+rewritten into the new Axiom pamphlet format. Changes were made to
+reflect the new Axiom system. Additional material was added and some
+previous examples were rewritten. This is intended to be a ``living''
+document with material referenced or gathered automatically from other
+parts of the system documentation. Future plans include adding active
+examples (moving graphics, in-line command prompts) using Active-DVI.
+
+Axiom has been in existence for over thirty years. It is estimated to
+contain about three hundred man-years of research and has, as of
+September 3, 2003, 143 people listed in the credits. All of these
+people have contributed directly or indirectly to making Axiom
+available.  Axiom is being passed to the next generation. I'm looking
+forward to future milestones.
+
+With that in mind I've introduced the theme of the ``30 year horizon''.
+We must invent the tools that support the Computational Mathematician
+working 30 years from now. How will research be done when every bit of
+mathematical knowledge is online and instantly available? What happens
+when we scale Axiom by a factor of 100, giving us 1.1 million domains?
+How can we integrate theory with code? How will we integrate theorems
+and proofs of the mathematics with space-time complexity proofs and
+running code? What visualization tools are needed? How do we support
+the conceptual structures and semantics of mathematics in effective
+ways? How do we support results from the sciences? How do we teach
+the next generation to be effective Computational Mathematicians?
+
+The ``30 year horizon'' is much nearer than it appears.
+
+\vskip .25in
+%\noindent
+Tim Daly\\
+CAISS, City College of New York\\
+November 10, 2003 ((iHy))
+\vfill
+\eject
+%\noindent
+{\Large{\bf Foreword}}
+\vskip .25in
+
+You are holding in your hands an unusual book.  Winston Churchill once
+said that the empires of the future will be empires of the mind.  This
+book might hold an electronic key to such an empire.
+
+When computers were young and slow, the emerging computer science
+developed dreams of Artificial Intelligence and Automatic Theorem
+Proving in which theorems can be proved by machines instead of
+mathematicians.  Now, when computer hardware has matured and become
+cheaper and faster, there is not too much talk of putting the burden
+of formulating and proving theorems on the computer's shoulders.
+Moreover, even in those cases when computer programs do prove
+theorems, or establish counter-examples (for example, the solution of
+the four color problem, the non-existence of projective planes of
+order 10, the disproof of the Mertens conjecture), humans carry most
+of the burden in the form of programming and verification.
+
+It is the language of computer programming that has turned out to be
+the crucial instrument of productivity in the evolution of scientific
+computing.  The original Artificial Intelligence efforts gave birth to
+the first symbolic manipulation systems based on LISP.  The first
+complete symbolic manipulation or, as they are called now, computer
+algebra packages tried to imbed the development programming and
+execution of mathematical problems into a framework of familiar
+symbolic notations, operations and conventions.  In the third decade
+of symbolic computations, a couple of these early systems---REDUCE and
+MACSYMA---still hold their own among faithful users.
+
+Axiom was born in the mid-70's as a system called Scratchpad
+developed by IBM researchers.  Scratchpad/Axiom was born big---its
+original platform was an IBM mainframe 3081, and later a 3090.  The
+system was growing and learning during the decade of the 80's, and its
+development and progress influenced the field of computer algebra.
+During this period, the first commercially available computer algebra
+packages for mini and and microcomputers made their debut.  By now,
+our readers are aware of Mathematica, Maple, Derive, and Macsyma.
+These systems (as well as a few special purpose computer algebra
+packages in academia) emphasize ease of operation and standard
+scientific conventions, and come with a prepared set of mathematical
+solutions for typical tasks confronting an applied scientist or an
+engineer.  These features brought a recognition of the enormous
+benefits of computer algebra to the widest circles of scientists and
+engineers.
+
+The Scratchpad system took its time to blossom into the beautiful
+Axiom product.  There is no rival to this powerful environment in
+its scope and, most importantly, in its structure and organization.
+Axiom contains the basis for any comprehensive and elaborate
+mathematical development.  It gives the user all Foundation and
+Algebra instruments necessary to develop a computer realization of
+sophisticated mathematical objects in exactly the way a mathematician
+would do it.  Axiom is also the basis of a complete scientific
+cyberspace---it provides an environment for mathematical objects used
+in scientific computation, and the means of controlling and
+communicating between these objects.  Knowledge of only a few Axiom
+language features and operating principles is all that is required to
+make impressive progress in a given domain of interest.  The system is
+powerful.  It is not an interactive interpretive environment operating
+only in response to one line commands---it is a complete language with
+rich syntax and a full compiler.  Mathematics can be developed and
+explored with ease by the user of Axiom.  In fact, during
+Axiom's growth cycle, many detailed mathematical domains were
+constructed.  Some of them are a part of Axiom's core and are
+described in this book.  For a bird's eye view of the algebra
+hierarchy of Axiom, glance inside the book cover.
+
+The crucial strength of Axiom lies in its excellent structural
+features and unlimited expandability---it is open, modular system
+designed to support an ever growing number of facilities with minimal
+increase in structural complexity.  Its design also supports the
+integration of other computation tools such as numerical software
+libraries written in FORTRAN and C.  While Axiom is already a
+very powerful system, the prospect of scientists using the system to
+develop their own fields of Science is truly exciting---the day is
+still young for Axiom.
+
+Over the last several years Scratchpad/Axiom has scored many
+successes in theoretical mathematics, mathematical physics,
+combinatorics, digital signal processing, cryptography and parallel
+processing.  We have to confess that we enjoyed using
+Scratchpad/Axiom.  It provided us with an excellent environment for
+our research, and allowed us to solve problems intractable on other
+systems.  We were able to prove new diophantine results for $\pi$;
+establish the Grothendieck conjecture for certain classes of linear
+differential equations; study the arithmetic properties of the
+uniformization of hyperelliptic and other algebraic curves; construct
+new factorization algorithms based on formal groups; within
+Scratchpad/Axiom we were able to obtain new identities needed for
+quantum field theory (elliptic genus formula and double scaling limit
+for quantum gravity), and classify period relations for CM varieties
+in terms of hypergeometric series.
+
+The Axiom system is now supported and distributed by NAG, the group
+that is well known for its high quality software products for
+numerical and statistical computations.  The development of Axiom
+in IBM was conducted at IBM T.J. Watson Research Center at Yorktown,
+New York by a symbolic computation group headed by Richard D. Jenks.
+Shmuel Winograd of IBM was instrumental in the progress of symbolic
+research at IBM.
+
+This book opens the wonderful world of Axiom, guiding the reader
+and user through Axiom's definitions, rules, applications and
+interfaces.  A variety of fully developed areas of mathematics are
+presented as packages, and the user is well advised to take advantage
+of the sophisticated realization of familiar mathematics.  The
+Axiom book is easy to read and the Axiom system is easy to use.
+It possesses all the features required of a modern computer
+environment (for example, windowing, integration of operating system
+features, and interactive graphics).  Axiom comes with a detailed
+hypertext interface (HyperDoc), an elaborate browser, and complete
+on-line documentation.  The HyperDoc allows novices to solve their
+problems in a straightforward way, by providing menus for step-by-step
+interactive entry.
+
+The appearance of Axiom in the scientific market moves symbolic
+computing into a higher plane, where scientists can formulate their
+statements in their own language and receive computer assistance in
+their proofs.  Axiom's performance on workstations is truly
+impressive, and users of Axiom will get more from them than we, the
+early users, got from mainframes.  Axiom provides a powerful
+scientific environment for easy construction of mathematical tools and
+algorithms; it is a symbolic manipulation system, and a high
+performance numerical system, with full graphics capabilities.  We
+expect every (computer) power hungry scientist will want to take full
+advantage of Axiom.
+
+\vskip .25in
+%\noindent
+David V. Chudnovsky  \hfill             Gregory V. Chudnovsky
+\vfill
+\eject
+\pagenumbering{arabic}
+\pseudoChapter{Introduction to Axiom}
+\label{ugNewIntro}
+\section{Introduction to Axiom}
+Welcome to the world of Axiom.
+We call Axiom a scientific computation system:
+a self-contained toolbox designed to meet
+your scientific programming needs,
+from symbolics, to numerics, to graphics.
+
+This introduction is a quick overview of what Axiom offers.
+
+\subsection{Symbolic Computation}
+Axiom provides a wide range of simple commands for symbolic
+mathematical problem solving.  Do you need to solve an equation, to
+expand a series, or to obtain an integral?  If so, just ask Axiom
+to do it.
+
+Given $$\int\left({{1\over{(x^3 \  {(a+b x)}^{1/3})}}}\right)dx$$ 
+we would enter this into Axiom as:
+
+\spadcommand{integrate(1/(x**3 * (a+b*x)**(1/3)),x)}
+which would give the result:
+$$
+{\left(
+\begin{array}{@{}l}
+\displaystyle
+-{2 \ {b^2}\ {x^2}\ {\sqrt{3}}\ {\log \left({{{\root{3}\of{a}}\ {{\root{3}\of{{b 
+\  x}+ a}}^2}}+{{{\root{3}\of{a}}^2}\ {\root{3}\of{{b \  x}+ 
+a}}}+ a}\right)}}+ 
+\\
+\\
+\displaystyle
+{4 \ {b^2}\ {x^2}\ {\sqrt{3}}\ {\log \left({{{{\root{3}\of{a}}^
+2}\ {\root{3}\of{{b \  x}+ a}}}- a}\right)}}+ 
+\\
+\\
+\displaystyle
+{{12}\ {b^2}\ {x^2}\ {\arctan \left({{{2 \ {\sqrt{3}}\ {{\root{3}\of{a}}^
+2}\ {\root{3}\of{{b \  x}+ a}}}+{a \ {\sqrt{3}}}}\over{3 \  a}}\right)}}+
+ 
+\\
+\\
+\displaystyle
+{{\left({{12}\  b \  x}-{9 \  a}\right)}\ {\sqrt{3}}\ {\root{3}\of{a}}\ {{\root{3}\of{{b 
+\  x}+ a}}^2}}
+\end{array}
+\right)}\over{{18}\ {a^2}\ {x^2}\ {\sqrt{3}}\ {\root{3}\of{a}}}
+$$
+\returnType{Type: Union(Expression Integer,...)}
+Axiom provides state-of-the-art algebraic machinery to handle your
+most advanced symbolic problems.  For example, Axiom's integrator
+gives you the answer when an answer exists.  If one does not, it
+provides a proof that there is no answer.  Integration is just one of
+a multitude of symbolic operations that Axiom provides.
+
+\subsection{Numeric Computation}
+Axiom has a numerical library that includes operations for linear
+algebra, solution of equations, and special functions.  For many of
+these operations, you can select any number of floating point digits
+to be carried out in the computation.
+
+Solve $x^{49}-49x^4+9$ to 49 digits of accuracy.
+First we need to change the default output length of numbers:
+
+\spadcommand{digits(49)}
+and then we execute the command:
+
+\spadcommand{solve(x**49-49*x**4+9 = 0,1.e-49)}
+$$
+\begin{array}{@{}l}
+\displaystyle
+\left[{x = -{0.6546536706904271136718122105095984761851224331
+556}},  \right.
+\\
+\\
+\displaystyle
+\left.{x ={1.086921395653859508493939035954893289009213388763}},
+  \right.
+\\
+\\
+\displaystyle
+\left.{x ={0.654653670725527173969468606613676483536148760766
+1}}\right] 
+\end{array}
+$$
+
+
+\returnType{Type: List Equation Polynomial Float}
+The output of a computation can be converted to FORTRAN to be used
+in a later numerical computation.
+Besides floating point numbers, Axiom provides literally
+dozens of kinds of numbers to compute with.
+These range from various kinds of integers, to fractions, complex
+numbers, quaternions, continued fractions, and to numbers represented
+with an arbitrary base.
+
+What is $10$ to the $90$-th power in base $32$?
+
+\spadcommand{radix(10**90,32)}
+returns:
+
+%\noindent
+{\tt FMM3O955CSEIV0ILKH820CN3I7PICQU0OQMDOFV6TP000000000000000000 }
+\returnType{Type: RadixExpansion 32}
+
+The AXIOM numerical library can be enhanced with a
+substantial number of functions from the NAG library of numerical and
+statistical algorithms. These functions will provide coverage of a wide
+range of areas including roots of functions, Fourier transforms, quadrature,
+differential equations, data approximation, non-linear optimization, linear
+algebra, basic statistics, step-wise regression, analysis of variance,
+time series analysis, mathematical programming, and special functions.
+Contact the Numerical Algorithms Group Limited, Oxford, England.
+
+\subsection{Graphics}
+You may often want to visualize a symbolic formula or draw
+a graph from a set of numerical values.
+To do this, you can call upon the Axiom
+graphics capability.
+
+Draw $J_0(\sqrt{x^2+y^2})$ for $-20 \leq x,y \leq 20$.
+
+\spadcommand{draw(5*besselJ(0,sqrt(x**2+y**2)), x=-20..20, y=-20..20)}
+\begin{figure}[htbp]
+\includegraphics[bbllx=1, bblly=39, bburx=298, bbury=290]{ps/bessintr.ps}
+\caption{$J_0(\sqrt{x^2+y^2})$ for $-20 \leq x,y \leq 20$}
+\label{tpdhere}
+\end{figure}
+
+Graphs in Axiom are interactive objects you can manipulate with
+your mouse.  Just click on the graph, and a control panel pops up.
+Using this mouse and the control panel, you can translate, rotate,
+zoom, change the coloring, lighting, shading, and perspective on the
+picture.  You can also generate a PostScript copy of your graph to
+produce hard-copy output.
+
+\subsection{HyperDoc}
+
+\begin{figure}[htbp]
+\includegraphics[bbllx=1, bblly=1, bburx=298, bbury=290]{ps/h-root.ps}
+\caption{Hyperdoc opening menu}
+\label{fig-intro-br}
+\end{figure}
+
+HyperDoc presents you windows on the world of Axiom,
+offering on-line help, examples, tutorials, a browser, and reference
+material.  HyperDoc gives you on-line access to this document in a
+``hypertext'' format.  Words that appear in a different font (for
+example, {\tt Matrix}, {\bf factor}, and
+{\it category}) are generally mouse-active; if you click on one
+with your mouse, HyperDoc shows you a new window for that word.
+
+As another example of a HyperDoc facility, suppose that you want to
+compute the roots of $x^{49} - 49x^4 + 9$ to 49 digits (as in our
+previous example) and you don't know how to tell Axiom to do this.
+The ``basic command'' facility of HyperDoc leads the way.  Through the
+series of HyperDoc windows shown in Figure \ref{fig-intro-br} on
+page~\pageref{fig-intro-br} and the specified mouse clicks, you and
+HyperDoc generate the correct command to issue to compute the answer.
+
+\subsection{Interactive Programming }
+Axiom's interactive programming language lets you define your
+own functions.  A simple example of a user-defined function is one
+that computes the successive Legendre polynomials.  Axiom lets
+you define these polynomials in a piece-wise way.
+
+The first Legendre polynomial.
+
+\spadcommand{p(0) == 1}
+\returnType{Type: Void}
+The second Legendre polynomial.
+
+\spadcommand{p(1) == x}
+\returnType{Type: Void}
+The $n$-th Legendre polynomial for $(n > 1)$.
+
+\spadcommand{p(n) == ((2*n-1)*x*p(n-1) - (n-1) * p(n-2))/n}
+\returnType{Type: Void}
+
+In addition to letting you define simple functions like this, the
+interactive language can be used to create entire application
+packages.  All the graphs in the Axiom images section were created by
+programs written in the interactive language.
+
+The above definitions for $p$ do no computation---they simply
+tell Axiom how to compute $p(k)$ for some positive integer
+$k$.
+
+To actually get a value of a Legendre polynomial, you ask for it.
+\index{Legendre polynomials}
+
+What is the tenth Legendre polynomial?
+
+\spadcommand{p(10)}
+\begin{verbatim}
+   Compiling function p with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function p as a recurrence relation.
+\end{verbatim}
+$$
+{{{46189} \over {256}} \  {x \sp {10}}} -{{{109395} \over {256}} \  {x \sp 
+8}}+{{{45045} \over {128}} \  {x \sp 6}} -{{{15015} \over {128}} \  {x \sp 
+4}}+{{{3465} \over {256}} \  {x \sp 2}} -{{63} \over {256}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+Axiom applies the above pieces for $p$ to obtain the value
+of $p(10)$.  But it does more: it creates an optimized, compiled
+function for $p$.  The function is formed by putting the pieces
+together into a single piece of code.  By {\it compiled}, we mean that
+the function is translated into basic machine-code.  By {\it
+optimized}, we mean that certain transformations are performed on that
+code to make it run faster.  For $p$, Axiom actually
+translates the original definition that is recursive (one that calls
+itself) to one that is iterative (one that consists of a simple loop).
+
+What is the coefficient of $x^{90}$ in $p(90)$?
+
+\spadcommand{coefficient(p(90),x,90)}
+$$
+{5688265542052017822223458237426581853561497449095175} \over 
+{77371252455336267181195264} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+In general, a user function is type-analyzed and compiled on first use.
+Later, if you use it with a different kind of object, the function
+is recompiled if necessary.
+
+\subsection{Data Structures}
+
+A variety of data structures are available for interactive use.  These
+include strings, lists, vectors, sets, multisets, and hash tables.  A
+particularly useful structure for interactive use is the infinite
+stream:
+
+Create the infinite stream of derivatives of Legendre polynomials.
+
+\spadcommand{[D(p(i),x) for i in 1..]}
+$$
+\begin{array}{@{}l}
+\displaystyle
+\left[ 1, {3 \  x}, {{{{15}\over 2}\ {x^2}}-{3 \over 2}},
+ {{{{35}\over 2}\ {x^3}}-{{{15}\over 2}\  x}}, {{{{315}\over 
+8}\ {x^4}}-{{{105}\over 4}\ {x^2}}+{{15}\over 8}},  \right.
+\\
+\\
+\displaystyle
+\left.{{{{693}\over 8}\ {x^5}}-{{{315}\over 4}\ {x^3}}+{{{105}\over 
+8}\  x}}, {{{{3003}\over{16}}\ {x^6}}-{{{3465}\over{16}}\ {x^
+4}}+{{{945}\over{16}}\ {x^2}}-{{35}\over{16}}},  \right.
+\\
+\\
+\displaystyle
+\left.{{{{6435}\over{16}}\ {x^7}}-{{{9009}\over{16}}\ {x^5}}+
+{{{3465}\over{16}}\ {x^3}}-{{{315}\over{16}}\  x}},  \right.
+\\
+\\
+\displaystyle
+\left.{{{{109395}\over{128}}\ {x^8}}-{{{45045}\over{32}}\ {x^
+6}}+{{{45045}\over{64}}\ {x^4}}-{{{3465}\over{32}}\ {x^2}}+{{3
+15}\over{128}}},  \right.
+\\
+\\
+\displaystyle
+\left.{{{{230945}\over{128}}\ {x^9}}-{{{109395}\over{32}}\ {x^
+7}}+{{{135135}\over{64}}\ {x^5}}-{{{15015}\over{32}}\ {x^3}}+
+{{{3465}\over{128}}\  x}},  \ldots \right] 
+\end{array}
+$$
+\returnType{Type: Stream Polynomial Fraction Integer}
+
+
+Streams display only a few of their initial elements.  Otherwise, they
+are ``lazy'': they only compute elements when you ask for them.
+
+Data structures are an important component for building application
+software. Advanced users can represent data for applications in
+optimal fashion.  In all, Axiom offers over forty kinds of
+aggregate data structures, ranging from mutable structures (such as
+cyclic lists and flexible arrays) to storage efficient structures
+(such as bit vectors).  As an example, streams are used as the
+internal data structure for power series.
+
+What is the series expansion
+of $\log(\cot(x))$
+about $x=\pi/2$?
+%NOTE: The book has a different answer (see p6)
+
+\spadcommand{series(log(cot(x)),x = \%pi/2)}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{\log \left({{-{2 \  x}+ \pi}\over 2}\right)}+
+{{1 \over 3}\ {{\left(x -{\pi \over 2}\right)}^2}}+
+{{7 \over{90}}\ {{\left(x -{\pi \over 2}\right)}^4}}+ 
+{{{62}\over{2835}}\ {{\left(x -{\pi \over 2}\right)}^6}}+
+\\
+\\
+\displaystyle
+{{{127}\over{18900}}\ {{\left(x -{\pi \over 2}\right)}^8}}+
+{{{146}\over{66825}}\ {{\left(x -{\pi \over 2}\right)}^{10}}}+ 
+{O \left({{\left(x -{\pi \over 2}\right)}^{11}}\right)}
+\end{array}
+$$
+\returnType{Type: GeneralUnivariatePowerSeries(Expression Integer,x,pi/2)}
+
+Series and streams make no attempt to compute {\it all} their
+elements!  Rather, they stand ready to deliver elements on demand.
+
+What is the coefficient of the $50$-th
+term of this series?
+
+\spadcommand{coefficient(\%,50)}
+$$
+{44590788901016030052447242300856550965644} \over 
+{7131469286438669111584090881309360354581359130859375} 
+$$
+\returnType{Type: Expression Integer}
+
+\subsection{Mathematical Structures}
+Axiom also has many kinds of mathematical structures.  These
+range from simple ones (like polynomials and matrices) to more
+esoteric ones (like ideals and Clifford algebras).  Most structures
+allow the construction of arbitrarily complicated ``types.''
+
+Even a simple input expression can
+result in a type with several levels.
+
+\spadcommand{matrix [ [x + \%i,0], [1,-2] ]}
+$$
+\left[
+\begin{array}{cc}
+{x+i} & 0 \\ 
+1 & -2 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Complex Integer}
+
+The Axiom interpreter builds types in response to user input.
+Often, the type of the result is changed in order to be applicable to
+an operation.
+
+The inverse operation requires that elements of the above matrices
+are fractions.
+
+\spadcommand{inverse(\%)}
+$$
+\left[
+\begin{array}{cc}
+{1 \over {x+i}} & 0 \\ 
+{1 \over {{2 \  x}+{2 \  i}}} & -{1 \over 2} 
+\end{array}
+\right]
+$$
+\returnType{Type: Union(Matrix Fraction Polynomial Complex Integer,...)}
+
+\subsection{Pattern Matching}
+
+A convenient facility for symbolic computation is ``pattern
+matching.''  Suppose you have a trigonometric expression and you want
+to transform it to some equivalent form.  Use a $rule$ command to
+describe the transformation rules you \index{rule} need.  Then give
+the rules a name and apply that name as a function to your
+trigonometric expression.
+
+Introduce two rewrite rules.
+
+\spadcommand{sinCosExpandRules := rule\\
+\ \ sin(x+y) == sin(x)*cos(y) + sin(y)*cos(x)\\
+\ \  cos(x+y) == cos(x)*cos(y) - sin(x)*sin(y)\\
+\ \  sin(2*x) == 2*sin(x)*cos(x)\\
+\ \  cos(2*x) == cos(x)**2 - sin(x)**2
+}
+
+\begin{verbatim}
+   {sin(y + x) == cos(x)sin(y) + cos(y)sin(x),
+    cos(y + x) == - sin(x)sin(y) + cos(x)cos(y), 
+    sin(2x) == 2cos(x)sin(x),
+                       2         2
+    cos(2x) == - sin(x)  + cos(x) }
+\end{verbatim}
+\returnType{Type: Ruleset(Integer,Integer,Expression Integer)}
+
+Apply the rules to a simple trigonometric expression.
+
+\spadcommand{sinCosExpandRules(sin(a+2*b+c))}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{{\left(-{{\cos \left({a}\right)}\ {{\sin \left({b}\right)}^2}}-
+{2 \ {\cos \left({b}\right)}\ {\sin \left({a}\right)}\ {\sin 
+\left({b}\right)}}+{{\cos \left({a}\right)}\ {{\cos \left({b}\right)}^
+2}}\right)}\ {\sin \left({c}\right)}}- 
+\\
+\\
+\displaystyle
+{{\cos \left({c}\right)}\ {\sin \left({a}\right)}\ {{\sin \left({b}\right)}^
+2}}+{2 \ {\cos \left({a}\right)}\ {\cos \left({b}\right)}\ {\cos 
+\left({c}\right)}\ {\sin \left({b}\right)}}+ 
+\\
+\\
+\displaystyle
+{{{\cos \left({b}\right)}^2}\ {\cos \left({c}\right)}\ {\sin 
+\left({a}\right)}}
+\end{array}
+$$
+\returnType{Type: Expression Integer}
+
+
+Using input files, you can create your own library of transformation
+rules relevant to your applications, then selectively apply the rules
+you need.
+
+\subsection{Polymorphic Algorithms}
+All components of the Axiom algebra library are written in the
+Axiom library language.  This language is similar to the
+interactive language except for protocols that authors are obliged to
+follow.  The library language permits you to write ``polymorphic
+algorithms,'' algorithms defined to work in their most natural
+settings and over a variety of types.
+
+Define a system of polynomial equations $S$.
+
+\spadcommand{S := [3*x**3 + y + 1 = 0,y**2 = 4]}
+$$
+\left[
+{{y+{3 \  {x \sp 3}}+1}=0},  {{y \sp 2}=4} 
+\right]
+$$
+\returnType{Type: List Equation Polynomial Integer}
+
+Solve the system $S$ using rational number arithmetic and
+30 digits of accuracy.
+
+\spadcommand{solve(S,1/10**30)}
+$$
+\left[
+{\left[ {y=-2},  {x={{1757879671211184245283070414507} \over 
+{2535301200456458802993406410752}}} 
+\right]},
+ {\left[ {y=2},  {x=-1} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Polynomial Fraction Integer}
+
+Solve $S$ with the solutions expressed in radicals.
+
+\spadcommand{radicalSolve(S)}
+$$
+\begin{array}{@{}l}
+\displaystyle
+\left[{\left[{y = 2}, {x = - 1}\right]}, {\left[{y = 2}, 
+{x ={{-{\sqrt{- 3}}+ 1}\over 2}}\right]},  \right.
+\\
+\\
+\displaystyle
+\left.{\left[{y = 2}, {x ={{{\sqrt{- 3}}+ 1}\over 2}}\right]},
+ {\left[{y = - 2}, {x ={1 \over{\root{3}\of{3}}}}\right]},
+  \right.
+\\
+\\
+\displaystyle
+\left.{\left[{y = - 2}, {x ={{{{\sqrt{- 1}}\ {\sqrt{3}}}- 1}\over{2 
+\ {\root{3}\of{3}}}}}\right]}, {\left[{y = - 2}, {x ={{-{{\sqrt{-
+ 1}}\ {\sqrt{3}}}- 1}\over{2 \ {\root{3}\of{3}}}}}\right]}\right] 
+\end{array}
+$$
+\returnType{Type: List List Equation Expression Integer}
+
+While these solutions look very different, the results were produced
+by the same internal algorithm!  The internal algorithm actually works
+with equations over any ``field.''  Examples of fields are the
+rational numbers, floating point numbers, rational functions, power
+series, and general expressions involving radicals.
+
+\subsection{Extensibility}
+
+Users and system developers alike can augment the Axiom library,
+all using one common language.  Library code, like interpreter code,
+is compiled into machine binary code for run-time efficiency.
+
+Using this language, you can create new computational types and new
+algorithmic packages.  All library code is polymorphic, described in
+terms of a database of algebraic properties.  By following the
+language protocols, there is an automatic, guaranteed interaction
+between your code and that of colleagues and system implementers.
+\vfill\eject
+\pseudoChapter{A Technical Introduction}
+\label{ugTechIntro}
+Axiom has both an {\it interactive language} for user
+interactions and a {\it programming language} for building library
+modules.  Like Modula 2, \index{Modula 2} PASCAL, \index{PASCAL}
+FORTRAN, \index{FORTRAN} and Ada, \index{Ada} the programming language
+emphasizes strict type-checking.  Unlike these languages, types in
+Axiom are dynamic objects: they are created at run-time in
+response to user commands.
+
+Here is the idea of the Axiom programming language in a
+nutshell.  Axiom types range from algebraic ones (like
+polynomials, matrices, and power series) to data structures (like
+lists, dictionaries, and input files).  Types combine in any
+meaningful way.  You can build polynomials of matrices, matrices of
+polynomials of power series, hash tables with symbolic keys and
+rational function entries, and so on.
+
+{\it Categories} define algebraic properties to ensure mathematical
+correctness. They ensure, for example, that matrices of polynomials
+are OK, but matrices of input files are not.  Through categories,
+programs can discover that polynomials of continued fractions have a
+commutative multiplication whereas polynomials of matrices do not.
+
+Categories allow algorithms to be defined in their most natural
+setting. For example, an algorithm can be defined to solve polynomial
+equations over {\it any} field.  Likewise a greatest common divisor
+can compute the ``gcd'' of two elements from {\it any} Euclidean
+domain.  Categories foil attempts to compute meaningless ``gcds'', for
+example, of two hashtables.  Categories also enable algorithms to be
+compiled into machine code that can be run with arbitrary types.
+
+The Axiom interactive language is oriented towards ease-of-use.
+The Axiom interpreter uses type-inferencing to deduce the type
+of an object from user input.  Type declarations can generally be
+omitted for common types in the interactive language.
+
+So much for the nutshell.
+Here are these basic ideas described by ten design principles:
+
+\subsection{Types are Defined by Abstract Datatype Programs}
+
+Basic types are called {\it domains of computation}, or,
+simply, {\it domains.}
+\index{domain}
+Domains are defined by Axiom programs of the form:
+
+\begin{verbatim}
+Name(...): Exports == Implementation
+\end{verbatim}
+
+Each domain has a capitalized {\tt Name} that is used to refer to the
+class of its members.  For example, {\tt Integer} denotes ``the
+class of integers,'' {\tt Float}, ``the class of floating point
+numbers,'' and {\tt String}, ``the class of strings.''
+
+The ``{\tt ...}'' part following {\tt Name} lists zero or more
+parameters to the constructor. Some basic ones like {\tt Integer} take
+no parameters.  Others, like {\tt Matrix}, {\tt Polynomial} and 
+{\tt List}, take a single parameter that again must be a domain.  For
+example, {\tt Matrix(Integer)} denotes ``matrices over the integers,''
+{\tt Polynomial (Float)} denotes ``polynomial with floating point
+coefficients,'' and {\tt List (Matrix (Polynomial (Integer)))} denotes
+``lists of matrices of polynomials over the integers.''  There is no
+restriction on the number or type of parameters of a domain
+constructor.
+
+SquareMatrix(2,Integer) is an example of a domain constructor that accepts
+both a particular data value as well as an integer. In this case the
+number 2 specifies the number of rows and columns the square matrix
+will contain. Elements of the matricies are integers.
+
+The {\tt Exports} part specifies operations for creating and
+manipulating objects of the domain.  For example, type
+{\tt Integer} exports constants $0$ and $1$, and
+operations \spadopFrom{+}{Integer}, \spadopFrom{-}{Integer}, and
+\spadopFrom{*}{Integer}.  While these operations are common, others
+such as \spadfunFrom{odd?}{Integer} and \spadfunFrom{bit?}{Integer}
+are not. In addition the Exports section can contain symbols that
+represent properties that can be tested. For example, the Category
+{\tt EntireRing} has the symbol {\tt noZeroDivisors} which asserts
+that if a product is zero then one of the factors must be zero.
+
+The {\tt Implementation} part defines functions that implement the
+exported operations of the domain.  These functions are frequently
+described in terms of another lower-level domain used to represent the
+objects of the domain. Thus the operation of adding two vectors of
+real numbers can be described and implemented using the addition
+operation from {\tt Float}. 
+
+\subsection{The Type of Basic Objects is a Domain or Subdomain}
+
+Every Axiom object belongs to a {\it unique} domain.  The domain
+of an object is also called its {\it type.}  Thus the integer $7$
+has type {\tt Integer} and the string {\tt "daniel"} has type
+{\tt String}.
+
+The type of an object, however, is not unique.  The type of integer
+$7$ is not only {\tt Integer} but {\tt NonNegativeInteger},
+{\tt PositiveInteger}, and possibly, in general, any other
+``subdomain'' of the domain {\tt Integer}.  A {\it subdomain}
+\index{subdomain} is a domain with a ``membership predicate''.
+{\tt PositiveInteger} is a subdomain of {\tt Integer} with the
+predicate ``is the integer $> 0$?''.
+
+Subdomains with names are defined by abstract datatype programs
+similar to those for domains.  The {\it Export} part of a subdomain,
+however, must list a subset of the exports of the domain.  The {\tt
+Implementation} part optionally gives special definitions for
+subdomain objects.
+
+\subsection{Domains Have Types Called Categories}
+
+Domain and subdomains in Axiom are themselves objects that have
+types.  The type of a domain or subdomain is called a {\it category}.
+\index{category} Categories are described by programs of the form:
+
+\begin{verbatim}
+Name(...): Category == Exports
+\end{verbatim}
+The type of every category is the distinguished symbol {\tt Category.}
+The category {\tt Name} is used to designate the class of domains of
+that type.  For example, category {\tt Ring} designates the class
+of all rings.  Like domains, categories can take zero or more
+parameters as indicated by the ``{\tt ...}'' part following {\tt
+Name.}  Two examples are {\tt Module(R)} and
+{\tt MatrixCategory(R,Row,Col)}.
+
+The {\tt Exports} part defines a set of operations.  For example,
+{\tt Ring} exports the operations \spadopFrom{0}{Ring},
+\spadopFrom{1}{Ring}, \spadopFrom{+}{Ring}, \spadopFrom{-}{Ring}, and
+\spadopFrom{*}{Ring}.  Many algebraic domains such as
+{\tt Integer} and {\tt Polynomial (Float)} are rings.
+{\tt String} and {\tt List (R)} (for any domain $R$)
+are not.
+
+Categories serve to ensure the type-correctness.  The definition of
+matrices states {\tt Matrix(R: Ring)} requiring its single parameter
+$R$ to be a ring.  Thus a ``matrix of polynomials'' is allowed,
+but ``matrix of lists'' is not.
+
+Categories say nothing about representation. Domains, which are
+instances of category types, specify representations.
+
+\subsection{Operations Can Refer To Abstract Types}
+
+All operations have prescribed source and target types.  Types can be
+denoted by symbols that stand for domains, called ``symbolic
+domains.''  The following lines of Axiom code use a symbolic
+domain $R$:
+
+\begin{verbatim}
+R: Ring
+power: (R, NonNegativeInteger): R -> R
+power(x, n) == x ** n
+\end{verbatim}
+
+Line 1 declares the symbol $R$ to be a ring.  Line 2 declares the
+type of $power$ in terms of $R$.  From the definition on
+line 3, $power(3,2)$ produces 9 for $x = 3$ and $R =$
+{\tt Integer}.  Also, $power(3.0,2)$ produces $9.0$ for
+$x = 3.0$ and $R =$ {\tt Float}.
+$power("oxford",2)$ however fails since $"oxford"$ has type
+{\tt String} which is not a ring.
+
+Using symbolic domains, algorithms can be defined in their most
+natural or general setting.
+
+\subsection{Categories Form Hierarchies}
+
+Categories form hierarchies (technically, directed-acyclic graphs).  A
+simplified hierarchical world of algebraic categories is shown below.
+At the top of this world is {\tt SetCategory}, the class of
+algebraic sets.  The notions of parents, ancestors, and descendants is
+clear.  Thus ordered sets (domains of category {\tt OrderedSet})
+and rings are also algebraic sets.  Likewise, fields and integral
+domains are rings and algebraic sets.  However fields and integral
+domains are not ordered sets.
+
+\begin{verbatim}
+SetCategory +---- Ring       ---- IntegralDomain ---- Field
+            |
+            +---- Finite     ---+
+            |                    \
+            +---- OrderedSet -----+ OrderedFinite
+\end{verbatim}
+\begin{center}
+Figure 1.  A  simplified category hierarchy.
+\end{center}
+
+\subsection{Domains Belong to Categories by Assertion}
+
+A category designates a class of domains.  Which domains?  You might
+think that {\tt Ring} designates the class of all domains that
+export $0$, $1$, \spadopFrom{+}{Integer},
+\spadopFrom{-}{Integer}, and \spadopFrom{*}{Integer}.  But this is not
+so.  Each domain must {\it assert} which categories it belongs to.
+
+The {\tt Export} part of the definition for {\tt Integer} reads,
+for example:
+
+\begin{verbatim}
+Join(OrderedSet, IntegralDomain,  ...) with ...
+\end{verbatim}
+
+This definition asserts that {\tt Integer} is both an ordered set
+and an integral domain.  In fact, {\tt Integer} does not
+explicitly export constants $0$ and $1$ and operations
+\spadopFrom{+}{Ring}, \spadopFrom{-}{Ring} and \spadopFrom{*}{Ring} at
+all: it inherits them all from $Ring$!  Since
+{\tt IntegralDomain} is a descendant of $Ring$,
+{\tt Integer} is therefore also a ring.
+
+Assertions can be conditional.  For example, {\tt Complex(R)}
+defines its exports by:
+
+\begin{verbatim}
+Ring with ... if R has Field then Field ...
+\end{verbatim}
+Thus {\tt Complex(Float)} is a field but {\tt Complex(Integer)}
+is not since {\tt Integer} is not a field.
+
+You may wonder: ``Why not simply let the set of operations determine
+whether a domain belongs to a given category?''.  Axiom allows
+operation names (for example, {\bf norm}) to have very different
+meanings in different contexts.  The meaning of an operation in
+Axiom is determined by context.  By associating operations with
+categories, operation names can be reused whenever appropriate or
+convenient to do so.  As a simple example, the operation {\tt <}
+might be used to denote lexicographic-comparison in an algorithm.
+However, it is wrong to use the same {\tt <} with this definition
+of absolute-value: $$abs(x) == if\ x < 0\  then -x\ else\ x$$ Such a
+definition for {\tt abs} in Axiom is protected by context:
+argument $x$ is required to be a member of a domain of category
+{\tt OrderedSet}.
+
+\subsection{Packages Are Clusters of Polymorphic Operations}
+
+In Axiom, facilities for symbolic integration, solution of
+equations, and the like are placed in ``packages''.  A {\it package}
+\index{package} is a special kind of domain: one whose exported
+operations depend solely on the parameters of the constructor and/or
+explicit domains. Packages, unlike Domains, do not specify the
+representation.
+
+If you want to use Axiom, for example, to define some algorithms
+for solving equations of polynomials over an arbitrary field $F$,
+you can do so with a package of the form:
+
+\begin{verbatim}
+MySolve(F: Field): Exports == Implementation
+\end{verbatim}
+where {\tt Exports} specifies the {\bf solve} operations
+you wish to export from the domain and the {\tt Implementation}
+defines functions for implementing your algorithms.  Once Axiom has
+compiled your package, your algorithms can then be used for any {\tt F}:
+floating-point numbers, rational numbers, complex rational functions,
+and power series, to name a few.
+
+\subsection{The Interpreter Builds Domains Dynamically}
+
+The Axiom interpreter reads user input then builds whatever types
+it needs to perform the indicated computations.
+For example, to create the matrix
+$$M = \pmatrix{x^2+1&0\cr0&x / 2\cr}$$
+using the command:
+
+\spadcommand{M = [ [x**2+1,0],[0,x / 2] ]::Matrix(POLY(FRAC(INT)))}
+$$
+M={\left[ 
+\begin{array}{cc}
+x^2+1 & 0 \\ 
+0 & x/2
+\end{array}
+\right]}
+$$
+\returnType{Type: Matrix Polynomial Fraction Integer}
+the interpreter first loads the modules {\tt Matrix},
+{\tt Polynomial}, {\tt Fraction}, and {\tt Integer}
+from the library, then builds the {\it domain tower} ``matrices of
+polynomials of rational numbers (i.e. fractions of integers)''.
+
+You can watch the loading process by first typing 
+
+\spadcommand{)set message autoload on}
+In addition to the named
+domains above many additional domains and categories are loaded.
+Most systems are preloaded with such common types. For efficiency
+reasons the most common domains are preloaded but most (there are
+more than 1100 domains, categories, and packages) are not. Once these
+domains are loaded they are immediately available to the interpreter.
+
+Once a domain tower is built, it contains all the operations specific
+to the type. Computation proceeds by calling operations that exist in
+the tower.  For example, suppose that the user asks to square the
+above matrix.  To do this, the function \spadopFrom{*}{Matrix} from
+{\tt Matrix} is passed the matrix $M$ to compute $M * M$.  
+The function is also passed an environment containing $R$
+that, in this case, is {\tt Polynomial (Fraction (Integer))}.
+This results in the successive calling of the \spadopFrom{*}{Fraction}
+operations from {\tt Polynomial}, then from {\tt Fraction},
+and then finally from {\tt Integer}.
+
+Categories play a policing role in the building of domains.  Because
+the argument of {\tt Matrix} is required to be a {\tt Ring},
+Axiom will not build nonsensical types such as ``matrices of
+input files''.
+
+\subsection{Axiom Code is Compiled}
+
+Axiom programs are statically compiled to machine code, then
+placed into library modules.  Categories provide an important role in
+obtaining efficient object code by enabling:
+\begin{itemize}
+\item static type-checking at compile time;
+\item fast linkage to operations in domain-valued parameters;
+\item optimization techniques to be used for partially specified types
+(operations for ``vectors of $R$'', for instance, can be open-coded even
+though {\tt R} is unknown).
+\end{itemize}
+
+\subsection{Axiom is Extensible}
+
+Users and system implementers alike use the Axiom language to
+add facilities to the Axiom library.  The entire Axiom
+library is in fact written in the Axiom source code and
+available for user modification and/or extension.
+
+Axiom's use of abstract datatypes clearly separates the exports
+of a domain (what operations are defined) from its implementation (how
+the objects are represented and operations are defined).  Users of a
+domain can thus only create and manipulate objects through these
+exported operations.  This allows implementers to ``remove and
+replace'' parts of the library safely by newly upgraded (and, we hope,
+correct) implementations without consequence to its users.
+
+Categories protect names by context, making the same names available
+for use in other contexts.  Categories also provide for code-economy.
+Algorithms can be parameterized categorically to characterize their
+correct and most general context.  Once compiled, the same machine
+code is applicable in all such contexts.
+
+Finally, Axiom provides an automatic, guaranteed interaction
+between new and old code.  For example:
+\begin{itemize}
+\item if you write a new algorithm that requires a parameter to be a
+field, then your algorithm will work automatically with every field
+defined in the system; past, present, or future.
+\item if you introduce a new domain constructor that produces a field,
+then the objects of that domain can be used as parameters to any algorithm
+using field objects defined in the system; past, present, or future.
+\end{itemize}
+
+These are the key ideas.  For further information, we particularly
+recommend your reading chapters 11, 12, and 13, where these ideas are
+explained in greater detail.
+
+\section{Using Axiom as a Pocket Calculator}
+At the simplest level Axiom can be used as a pocket calculator
+where expressions involving numbers and operators are entered 
+directly in infix notation. In this sense the more advanced
+features of the calculator can be regarded as operators (e.g 
+{\bf sin}, {\bf cos}, etc).
+
+\subsection{Basic Arithmetic}
+An example of this might be to calculate the cosine of 2.45 (in radians).
+To do this one would type:
+
+\spadcommand{cos 2.45}
+$$
+-{0.7702312540 473073417} 
+$$
+\returnType{Type: Float}
+
+Before proceeding any further it would be best to explain the previous 
+three lines. Firstly the text ``(1) {\tt ->} '' is part of the prompt that the
+Axiom system provides when in interactive mode. The full prompt has other 
+text preceding this but it is not relevant here. The number in parenthesis
+is the step number of the input which may be used to refer to the 
+{\sl results} of previous calculations. The step number appears at the start
+of the second line to tell you which step the result belongs to. Since the
+interpreter probably loaded numberous libraries to calculate the result given
+above and listed each one in the prcess, there could easily be several pages
+of text between your input and the answer.
+
+The last line contains the type of the result. The type {\tt Float} is used
+to represent real numbers of arbitrary size and precision (where the user is
+able to define how big arbitrary is -- the default is 20 digits but can be
+as large as your computer system can handle). The type of the result can help
+track down mistakes in your input if you don't get the answer you expected.
+
+Other arithmetic operations such as addition, subtraction, and multiplication
+behave as expected:
+
+\spadcommand{6.93 * 4.1328}
+$$
+28.640304 
+$$
+\returnType{Type: Float}
+
+\spadcommand{6.93 / 4.1328}
+$$
+1.6768292682 926829268 
+$$
+\returnType{Type: Float}
+
+but integer division isn't quite so obvious. For example, if one types:
+
+\spadcommand{4/6}
+$$
+2 \over 3 
+$$
+\returnType{Type: Fraction Integer}
+
+a fractional result is obtained. The function used to display fractions
+attempts to produce the most readable answer. In the example:
+
+\spadcommand{4/2}
+$$
+2 
+$$
+\returnType{Type: Fraction Integer}
+
+the result is stored as the fraction 2/1 but is displayed as the integer 2.
+This fraction could be converted to type {\tt Integer} with no loss of
+information but Axiom will not do so automatically.
+
+\subsection{Type Conversion}
+To obtain the floating point value of a fraction one must convert 
+({\bf conversions} are applied by the user and 
+{\bf coercions} are applied automatically by the interpreter) the result
+to type {\tt Float} using the ``::'' operator as follows: 
+
+\spadcommand{(4.6)::Float}
+$$
+4.6 
+$$
+\returnType{Type: Float}
+
+Although Axiom can convert this back to a fraction it might not be the
+same fraction you started with as due to rounding errors. For example, the
+following conversion appears to be without error but others might not:
+
+\spadcommand{\%::Fraction Integer}
+$$
+{23} \over 5 
+$$
+\returnType{Type: Fraction Integer}
+
+where ``\%'' represents the previous {\it result} (not the calculation).
+
+Although Axiom has the ability to work with floating-point numbers to
+a very high precision it must be remembered that calculations with these
+numbers are {\bf not} exact. Since Axiom is a computer algebra package and
+not a numerical solutions package this should not create too many problems.
+The idea is that the user should use Axiom to do all the necessary symbolic
+manipulation and only at the end should actual numerical results be extracted.
+
+If you bear in mind that Axiom appears to store expressions just as you have
+typed them and does not perform any evalutation of them unless forced to then
+programming in the system will be much easier. It means that anything you
+ask Axiom to do (within reason) will be carried out with complete accuracy.
+
+In the previous examples the ``::'' operator was used to convert values from
+one type to another. This type conversion is not possible for all values.
+For instance, it is not possible to convert the number 3.4 to an integer
+type since it can't be represented as an integer. The number 4.0 can be 
+converted to an integer type since it has no fractional part.
+
+Conversion from floating point values to integers is performed using the 
+functions {\bf round} and {\bf truncate}. The first of these rounds a 
+floating point number to the nearest integer while the other truncates
+(i.e. removes the fractional part). Both functions return the result as a
+{\bf floating point} number. To extract the fractional part of a floating
+point number use the function {\bf fractionPart} but note that the sign
+of the result depends on the sign of the argument. Axiom obtains the
+fractional partof $x$ using $x - truncate(x)$:
+
+\spadcommand{round(3.77623)}
+$$
+4.0 
+$$
+\returnType{Type: Float}
+
+\spadcommand{round(-3.77623)}
+$$
+-{4.0} 
+$$
+\returnType{Type: Float}
+
+\spadcommand{truncate(9.235)}
+$$
+9.0 
+$$
+\returnType{Type: Float}
+
+\spadcommand{truncate(-9.654)}
+$$
+-{9.0} 
+$$
+\returnType{Type: Float}
+
+\spadcommand{fractionPart(-3.77623)}
+$$
+-{0.77623} 
+$$
+\returnType{Type: Float}
+
+\subsection{Useful Functions}
+To obtain the absolute value of a number the {\bf abs} function can be used.
+This takes a single argument which is usually an integer or a floating point
+value but doesn't necessarily have to be. The sign of a value can be obtained
+via the {\bf sign} function which rturns $-1$, $0$, or $1$ depending on the 
+sign of the argument.
+
+\spadcommand{abs(4)}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{abs(-3)}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{abs(-34254.12314)}
+$$
+34254.12314 
+$$
+\returnType{Type: Float}
+
+\spadcommand{sign(-49543.2345346)}
+$$
+-1 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{sign(0)}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+\spadcommand{sign(234235.42354)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Tests on values can be done using various functions which are generally more
+efficient than using relational operators such as $=$ particularly if the 
+value is a matrix. Examples of some of these functions are:
+
+\spadcommand{positive?(-234)}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{negative?(-234)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{zero?(42)}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{one?(1)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{odd?(23)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{odd?(9.435)}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{even?(-42)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{prime?(37)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{prime?(-37)}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Some other functions that are quite useful for manipulating numerical values
+are:
+
+\begin{verbatim}
+sin(x)         Sine of x
+cos(x)         Cosine of x
+tan(x)         Tangent of x
+asin(x)        Arcsin of x
+acos(x)        Arccos of x
+atan(x)        Arctangent of x
+gcd(x,y)       Greatest common divisor of x and y
+lcm(x,y)       Lowest common multiple of x and y
+max(x,y)       Maximum of x and y
+min(x,y)       Minimum of x and y
+factorial(x)   Factorial of x
+factor(x)      Prime factors of x
+divide(x,y)    Quotient and remainder of x/y
+\end{verbatim}
+
+Some simple infix and prefix operators:
+\begin{verbatim}
++      Addition             -      Subtraction
+-      Numerical Negation   ~      Logical Negation
+/\     Conjunction (AND)    \/     Disjunction (OR)
+and    Logical AND (/\)     or     Logical OR (\/)
+not    Logical Negation     **     Exponentiation
+*      Multiplication       /      Division
+quo    Quotient             rem    Remainder
+<      less than            >      greater than
+<=     less than or equal   >=     greater than or equal
+\end{verbatim}
+
+Some useful Axiom macros:
+\begin{verbatim}
+%i              The square root of -1
+%e              The base of the natural logarithm
+%pi             Pi
+%infinity       Infinity
+%plusInfinity   Positive Infinity
+%minusInfinity  Negative Infinity
+\end{verbatim}
+
+\section{Using Axiom as a Symbolic Calculator}
+In the previous section all the examples involved numbers and simple
+functions. Also none of the expressions entered were assigned to anything.
+In this section we will move on to simple algebra (i.e. expressions involving
+symbols and other features available on more sophisticated calculators).
+
+\subsection{Expressions Involving Symbols}
+Expressions involving symbols are entered just as they are written down,
+for example:
+
+\spadcommand{xSquared := x**2}
+$$
+x \sp 2 
+$$
+\returnType{Type: Polynomial Integer}
+
+where the assignment operator ``:='' represents immediate assignment. Later
+it will be seen that this form of assignment is not always desirable and
+the use of the delayed assignment operator ``=='' will be introduced. The
+type of the result is {\tt Polynomial Integer} which is used to represent
+polynomials with integer coefficients. Some other examples along similar
+lines are:
+
+\spadcommand{xDummy := 3.21*x**2}
+$$
+{3.21} \  {x \sp 2} 
+$$
+\returnType{Type: Polynomial Float}
+
+\spadcommand{xDummy := x**2.5}
+$$
+{x \sp 2} \  {\sqrt {x}} 
+$$
+\returnType{Type: Expression Float}
+
+\spadcommand{xDummy := x**3.3}
+$$
+{x \sp 3} \  {{\root {{10}} \of {x}} \sp 3} 
+$$
+\returnType{Type: Expression Float}
+
+\spadcommand{xyDummy := x**2 - y**2}
+$$
+-{y \sp 2}+{x \sp 2} 
+$$
+\returnType{Type: Polynomial Integer}
+
+Given that we can define expressions involving symbols, how do we actually
+compute the result when the symbols are assigned values? The answer is to
+use the {\bf eval} function which takes an expression as its first argument
+followed by a list of assignments. For example, to evaluate the expressions
+{\bf XDummy} and {xyDummy} resulting from their respective assignments above
+we type:
+
+\spadcommand{eval(xDummy,x=3)}
+$$
+37.5405075985 29552193 
+$$
+\returnType{Type: Expression Float}
+
+\spadcommand{eval(xyDummy, [x=3, y=2.1])}
+$$
+4.59 
+$$
+\returnType{Type: Polynomial Float}
+
+\subsection{Complex Numbers}
+For many scientific calculations real numbers aren't sufficient and support
+for complex numbers is also required. Complex numbers are handled in an
+intuitive manner and Axiom, which uses the {\bf \%i} macro to represent
+the square root of $-1$. Thus expressions involving complex numbers are
+entered just like other expressions.
+
+\spadcommand{(2/3 + \%i)**3}
+$$
+-{{46} \over {27}}+{{1 \over 3} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+The real and imaginary parts of a complex number can be extracted using 
+the {\bf real} and {\bf imag} functions and the complex conjugate of a
+number can be obtained using {\bf conjugate}:
+
+\spadcommand{real(3 + 2*\%i)}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{imag(3+ 2*\%i)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{conjugate(3 + 2*\%i)}
+$$
+3 -{2 \  i} 
+$$
+\returnType{Type: Complex Integer}
+
+The function {\bf factor} can also be applied to complex numbers but the
+results aren't quite so obvious as for factoring integer:
+
+\spadcommand{144 + 24*\%i}
+$$
+{144}+{{24} \  i} 
+$$
+\returnType{Type: Complex Integer}
+
+\subsection{Number Representations}
+By default all numerical results are displayed in decimal with real numbers
+shown to 20 significant figures. If the integer part of a number is longer
+than 20 digits then nothing after the decimal point is shown and the integer
+part is given in full. To alter the number of digits shown the function
+{\bf digits} can be called. The result returned by this function is the
+previous setting. For example, to find the value of $\pi$ to 40 digits
+we type:
+
+\spadcommand{digits(40)}
+$$
+20 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{\%pi::Float}
+$$
+3.1415926535\ 8979323846\ 2643383279\ 502884197 
+$$
+\returnType{Type: Float}
+
+As can be seen in the example above, there is a gap after every ten digits.
+This can be changed using the {\bf outputSpacing} function where the argument
+is the number of digits to be displayed before a space is inserted. If no
+spaces are desired then use the value $0$. Two other functions controlling
+the appearance of real numbers are {\bf outputFloating} and {\bf outputFixed}.
+The former causes Axiom to display floating-point values in exponent notation
+and the latter causes it to use fixed-point notation. For example:
+
+\spadcommand{outputFloating(); \%}
+$$
+0.3141592653 5897932384 6264338327 9502884197 E 1 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputFloating(3); 0.00345}
+$$
+0.345 E -2 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputFixed(); \%}
+$$
+0.00345 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputFixed(3); \%}
+$$
+0.003 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputGeneral(); \%}
+$$
+0.00345 
+$$
+\returnType{Type: Float}
+
+Note that the semicolon ``;'' in the examples above allows several
+expressions to be entered on one line. The result of the last expression
+is displayed. remember also that the percent symbol ``\%'' is used to
+represent the result of a previous calculation.
+
+To display rational numbers in a base other than 10 the function {\bf radix}
+is used. The first argument of this function is the expression to be 
+displayed and the second is the base to be used.
+
+\spadcommand{radix(10**10,32)}
+$$
+{\rm 9A0NP00 }
+$$
+\returnType{Type: RadixExpansion 32}
+
+\spadcommand{radix(3/21,5)}
+$$
+0.{\overline {032412}} 
+$$
+\returnType{Type: RadixExpansion 5}
+
+Rational numbers can be represented as a repeated decimal expansion using
+the {\bf decimal} function or as a continued fraction using 
+{\bf continuedFraction}. Any attempt to call these functions with irrational
+values will fail.
+
+\spadcommand{decimal(22/7)}
+$$
+3.{\overline {142857}} 
+$$
+\returnType{Type: DecimalExpansion}
+
+\spadcommand{continuedFraction(6543/210)}
+$$
+{31}+ \zag{1}{6}+ \zag{1}{2}+ \zag{1}{1}+ \zag{1}{3} 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+Finally, partial fractions in compact and expanded form are available via the
+functions {\bf partialFraction} and {\bf padicFraction} respectively. The
+former takes two arguments, the first being the numerator of the fraction
+and the second being the denominator. The latter function takes a fraction
+and expands it further while the function {\bf compactFraction} does the
+reverse:
+
+\spadcommand{partialFraction(234,40)}
+$$
+6 -{3 \over {2 \sp 2}}+{3 \over 5} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+\spadcommand{padicFraction(\%)}
+$$
+6 -{1 \over 2} -{1 \over {2 \sp 2}}+{3 \over 5} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+\spadcommand{compactFraction(\%)}
+$$
+6 -{3 \over {2 \sp 2}}+{3 \over 5} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+\spadcommand{padicFraction(234/40)}
+$$
+{117} \over {20} 
+$$
+\returnType{Type: PartialFraction Fraction Integer}
+
+To extract parts of a partial fraction the function {\bf nthFractionalTerm}
+is available and returns a partial fraction of one term. To decompose this
+further the numerator can be obtained using {\bf firstNumer} and the 
+denominator with {\bf firstDenom}. The whole part of a partial fraction can
+be retrieved using {\bf wholePart} and the number of fractional parts can
+be found using the function {\bf numberOf FractionalTerms}:
+
+\spadcommand{t := partialFraction(234,40)}
+$$
+6 -{3 \over {2 \sp 2}}+{3 \over 5} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+\spadcommand{wholePart(t)}
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{numberOfFractionalTerms(t)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{p := nthFractionalTerm(t,1)}
+$$
+-{3 \over {2 \sp 2}} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+\spadcommand{firstNumer(p)}
+$$
+-3 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{firstDenom(p)}
+$$
+2 \sp 2 
+$$
+\returnType{Type: Factored Integer}
+
+\subsection{Modular Arithmetic}
+By using the type constructor {\tt PrimeField} it is possible to do 
+arithmetic modulo some prime number. For example, arithmetic module $7$
+can be performed as follows:
+
+\spadcommand{x : PrimeField 7 := 5}
+$$
+5 
+$$
+\returnType{Type: PrimeField 7}
+
+\spadcommand{x**5 + 6}
+$$
+2 
+$$
+\returnType{Type: PrimeField 7}
+
+\spadcommand{1/x}
+$$
+3 
+$$
+\returnType{Type: PrimeField 7}
+
+The first example should be read as:
+\begin{center}
+{\tt Let $x$ be of type PrimeField(7) and assign to it the value $5$}
+\end{center}
+
+Note that it is only possible to invert non-zero values if the arithmetic
+is performed modulo a prime number. Thus arithmetic modulo a non-prime
+integer is possible but the reciprocal operation is undefined and will
+generate an error. Attempting to use the {\tt PrimeField} type constructor
+with a non-prime argument will generate an error. An example of non-prime
+modulo arithmetic is:
+
+\spadcommand{y : IntegerMod 8 := 11}
+$$
+3 
+$$
+\returnType{Type: IntegerMod 8}
+
+\spadcommand{y*4 + 27}
+$$
+7 
+$$
+\returnType{Type: IntegerMod 8}
+
+Note that polynomials can be constructed in a similar way:
+
+\spadcommand{(3*a**4 + 27*a - 36)::Polynomial PrimeField 7}
+$$
+{3 \  {a \sp 4}}+{6 \  a}+6 
+$$
+\returnType{Type: Polynomial PrimeField 7}
+
+\section{General Points about Axiom}
+\subsection{Computation Without Output}
+It is sometimes desirable to enter an expression and prevent Axiom from
+displaying the result. To do this the expression should be terminated with
+a semicolon ``;''. In a previous section it was mentioned that a set of 
+expressions separated by semicolons would be evaluated and the result
+of the last one displayed. Thus if a single expression is followed by a
+semicolon no output will be produced (except for its type):
+
+\spadcommand{2 + 4*5;}
+\returnType{Type: PositiveInteger}
+
+\subsection{Accessing Earlier Results}
+The ``\%'' macro represents the result of the previous computation. The 
+``\%\%'' macro is available which takes a single integer argument. If the
+argument is positive then it refers to the step number of the calculation
+where the numbering begins from one and can be seen at the end of each
+prompt (the number in parentheses). If the argument is negative then it
+refers to previous results counting backwards from the last result. That is,
+``\%\%(-1)'' is the same as ``\%''. The value of ``\%\%(0)'' is not defined and
+will generate an error if requested.
+
+\subsection{Splitting Expressions Over Several Lines}
+Although Axiom will quite happily accept expressions that are longer than
+the width of the screen (just keep typing without pressing the {\bf Return}
+key) it is often preferable to split the expression being entered at a point
+where it would result in more readable input. To do this the underscore
+``\_'' symbol is placed before the break point and then the {\bf Return}
+key is pressed. The rest of the expression is typed on the next line,
+can be preceeded by any number of whitespace chars, for example:
+\begin{verbatim}
+2_
++_
+3
+\end{verbatim}
+$$
+5 
+$$
+\returnType{Type: PositiveInteger}
+
+The underscore symbol is an escape character and its presence alters the
+meaning of the characters that follow it. As mentions above whitespace
+following an underscore is ignored (the {\bf Return} key generates a
+whitespace character). Any other character following an underscore loses
+whatever special meaning it may have had. Thus one can create the
+identifier ``a+b'' by typing ``a\_+b'' although this might lead to confusions.
+Also note the result of the following example:
+
+\spadcommand{ThisIsAVeryLong\_\\
+VariableName}
+$$
+ThisIsAVeryLongVariableName 
+$$
+\returnType{Type: Variable ThisIsAVeryLongVariableName}
+
+\subsection{Comments and Descriptions}
+Comments and descriptions are really only of use in files of Axiom code but
+can be used when the output of an interactive session is being spooled to
+a file (via the system command {\bf )spool}). A comment begins with two
+dashes ``- -'' and continues until the end of the line. Multi-line
+comments are only possible if each individual line begins with two dashes.
+
+Descriptions are the same as comments except that the Axiom compiler will 
+include them in the object files produced and make them availabe to the
+end user for documentation purposes.
+
+A description is placed {\bf before} a calculation begins with three
+``+++'' signs and a description placed after a calculation begins with
+two plus symbols ``++''. The so-called ``plus plus'' comments are used
+within the algebra files and are processed by the compiler to add
+to the documentation. The so-called ``minus minus'' comments are ignored
+everywhere.
+
+\subsection{Control of Result Types}
+In earlier sections the type of an expression was converted to another
+via the ``::'' operator. However, this is not the only method for
+converting between types and two other operators need to be introduced
+and explained. 
+
+The first operator is ``\$'' and is used to specify the package to be
+used to calculate the result. Thus:
+
+\spadcommand{(2/3)\$Float}
+$$
+0.6666666666\ 6666666667 
+$$
+\returnType{Type: Float}
+
+tells Axiom to use the ``/'' operator from the {\tt Float} package to
+evaluate the expression $2/3$. This does not necessarily mean that the
+result will be of the same type as the domain from which the operator
+was taken. In the following example the {\bf sign} operator is taken
+from the {\tt Float} package but the result is of type {\tt Integer}.
+
+\spadcommand{sign(2.3)\$Float}
+$$
+1 
+$$
+\returnType{Type: Integer}
+
+The other operator is ``@'' which is used to tell Axiom what the desired
+type of the result of the calculation is. In most situations all three
+operators yield the same results but the example below should help 
+distinguish them.
+
+\spadcommand{(2 + 3)::String}
+$$
+\mbox{\tt "5"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{(2 + 3)@String}
+\begin{verbatim}
+An expression involving @ String actually evaluated to one of 
+   type PositiveInteger . Perhaps you should use :: String .
+\end{verbatim}
+
+\spadcommand{(2 + 3)\$String}
+\begin{verbatim}
+   The function + is not implemented in String .
+\end{verbatim}
+
+If an expression {\sl X} is converted using one of the three operators to 
+type {\sl T} the interpretations are:
+
+{\bf ::} means explicitly convert {\sl X} to type {\sl T} if possible.
+
+{\bf \$} means use the available operators for type {\sl T} to compute {\sl X}.
+
+{\bf @} means choose operators to compute {\sl X} so that the result is of
+type {\sl T}.
+
+\section{Data Structures in Axiom}
+This chapter is an overview of {\sl some} of the data structures provided
+by Axiom.
+\subsection{Lists}
+The Axiom {\tt List} type constructor is used to create homogenous lists of
+finite size. The notation for lists and the names of the functions that 
+operate over them are similar to those found in functional languages such
+as ML.
+
+Lists can be created by placing a comma separated list of values inside
+square brackets or if a list with just one element is desired then the
+function {\bf list} is available:
+
+\spadcommand{[4]}
+$$
+\left[
+4 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{list(4)}
+$$
+\left[
+4 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{[1,2,3,5,7,11]}
+$$
+\left[
+1,  2,  3,  5,  7,  {11} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The function {\bf append} takes two lists as arguments and returns the list
+consisting of the second argument appended to the first. A single element
+can be added to the front of a list using {\bf cons}:
+
+\spadcommand{append([1,2,3,5],[7,11])}
+$$
+\left[
+1,  2,  3,  5,  7,  {11} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{cons(23,[65,42,19])}
+$$
+\left[
+{23},  {65},  {42},  {19} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Lists are accessed sequentially so if Axiom is asked for the value of the
+twentieth element in the list it will move from the start of the list over
+nineteen elements before it reaches the desired element. Each element of a 
+list is stored as a node consisting of the value of the element and a pointer
+to the rest of the list. As a result the two main operations on a list are
+called {\bf first} and {\bf rest}. Both of these functions take a second
+optional argument which specifies the length of the first part of the list:
+
+\spadcommand{first([1,5,6,2,3])}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{first([1,5,6,2,3],2)}
+$$
+\left[
+1,  5 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{rest([1,5,6,2,3])}
+$$
+\left[
+5,  6,  2,  3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{rest([1,5,6,2,3],2)}
+$$
+\left[
+6,  2,  3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Other functions are {\bf empty?} which tests to see if a list contains no
+elements, {\bf member?} which tests to see if the first argument is a member
+of the second, {\bf reverse} which reverses the order of the list, {\bf sort}
+which sorts a list, and {\bf removeDuplicates} which removes any duplicates.
+The length of a list can be obtained using the ``\#'' operator.
+
+\spadcommand{empty?([7,2,-1,2])}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{member?(-1,[7,2,-1,2])}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{reverse([7,2,-1,2])}
+$$
+\left[
+2,  -1,  2,  7 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{sort([7,2,-1,2])}
+$$
+\left[
+-1,  2,  2,  7 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{removeDuplicates([1,5,3,5,1,1,2])}
+$$
+\left[
+1,  5,  3,  2 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{\#[7,2,-1,2]}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+Lists in Axiom are mutable and so their contents (the elements and the links)
+can be modified in place. Functions that operator over lists in this way have
+names ending in the symbol ``!''. For example, {\bf concat!} takes two lists
+as arguments and appends the second argument to the first (except when the
+first argument is an empty list) and {\bf setrest!} changes the link 
+emanating from the first argument to point to the second argument:
+
+\spadcommand{u := [9,2,4,7]}
+$$
+\left[
+9,  2,  4,  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{concat!(u,[1,5,42]); u}
+$$
+\left[
+9,  2,  4,  7,  1,  5,  {42} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{endOfu := rest(u,4)}
+$$
+\left[
+1,  5,  {42} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{partOfu := rest(u,2)}
+$$
+\left[
+4,  7,  1,  5,  {42} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{setrest!(endOfu,partOfu); u}
+$$
+\left[
+9,  2,  {\overline {4,  7,  1}} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+From this it can be seen that the lists returned by {\bf first} and {\bf rest}
+are pointers to the original list and {\sl not} a copy. Thus great care must
+be taken when dealing with lists in Axiom.
+
+Although the {\sl n}th element of the list {\sl l} can be obtained by 
+applying the {\bf first} function to $n-1$ applications of {\bf rest}
+to {\sl l}, Axiom provides a more useful access method in the form of
+the ``.'' operator:
+
+\spadcommand{u.3}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{u.5}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{u.6}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{first rest rest u -- Same as u.3}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{u.first}
+$$
+9 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{u(3)}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+The operation {\sl u.i} is referred to as {\sl indexing into u} or 
+{\sl elting into u}. The latter term comes from the {\bf elt} function
+which is used to extract elements (the first element of the list is at
+index $1$).
+
+\spadcommand{elt(u,4)}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+If a list has no cycles then any attempt to access an element beyond the
+end of the list will generate an error. However, in the example above there
+was a cycle starting at the third element so the access to the sixth
+element wrapped around to give the third element. Since lists are mutable it
+is possible to modify elements directly:
+
+\spadcommand{u.3 := 42; u}
+$$
+\left[
+9,  2,  {\overline {{42},  7,  1}} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Other list operations are:
+\spadcommand{L := [9,3,4,7]; \#L}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{last(L)}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{L.last}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{L.(\#L - 1)}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+Note that using the ``\#'' operator on a list with cycles causes Axiom to
+enter an infinite loop.
+
+Note that any operation on a list {\sl L} that returns a list ${\sl L}L^{'}$
+will, in general, be such that any changes to ${\sl L}L^{'}$ will have the
+side-effect of altering {\sl L}. For example:
+
+\spadcommand{m := rest(L,2)}
+$$
+\left[
+4,  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{m.1 := 20; L}
+$$
+\left[
+9,  3,  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{n := L}
+$$
+\left[
+9,  3,  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{n.2 := 99; L}
+$$
+\left[
+9,  {99},  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{n}
+$$
+\left[
+9,  {99},  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Thus the only safe way of copying lists is to copy each element from one to
+another and not use the assignment operator:
+
+\spadcommand{p := [i for i in n] -- Same as `p := copy(n)'}
+$$
+\left[
+9,  {99},  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{p.2 := 5; p}
+$$
+\left[
+9,  5,  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{n}
+$$
+\left[
+9,  {99},  {20},  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+In the previous example a new way of constructing lists was given. This is
+a powerful method which gives the reader more information about the contents
+of the list than before and which is extremely flexible. The example
+
+\spadcommand{[i for i in 1..10]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+should be read as
+
+\begin{center}
+``Using the expression {\sl i}, generate each element of the list by
+iterating the symbol {\sl i} over the range of integers [1,10]''
+\end{center}
+
+To generate the list of the squares of the first ten elements we just use:
+
+\spadcommand{[i**2 for i in 1..10]}
+$$
+\left[
+1,  4,  9,  {16},  {25},  {36},  {49},  {64},  {81},  {100} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+For more complex lists we can apply a condition to the elements that are to
+be placed into the list to obtain a list of even numbers between 0 and 11:
+
+\spadcommand{[i for i in 1..10 | even?(i)]}
+$$
+\left[
+2,  4,  6,  8,  {10} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+This example should be read as:
+\begin{center}
+``Using the expression {\sl i}, generate each element of the list
+by iterating the symbol {\sl i} over the range of integers [1,10] such that 
+{\sl i} is even''
+\end{center}
+
+The following achieves the same result:
+
+\spadcommand{[i for i in 2..10 by 2]}
+$$
+\left[
+2,  4,  6,  8,  {10} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\subsection{Segmented Lists}
+A segmented list is one in which some of the elements are ranges of values.
+The {\bf expand} function converts lists of this type into ordinary lists:
+
+\spadcommand{[1..10]}
+$$
+\left[
+{1..{10}} 
+\right]
+$$
+\returnType{Type: List Segment PositiveInteger}
+
+\spadcommand{[1..3,5,6,8..10]}
+$$
+\left[
+{1..3},  {5..5},  {6..6},  {8..{10}} 
+\right]
+$$
+\returnType{Type: List Segment PositiveInteger}
+
+\spadcommand{expand(\%)}
+$$
+\left[
+1,  2,  3,  5,  6,  8,  9,  {10} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+If the upper bound of a segment is omitted then a different type of 
+segmented list is obtained and expanding it will produce a stream (which
+will be considered in the next section):
+
+\spadcommand{[1..]}
+$$
+\left[
+{1..} 
+\right]
+$$
+\returnType{Type: List UniversalSegment PositiveInteger}
+
+\spadcommand{expand(\%)}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+\subsection{Streams}
+Streams are infinite lists which have the ability to calculate the next
+element should it be required. For example, a stream of positive integers
+and a list of prime numbers can be generated by:
+
+\spadcommand{[i for i in 1..]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10},  \ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+\spadcommand{[i for i in 1.. | prime?(i)]}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+In each case the first few elements of the stream are calculated for display
+purposes but the rest of the stream remains unevaluated. The value of items
+in a stream are only calculated when they are needed which gives rise to
+their alternative name of ``lazy lists''.
+
+Another method of creating streams is to use the {\bf generate(f,a)} function.
+This applies its first argument repeatedly onto its second to produce the
+stream $[a,f(a),f(f(a)),f(f(f(a)))\ldots]$. Given that the function
+{\bf nextPrime} returns the lowest prime number greater than its argument we
+can generate a stream of primes as follows:
+\spadcommand{generate(nextPrime,2)\$Stream Integer}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+As a longer example a stream of Fibonacci numbers will be computed. The
+Fibonacci numbers start at $1$ and each following number is the addition
+of the two numbers that precede it so the Fibonacci sequence is:
+$$1,1,2,3,5,8,\ldots$$. 
+
+Since the generation of any Fibonacci number only relies on knowing the 
+previous two numbers we can look at the series through a window of two
+elements. To create the series the window is placed at the start over
+the values $[1,1]$ and their sum obtained. The window is now shifted to 
+the right by one position and the sum placed into the empty slot of the
+window; the process is then repeated. To implement this we require a 
+function that takes a list of two elements (the current view of the window),
+adds them, and outputs the new window. The result is the function
+$[a,b]$~{\tt ->}~$[b,a+b]$:
+\spadcommand{win : List Integer -> List Integer}
+\returnType{Type: Void}
+
+\spadcommand{win(x) == [x.2, x.1 + x.2]}
+\returnType{Type: Void}
+
+\spadcommand{win([1,1])}
+$$
+\left[
+1,  2 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{win(\%)}
+$$
+\left[
+2,  3 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Thus it can be seen that by repeatedly applying {\bf win} to the {\sl results}
+of the previous invocation each element of the series is obtained. Clearly
+{\bf win} is an ideal function to construct streams using the {\bf generate}
+function:
+\spadcommand{fibs := [generate(win,[1,1])]}
+$$
+\left[
+{\left[ 1,  1 
+\right]},
+ {\left[ 1,  2 
+\right]},
+ {\left[ 2,  3 
+\right]},
+ {\left[ 3,  5 
+\right]},
+ {\left[ 5,  8 
+\right]},
+ {\left[ 8,  {13} 
+\right]},
+ {\left[ {13},  {21} 
+\right]},
+ {\left[ {21},  {34} 
+\right]},
+ {\left[ {34},  {55} 
+\right]},
+ {\left[ {55},  {89} 
+\right]},
+ \ldots 
+\right]
+$$
+\returnType{Type: Stream List Integer}
+
+This isn't quite what is wanted -- we need to extract the first element of
+each list and place that in our series:
+\spadcommand{fibs := [i.1 for i in [generate(win,[1,1])] ]}
+$$
+\left[
+1,  1,  2,  3,  5,  8,  {13},  {21},  {34},  {55},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Obtaining the 200th Fibonacci number is trivial:
+\spadcommand{fibs.200}
+$$
+280571172992510140037611932413038677189525 
+$$
+\returnType{Type: PositiveInteger}
+
+One other function of interest is {\bf complete} which expands a finite
+stream derived from an infinite one (and thus was still stored as an
+infinite stream) to form a finite stream.
+
+\subsection{Arrays, Vectors, Strings, and Bits}
+The simplest array data structure is the {\sl one-dimensional array} which
+can be obtained by applying the {\bf oneDimensionalArray} function to a list:
+\spadcommand{oneDimensionalArray([7,2,5,4,1,9])}
+$$
+\left[
+7,  2,  5,  4,  1,  9 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+One-dimensional array are homogenous (all elements must have the same type)
+and mutable (elements can be changed) like lists but unlike lists they are
+constant in size and have uniform access times (it is just as quick to read
+the last element of a one-dimensional array as it is to read the first; this
+is not true for lists).
+
+Since these arrays are mutable all the warnings that apply to lists apply to
+arrays. That is, it is possible to modify an element in a copy of an array
+and change the original:
+\spadcommand{x := oneDimensionalArray([7,2,5,4,1,9])}
+$$
+\left[
+7,  2,  5,  4,  1,  9 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{y := x}
+$$
+\left[
+7,  2,  5,  4,  1,  9 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{y.3 := 20 ; x}
+$$
+\left[
+7,  2,  {20},  4,  1,  9 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+Note that because these arrays are of fixed size the {\bf concat!} function
+cannot be applied to them without generating an error. If arrays of this 
+type are required use the {\bf FlexibleArray} constructor.
+
+One-dimensional arrays can be created using {\bf new} which specifies the size
+of the array and the initial value for each of the elements. Other operations
+that can be applied to one-dimensional arrays are {\bf map!} which applies
+a mapping onto each element, {\bf swap!} which swaps two elements and
+{\bf copyInto!(a,b,c)} which copies the array {\sl b} onto {\sl a} starting at
+position {\sl c}.
+\spadcommand{a : ARRAY1 PositiveInteger := new(10,3)}
+$$
+\left[
+3,  3,  3,  3,  3,  3,  3,  3,  3,  3 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+(note that {\tt ARRAY1} is an abbreviation for the type 
+{\tt OneDimensionalArray}.) Other types based on one-dimensional arrays are
+{\tt Vector}, {\tt String}, and {tt Bits}.
+
+\spadcommand{map!(i +-> i+1,a); a}
+$$
+\left[
+4,  4,  4,  4,  4,  4,  4,  4,  4,  4 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{b := oneDimensionalArray([2,3,4,5,6])}
+$$
+\left[
+2,  3,  4,  5,  6 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{swap!(b,2,3); b}
+$$
+\left[
+2,  4,  3,  5,  6 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{copyInto!(a,b,3)}
+$$
+\left[
+4,  4,  2,  4,  3,  5,  6,  4,  4,  4 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{a}
+$$
+\left[
+4,  4,  2,  4,  3,  5,  6,  4,  4,  4 
+\right]
+$$
+\returnType{Type: OneDimensionalArray PositiveInteger}
+
+\spadcommand{vector([1/2,1/3,1/14])}
+$$
+\left[
+{1 \over 2},  {1 \over 3},  {1 \over {14}} 
+\right]
+$$
+\returnType{Type: Vector Fraction Integer}
+
+\spadcommand{"Hello, World"}
+$$
+\mbox{\tt "Hello, World"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{bits(8,true)}
+$$
+\mbox{\tt "11111111"} 
+$$
+\returnType{Type: Bits}
+
+A vector is similar to a one-dimensional array except that if its 
+components belong to a ring then arithmetic operations are provided.
+
+\subsection{Flexible Arrays}
+Flexible arrays are designed to provide the efficiency of one-dimensional
+arrays while retaining the flexibility of lists. They are implemented by
+allocating a fixed block of storage for the array. If the array needs to
+be expanded then a larger block of storage is allocated and the contents
+of the old block are copied into the new one.
+
+There are several operations that can be applied to this type, most of
+which modify the array in place. As a result these functions all have 
+names ending in ``!''. The {\bf physicalLength} returns the actual length
+of the array as stored in memory while the {\bf physicalLength!} allows this
+value to be changed by the user.
+\spadcommand{f : FARRAY INT := new(6,1)}
+$$
+\left[
+1,  1,  1,  1,  1,  1 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{f.1:=4; f.2:=3 ; f.3:=8 ; f.5:=2 ; f}
+$$
+\left[
+4,  3,  8,  1,  2,  1 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{insert!(42,f,3); f}
+$$
+\left[
+4,  3,  {42},  8,  1,  2,  1 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{insert!(28,f,8); f}
+$$
+\left[
+4,  3,  {42},  8,  1,  2,  1,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{removeDuplicates!(f)}
+$$
+\left[
+4,  3,  {42},  8,  1,  2,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{delete!(f,5)}
+$$
+\left[
+4,  3,  {42},  8,  2,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{g:=f(3..5)}
+$$
+\left[
+{42},  8,  2 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{g.2:=7; f}
+$$
+\left[
+4,  3,  {42},  8,  2,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{insert!(g,f,1)}
+$$
+\left[
+{42},  7,  2,  4,  3,  {42},  8,  2,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{physicalLength(f)}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{physicalLength!(f,20)}
+$$
+\left[
+{42},  7,  2,  4,  3,  {42},  8,  2,  {28} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{merge!(sort!(f),sort!(g))}
+$$
+\left[
+2,  2,  2,  3,  4,  7,  7,  8,  {28},  {42},  {42},  
+{42} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+\spadcommand{shrinkable(false)\$FlexibleArray(Integer)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+There are several things to point out concerning these
+examples. First, although flexible arrays are mutable, making copies
+of these arrays creates separate entities. This can be seen by the
+fact that the modification of element {\sl b.2} above did not alter
+{\sl a}. Second, the {\bf merge!}  function can take an extra argument
+before the two arrays are merged. The argument is a comparison
+function and defaults to ``{\tt <=}'' if omitted. Lastly, 
+{\bf shrinkable} tells the system whether or not to let flexible arrays
+contract when elements are deleted from them. An explicit package
+reference must be given as in the example above.
+
+\section{Functions, Choices, and Loops}
+By now the reader should be able to construct simple one-line expressions
+involving variables and different data structures. This section builds on
+this knowledge and shows how to use iteration, make choices, and build
+functions in Axiom. At the moment it is assumed that the reader has a rough
+idea of how types are specified and constructed so that they can follow
+the examples given.
+
+From this point on most examples will be taken from input files. 
+
+\subsection{Reading Code from a File}
+Input files contain code that will be fed to the command prompt. The 
+primary different between the command line and an input file is that
+indentation matters. In an input file you can specify ``piles'' of code
+by using indentation. 
+
+The names of all input files in Axiom should end in ``.input'' otherwise
+Axiom will refuse to read them. 
+
+If an input file is named {\bf foo.input} you can feed the contents of
+the file to the command prompt (as though you typed them) by writing:
+{\bf )read foo.input}.
+
+It is good practice to start each input file with the {\bf )clear all}
+command so that all functions and variables in the current environment
+are erased. 
+\subsection{Blocks}
+The Axiom constructs that provide looping, choices, and user-defined
+functions all rely on the notion of blocks. A block is a sequence of
+expressions which are evaluated in the order that they appear except
+when it is modified by control expressions such as loops. To leave a
+block prematurely use an expression of the form:
+{\sl BoolExpr}~{\tt =>}~{\sl Expr} 
+where {\sl BoolExpr} is any Axiom expression that has type {\tt Boolean}. 
+The value and type of {\sl Expr} determines the value and type returned 
+by the block.
+
+If blocks are entered at the keyboard (as opposed to reading them from
+a text file) then there is only one way of creating them. The syntax is:
+$$( expression1 ; expression2; \ldots ; expressionN )$$
+
+In an input file a block can be constructed as above or by placing all the
+statements at the same indentation level. When indentation is used to
+indicate program structure the block is called a {\sl pile}. As an example
+of a simple block a list of three integers can be constructed using
+parentheses:
+\spadcommand{( a:=4; b:=1; c:=9; L:=[a,b,c])}
+$$
+\left[
+4,  1,  9 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Doing the same thing using piles in an input file you could type:
+\begin{verbatim}
+L :=
+  a:=4
+  b:=1
+  c:=9
+  [a,b,c]
+\end{verbatim}
+$$
+\left[
+4, 1, 9 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Since blocks have a type and a value they can be used as arguments to 
+functions or as part of other expressions. It should be pointed out that
+the following example is not recommended practice but helps to illustrate
+the idea of blocks and their ability to return values:
+\begin{verbatim}
+sqrt(4.0 +
+         a:=3.0
+         b:=1.0
+         c:=a + b
+         c
+    )
+\end{verbatim}
+$$
+2.8284271247\ 461900976 
+$$
+\returnType{Type: Float}
+
+Note that indentation is {\bf extremely} important. If the example above
+had the pile starting at ``a:='' moved left by two spaces so that the
+``a'' was under the ``('' of the first line then the interpreter would
+signal an error. Furthermore if the closing parenthesis ``)'' is moved 
+up to give
+\begin{verbatim}
+sqrt(4.0 +
+         a:=3.0
+         b:=1.0
+         c:=a + b
+         c)
+\end{verbatim}
+\begin{verbatim}
+  Line   1: sqrt(4.0 +
+           ....A
+  Error  A: Missing mate.
+  Line   2:          a:=3.0
+  Line   3:          b:=1.0
+  Line   4:          c:=a + b
+  Line   5:          c)
+           .........AB
+  Error  A: (from A up to B) Ignored.
+  Error  B: Improper syntax.
+  Error  B: syntax error at top level
+  Error  B: Possibly missing a ) 
+   5 error(s) parsing 
+\end{verbatim}
+then the parser will generate errors. If the parenthesis is shifted right 
+by several spaces so that it is in line with the ``c'' thus:
+\begin{verbatim}
+sqrt(4.0 +
+         a:=3.0
+         b:=1.0
+         c:=a + b
+         c
+         )
+\end{verbatim}
+\begin{verbatim}
+  Line   1: sqrt(4.0 +
+           ....A
+  Error  A: Missing mate.
+  Line   2:          a:=3.0
+  Line   3:          b:=1.0
+  Line   4:          c:=a + b
+  Line   5:          c
+  Line   6:          )
+           .........A
+  Error  A: (from A up to A) Ignored.
+  Error  A: Improper syntax.
+  Error  A: syntax error at top level
+  Error  A: Possibly missing a ) 
+   5 error(s) parsing 
+\end{verbatim}
+a similar error will be raised. Finally, the ``)'' must be indented by 
+at least one space relative to the sqrt thus:
+\begin{verbatim}
+sqrt(4.0 +
+         a:=3.0
+         b:=1.0
+         c:=a + b
+         c
+ )
+\end{verbatim}
+$$
+2.8284271247\ 461900976 
+$$
+\returnType{Type: Float}
+or an error will be generated.
+
+It can be seen that great care needs to be taken when constructing input
+files consisting of piles of expressions. It would seem prudent to add
+one pile at a time and check if it is acceptable before adding more,
+particularly if piles are nested. However, it should be pointed out that
+the use of piles as values for functions is not very readable and so
+perhaps the delicate nature of their interpretation should deter programmers
+from using them in these situations. Using piles should really be restricted
+to constructing functions, etc. and a small amount of rewriting can remove
+the need to use them as arguments. For example, the previous block could
+easily be implemented as:
+\begin{verbatim}
+a:=3.0
+b:=1.0
+c:=a + b
+sqrt(4.0 + c)
+\end{verbatim}
+\begin{verbatim}
+a:=3.0
+\end{verbatim}
+$$
+3.0
+$$
+\returnType{Type: Float}
+
+\begin{verbatim}
+b:=1.0
+\end{verbatim}
+$$
+1.0
+$$
+\returnType{Type: Float}
+
+\begin{verbatim}
+c:=a + b
+\end{verbatim}
+$$
+4.0
+$$
+\returnType{Type: Float}
+
+\begin{verbatim}
+sqrt(4.0 + c)
+\end{verbatim}
+$$
+2.8284271247\ 461900976
+$$
+\returnType{Type: Float}
+
+which achieves the same result and is easier to understand. Note that this
+is still a pile but it is not as fragile as the previous version.
+\subsection{Functions}
+Definitions of functions in Axiom are quite simple providing two things
+are observed. First, the type of the function must either be completely
+specified or completely unspecified. Second, the body of the function is
+assigned to the function identifier using the delayed assignment operator
+``==''.
+
+To specify the type of something the ``:'' operator is used. Thus to define
+a variable {\sl x} to be of type {\tt Fraction Integer} we enter:
+\spadcommand{x : Fraction Integer}
+\returnType{Type: Void}
+
+For functions the method is the same except that the arguments are
+placed in parentheses and the return type is placed after the symbol
+``{\tt ->}''.  Some examples of function definitions taking zero, one,
+two, or three arguments and returning a list of integers are:
+
+\spadcommand{f : () -> List Integer}
+\returnType{Type: Void}
+
+\spadcommand{g : (Integer) -> List Integer}
+\returnType{Type: Void}
+
+\spadcommand{h : (Integer, Integer) -> List Integer}
+\returnType{Type: Void}
+
+\spadcommand{k : (Integer, Integer, Integer) -> List Integer}
+\returnType{Type: Void}
+
+Now the actual function definitions might be:
+\spadcommand{f() == [\ ]}
+\returnType{Type: Void}
+
+\spadcommand{g(a) == [a]}
+\returnType{Type: Void}
+
+\spadcommand{h(a,b) == [a,b]}
+\returnType{Type: Void}
+
+\spadcommand{k(a,b,c) == [a,b,c]}
+\returnType{Type: Void}
+
+with some invocations of these functions:
+\spadcommand{f()}
+\begin{verbatim}
+   Compiling function f with type () -> List Integer 
+\end{verbatim}
+$$
+\left[\ 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{g(4)}
+\begin{verbatim}
+   Compiling function g with type Integer -> List Integer 
+\end{verbatim}
+$$
+\left[
+4 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{h(2,9)}
+\begin{verbatim}
+   Compiling function h with type (Integer,Integer) -> List Integer 
+\end{verbatim}
+$$
+\left[
+2,  9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{k(-3,42,100)}
+\begin{verbatim}
+   Compiling function k with type (Integer,Integer,Integer) -> List 
+      Integer 
+\end{verbatim}
+$$
+\left[
+-3,  {42},  {100} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+The value returned by a function is either the value of the last expression
+evaluated or the result of a {\bf return} statement. For example, the
+following are effectively the same:
+\spadcommand{p : Integer -> Integer}
+\returnType{Type: Void}
+
+\spadcommand{p x == (a:=1; b:=2; a+b+x)}
+\returnType{Type: Void}
+
+\spadcommand{p x == (a:=1; b:=2; return(a+b+x))}
+\returnType{Type: Void}
+
+Note that a block (pile) is assigned to the function identifier {\bf p} and
+thus all the rules about blocks apply to function definitions. Also there was
+only one argument so the parenthese are not needed.
+
+This is basically all that one needs to know about defining functions in 
+Axiom -- first specify the complete type and then assign a block to the
+function name. The rest of this section is concerned with defining more 
+complex blocks than those in this section and as a result function definitions
+will crop up continually particularly since they are a good way of testing
+examples. Since the block structure is more complex we will use the {\bf pile}
+notation and thus have to use input files to read the piles.
+
+\subsection{Choices}
+Apart from the ``{\tt =>}'' operator that allows a block to exit before the end
+Axiom provides the standard {\bf if-then-else} construct. The general
+syntax is:
+{\center{if {\sl BooleanExpr} then {\sl Expr1} else {\sl Expr2}}}
+
+where ``else {\sl Expr2}'' can be omitted. If the expression {\sl BooleanExpr}
+evaluates to {\tt true} then {\sl Expr1} is executed otherwise {\sl Expr2}
+(if present) will be executed. An example of piles and {\bf if-then-else} is:
+(read from an input file)
+\begin{verbatim}
+h := 2.0
+if h > 3.1 then
+      1.0
+   else
+      z:= cos(h)
+      max(x,0.5)
+\end{verbatim}
+\begin{verbatim}
+h := 2.0
+\end{verbatim}
+$$
+2.0
+$$
+\returnType{Type: Float}
+
+\begin{verbatim}
+if h > 3.1 then
+      1.0
+   else
+      z:= cos(h)
+      max(x,0.5)
+\end{verbatim}
+$$
+x
+$$
+\returnType{Type: Polynomial Float}
+
+Note the indentation -- the ``else'' must be indented relative to the ``if''
+otherwise it will generate an error (Axiom will think there are two piles,
+the second one beginning with ``else'').
+
+Any expression that has type {\tt Boolean} can be used as {\tt BooleanExpr}
+and the most common will be those involving the relational operators ``$>$'',
+``$<$'', and ``=''. Usually the type of an expression involving the equality
+operator ``='' will be {\bf Boolean} but in those situations when it isn't
+you may need to use the ``@'' operator to ensure that it is.
+
+\subsection{Loops}
+Loops in Axiom are regarded as expressions containing another expression 
+called the {\sl loop body}. The loop body is executed zero or more times
+depending on the kind of loop. Loops can be nested to any depth.
+
+\subsubsection{The {\tt repeat} loop}
+The simplest kind of loop provided by Axiom is the {\bf repeat} loop. The 
+general syntax of this is:
+{\center{{\bf repeat} {\sl loopBody}}}
+
+This will cause Axiom to execute {\sl loopBody} repeatedly until either a
+{\bf break} or {\bf return} statement is encountered. If {\sl loopBody}
+contains neither of these statements then it will loop forever. The 
+following piece of code will display the numbers from $1$ to $4$:
+\begin{verbatim}
+i:=1
+repeat
+  if i > 4 then break
+  output(i)
+  i:=i+1
+\end{verbatim}
+\begin{verbatim}
+i:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+repeat
+  if i > 4 then break
+  output(i)
+  i:=i+1
+ 
+   1
+   2
+   3
+   4
+\end{verbatim}
+\returnType{Type: Void}
+
+It was mentioned that loops will only be left when either a {\bf break} or
+{\bf return} statement is encountered so why can't one use the ``{\tt =>}'' 
+operator? The reason is that the ``{\tt =>}'' operator tells Axiom to leave the
+current block whereas {\bf break} leaves the current loop. The {\bf return}
+statement leaves the current function.
+
+To skip the rest of a loop body and continue the next iteration of the loop
+use the {\bf iterate} statement (the -- starts a comment in Axiom)
+\begin{verbatim}
+i := 0
+repeat
+  i := i + 1
+  if i > 6 then break
+  -- Return to start if i is odd
+  if odd?(i) then iterate
+  output(i)
+\end{verbatim}
+\begin{verbatim}
+i := 0
+\end{verbatim}
+$$
+0
+$$
+\returnType{Type: NonNegativeInteger}
+
+\begin{verbatim}
+repeat
+  i := i + 1
+  if i > 6 then break
+  -- Return to start if i is odd
+  if odd?(i) then iterate
+  output(i)
+ 
+   2
+   4
+   6
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsubsection{The {\tt while} loop}
+The while statement extends the basic {\bf repeat} loop to place the control
+of leaving the loop at the start rather than have it buried in the middle.
+Since the body of the loop is still part of a {\bf repeat} loop, {\bf break}
+and ``{\tt =>}'' work in the same way as in the previous section. The general
+syntax of a {\bf while} loop is:
+{\center{while {\sl BoolExpr} repeat {\sl loopBody}}}
+
+As before, {\sl BoolExpr} must be an expression of type {\bf Boolean}. Before
+the body of the loop is executed {\sl BoolExpr} is tested. If it evaluates to
+{\tt true} then the loop body is entered otherwise the loop is terminated.
+Multiple conditions can be applied using the logical operators such as 
+{\bf and} or by using several {\bf while} statements before the {\bf repeat}.
+\begin{verbatim}
+x:=1
+y:=1
+while x < 4 and y < 10 repeat
+  output [x,y]
+  x := x + 1
+  y := y + 2
+\end{verbatim}
+\begin{verbatim}
+x:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+y:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+while x < 4 and y < 10 repeat
+  output [x,y]
+  x := x + 1
+  y := y + 2
+ 
+   [1,1]
+   [2,3]
+   [3,5]
+\end{verbatim}
+\returnType{Type: Void}
+
+\begin{verbatim}
+x:=1
+y:=1
+while x < 4 while y < 10 repeat
+  output [x,y]
+  x := x + 1
+  y := y + 2
+\end{verbatim}
+\begin{verbatim}
+x:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+y:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+while x < 4 while y < 10 repeat
+  output [x,y]
+  x := x + 1
+  y := y + 2
+ 
+   [1,1]
+   [2,3]
+   [3,5]
+\end{verbatim}
+\returnType{Type: Void}
+
+Note that the last example using two {\bf while} statements is {\sl not} a
+nested loop but the following one is:
+\begin{verbatim}
+x:=1
+y:=1
+while x < 4 repeat
+  while y < 10 repeat
+    output [x,y]
+    x := x + 1
+    y := y + 2
+\end{verbatim}
+\begin{verbatim}
+x:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+y:=1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+while x < 4 repeat
+  while y < 10 repeat
+    output [x,y]
+    x := x + 1
+    y := y + 2
+ 
+   [1,1]
+   [2,3]
+   [3,5]
+   [4,7]
+   [5,9]
+\end{verbatim}
+\returnType{Type: Void}
+
+Suppose we that, given a matrix of arbitrary size, find the position and
+value of the first negative element by examining the matrix in row-major 
+order:
+\begin{verbatim}
+m := matrix [ [ 21, 37, 53, 14 ],_
+              [  8, 22,-24, 16 ],_
+              [  2, 10, 15, 14 ],_
+              [ 26, 33, 55,-13 ] ]
+
+lastrow := nrows(m)
+lastcol := ncols(m)
+r := 1
+while r <= lastrow repeat
+  c := 1 -- Index of first column
+  while c <= lastcol repeat
+    if elt(m,r,c) < 0 then
+      output [r,c,elt(m,r,c)]
+      r := lastrow
+      break -- Don't look any further
+    c := c + 1
+  r := r + 1
+\end{verbatim}
+\begin{verbatim}
+m := matrix [ [ 21, 37, 53, 14 ],_
+              [  8, 22,-24, 16 ],_
+              [  2, 10, 15, 14 ],_
+              [ 26, 33, 55,-13 ] ]
+\end{verbatim} 
+$$
+\left[
+\begin{array}{cccc}
+{21} & {37} & {53} & {14} \\ 
+8 & {22} & -{24} & {16} \\ 
+2 & {10} & {15} & {14} \\ 
+{26} & {33} & {55} & -{13} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+\begin{verbatim}
+lastrow := nrows(m)
+\end{verbatim}
+$$
+4
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+lastcol := ncols(m)
+\end{verbatim}
+$$
+4
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+r := 1
+\end{verbatim}
+$$
+1
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+while r <= lastrow repeat
+  c := 1 -- Index of first column
+  while c <= lastcol repeat
+    if elt(m,r,c) < 0 then
+      output [r,c,elt(m,r,c)]
+      r := lastrow
+      break -- Don't look any further
+    c := c + 1
+  r := r + 1
+ 
+   [2,3,- 24]
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsubsection{The {\tt for} loop}
+The last loop statement of interest is the {\bf for} loop. There are two
+ways of creating a {\bf for} loop. The first way uses either a list or
+a segment:
+\begin{center}
+for {\sl var} in {\sl seg} repeat {\sl loopBody}\\
+for {\sl var} in {\sl list} repeat {\sl loopBody}
+\end{center}
+where {\sl var} is an index variable which is iterated over the values in
+{\sl seg} or {\sl list}. The value {\sl seg} is a segment such as $1\ldots10$
+or $1\ldots$ and {\sl list} is a list of some type. For example:
+\begin{verbatim}
+for i in 1..10 repeat
+  ~prime?(i) => iterate
+  output(i)
+ 
+   2
+   3
+   5
+   7
+\end{verbatim}
+\returnType{Type: Void}
+
+\begin{verbatim}
+for w in ["This", "is", "your", "life!"] repeat
+  output(w)
+ 
+   This
+   is
+   your
+   life!
+\end{verbatim}
+\returnType{Type: Void}
+
+The second form of the {\bf for} loop syntax includes a ``{\bf such that}''
+clause which must be of type {\bf Boolean}:
+\begin{center}
+for {\sl var} | {\sl BoolExpr} in {\sl seg} repeat {\sl loopBody}\\
+for {\sl var} | {\sl BoolExpr} in {\sl list} repeat {\sl loopBody}
+\end{center}
+Some examples are:
+\begin{verbatim}
+for i in 1..10 | prime?(i) repeat
+  output(i)
+ 
+   2
+   3
+   5
+   7
+\end{verbatim}
+\returnType{Type: Void}
+
+\begin{verbatim}
+for i in [1,2,3,4,5,6,7,8,9,10] | prime?(i) repeat
+  output(i)
+ 
+   2
+   3
+   5
+   7
+\end{verbatim}
+\returnType{Type: Void}
+
+You can also use a {\bf while} clause:
+\begin{verbatim}
+for i in 1.. while i < 7 repeat
+  if even?(i) then output(i)
+ 
+   2
+   4
+   6
+\end{verbatim}
+\returnType{Type: Void}
+
+Using the ``{\bf such that}'' clause makes this appear simpler:
+\begin{verbatim}
+for i in 1.. | even?(i) while i < 7 repeat
+  output(i)
+ 
+   2
+   4
+   6
+\end{verbatim}
+\returnType{Type: Void}
+
+You can use multiple {\bf for} clauses to iterate over several sequences
+in parallel:
+\begin{verbatim}
+for a in 1..4 for b in 5..8 repeat
+  output [a,b]
+ 
+   [1,5]
+   [2,6]
+   [3,7]
+   [4,8]
+\end{verbatim}
+\returnType{Type: Void}
+
+As a general point it should be noted that any symbols referred to in the
+``{\bf such that}'' and {\bf while} clauses must be pre-defined. This 
+either means that the symbols must have been defined in an outer level
+(e.g. in an enclosing loop) or in a {\bf for} clause appearing before the
+``{\bf such that}'' or {\bf while}. For example:
+\begin{verbatim}
+for a in 1..4 repeat
+  for b in 7..9 | prime?(a+b) repeat
+    output [a,b,a+b]
+ 
+   [2,9,11]
+   [3,8,11]
+   [4,7,11]
+   [4,9,13]
+\end{verbatim}
+\returnType{Type: Void}
+
+Finally, the {\bf for} statement has a {\bf by} clause to specify the
+step size. This makes it possible to iterate over the segment in
+reverse order:
+\begin{verbatim}
+for a in 1..4 for b in 8..5 by -1 repeat
+  output [a,b]
+ 
+   [1,8]
+   [2,7]
+   [3,6]
+   [4,5]
+\end{verbatim}
+\returnType{Type: Void}
+
+Note that without the ``by -1'' the segment 8..5 is empty so there is
+nothing to iterate over and the loop exits immediately.
+
+\setcounter{chapter}{0} % Chapter 1
+
+\hyphenation{
+multi-set
+Uni-var-iate-Poly-nomial
+Mul-ti-var-iate-Poly-nomial
+Distributed-Mul-ti-var-iate-Poly-nomial
+Homo-gen-eous-Distributed-Mul-ti-var-iate-Poly-nomial
+New-Distributed-Mul-ti-var-iate-Poly-nomial
+General-Distributed-Mul-ti-var-iate-Poly-nomial
+}
+
+\chapter{An Overview of Axiom}
+\begin{quote}
+When we start cataloging the gains in tools sitting on a computer, the 
+benefits of software are amazing. But, if the benefits of software are
+so great, why do we worry about making it easier -- don't the ends pay 
+for the means? We worry becuase making such software is extraordinarily
+hard and almost no one can do it -- the detail is exhausting, the 
+creativity required is extreme, the hours of failure upon failure
+requiring patience and persistence would tax anyone claiming to be
+sane. Yet we require people with such characteristics be found and
+employed and employed cheaply.
+
+-- Christopher Alexander
+
+(from Patterns of Software by Richard Gabriel)
+
+\end{quote}
+\label{ugIntro}
+
+Welcome to the Axiom environment for interactive computation and
+problem solving.  Consider this chapter a brief, whirlwind tour of the
+Axiom world.  We introduce you to Axiom's graphics and the
+Axiom language.  Then we give a sampling of the large variety of
+facilities in the Axiom system, ranging from the various kinds
+of numbers, to data types (like lists, arrays, and sets) and
+mathematical objects (like matrices, integrals, and differential
+equations).  We conclude with the discussion of system commands and an
+interactive ``undo.''
+
+Before embarking on the tour, we need to brief those readers working
+interactively with Axiom on some details. 
+
+\section{Starting Up and Winding Down}
+\label{ugIntroStart}
+You need to know how to start the Axiom system and how to stop it.
+We assume that Axiom has been correctly installed on your
+machine (as described in another Axiom document).
+
+To begin using Axiom, issue the command {\bf axiom} to the
+Axiom operating system shell.
+\index{axiom @{\bf axiom}} There is a brief pause, some start-up
+messages, and then one or more windows appear.
+
+If you are not running Axiom under the X Window System, there is
+only one window (the console).  At the lower left of the screen there
+is a prompt that \index{prompt} looks like
+\begin{verbatim}
+(1) ->
+\end{verbatim}
+
+When you want to enter input to Axiom, you do so on the same
+line after the prompt.  The ``1'' in ``(1)'', also called the equation
+number, is the computation step number and is incremented 
+\index{step number} after you enter Axiom statements.  
+Note, however, that a system command such as {\tt )clear all} 
+may change the step number in other ways.  We talk about step numbers 
+more when we discuss system commands and the workspace history facility.
+
+If you are running Axiom under the X Window System, there may be
+two \index{X Window System} windows: the console window (as just
+described) and the HyperDoc main menu.  \index{Hyper@{HyperDoc}} 
+HyperDoc is a multiple-window hypertext system
+that lets you \index{window} view Axiom documentation and
+examples on-line, execute Axiom expressions, and generate
+graphics.  If you are in a graphical windowing environment, it is
+usually started automatically when Axiom begins.  If it is not
+running, issue {\tt )hd} to start it.  We discuss the basics of
+HyperDoc in Chapter \ref{ugHyper} on page~\pageref{ugHyper}.  
+
+To interrupt an Axiom computation, hold down the \index{interrupt} 
+{\bf Ctrl} (control) key and press {\bf c}.  This brings you back to 
+the Axiom prompt.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+To exit from Axiom, move to the console window, \index{stopping
+@{stopping Axiom}} type {\tt )quit} \index{exiting @{exiting
+Axiom}} at the input prompt and press the {\bf Enter} key.
+You will probably be prompted with the following
+message:
+\begin{center}
+Please enter {\bf y} or {\bf yes} if you really want to leave the \\
+interactive environment and return to the operating system
+\end{center}
+You should respond {\bf yes}, for example, to exit Axiom.\\
+}
+
+We are purposely vague in describing exactly what your screen looks
+like or what messages Axiom displays.  Axiom runs on a number of
+different machines, operating systems and window environments, and
+these differences all affect the physical look of the system.  You can
+also change the way that Axiom behaves via {\it system commands}
+described later in this chapter and in Appendix A.
+System commands are special commands, like {\tt )set}, that begin with
+a closing parenthesis and are used to change your environment.  For
+example, you can set a system variable so that you are not prompted
+for confirmation when you want to leave Axiom.
+
+\subsection{Clef}
+\label{ugAvailCLEF}
+If you are using Axiom under the X Window System, the
+\index{Clef} \index{command line editor} Clef command
+line editor is probably available and installed.  With this editor you
+can recall previous lines with the up and down arrow keys.  To move
+forward and backward on a line, use the right and left arrows.  You
+can use the {\bf Insert} key to toggle insert mode on or off.  When
+you are in insert mode, the cursor appears as a large block and if you
+type anything, the characters are inserted into the line without
+deleting the previous ones.
+
+If you press the {\bf Home} key, the cursor moves to the beginning of
+the line and if you press the {\bf End} key, the cursor moves to the
+end of the line.  Pressing {\bf Ctrl-End} deletes all the text from
+the cursor to the end of the line.
+
+Clef also provides Axiom operation name completion for
+\index{operation name completion} a limited set of operations.  If you
+enter a few letters and then press the {\bf Tab} key, Clef tries to
+use those letters as the prefix of an Axiom operation name.  If
+a name appears and it is not what you want, press {\bf Tab} again to
+see another name.
+
+You are ready to begin your journey into the world of Axiom.
+
+\section{Typographic Conventions}
+\label{ugIntroTypo}
+In this document we have followed these typographical conventions:
+\begin{itemize}
+%
+\item Categories, domains and packages are displayed in this font:
+{\tt Ring}, {\tt Integer}, {\tt DiophantineSolutionPackage}.
+%
+\item Prefix operators, infix operators, and punctuation symbols in 
+the Axiom language are displayed in the text like this:
+{\tt +}, {\tt \$}, {\tt +->}.
+%
+\item Axiom expressions or expression fragments are displayed in this font:\\
+{\tt inc(x) == x + 1}.
+%
+\item For clarity of presentation, \TeX{} is often used to format expressions\\
+$g(x)=x^2+1$.
+%
+\item Function names and HyperDoc button names are displayed in the text in
+this font:
+{\bf factor}, {\bf integrate},  {\bf Lighting}.
+%
+\item Italics are used for emphasis and for words defined in the glossary: \\
+{\it category}.
+\end{itemize}
+
+This document contains over 2500 examples of Axiom input and output.  All
+examples were run though Axiom and their output was created in \TeX{}
+form by the Axiom {\tt TexFormat} package.  We have deleted system
+messages from the example output if those messages are not important
+for the discussions in which the examples appear.
+
+\section{The Axiom Language}
+\label{ugIntroExpressions}
+The Axiom language is a rich language for performing interactive
+computations and for building components of the Axiom library.
+Here we present only some basic aspects of the language that you need
+to know for the rest of this chapter.  Our discussion here is
+intentionally informal, with details unveiled on an ``as needed''
+basis.  For more information on a particular construct, we suggest you
+consult the index.
+
+\subsection{Arithmetic Expressions}
+\label{ugIntroArithmetic}
+For arithmetic expressions, use the ``{\tt +}'' and ``{\tt -}'' operator
+as in mathematics.  Use ``{\tt *}'' for multiplication, and ``{\tt **}''
+for exponentiation.  To create a fraction, use ``{\tt /}''.  When an
+expression contains several operators, those of highest
+{\it precedence} are evaluated first.  For arithmetic operators,
+``{\tt **}'' has highest precedence, ``{\tt *}'' and ``{\tt /}'' have the
+next highest precedence, and ``{\tt +}'' and ``{\tt -}'' have the lowest
+precedence.
+
+Axiom puts implicit parentheses around operations of higher
+precedence, and groups those of equal precedence from left to right.
+\spadcommand{1 + 2 - 3 / 4 * 3 ** 2 - 1}
+$$
+-{{19} \over 4} 
+$$
+\returnType{Type: Fraction Integer}
+
+The above expression is equivalent to this.
+\spadcommand{((1 + 2) - ((3 / 4) * (3 ** 2))) - 1}
+$$
+-{{19} \over 4} 
+$$
+\returnType{Type: Fraction Integer}
+
+If an expression contains subexpressions enclosed in parentheses,
+the parenthesized subexpressions are evaluated first (from left to
+right, from inside out).
+\spadcommand{1 + 2 - 3/ (4 * 3 ** (2 - 1))}
+$$
+{11} \over 4 
+$$
+\returnType{Type: Fraction Integer}
+
+\subsection{Previous Results}
+\label{ugIntroPrevious}
+Use the percent sign ``{\tt \%}'' to refer to the last result.
+\index{result!previous} Also, use ``{\tt \%\%}' to refer to
+previous results.  \index{percentpercent@{\%\%}} ``{\tt \%\%(-1)}'' is
+equivalent to ``{\tt \%}'', ``{\tt \%\%(-2)}'' returns the next to
+the last result, and so on.  ``{\tt \%\%(1)}'' returns the result from
+step number 1, ``{\tt \%\%(2)}'' returns the result from step number 2,
+and so on.  ``{\tt \%\%(0)}'' is not defined.
+
+This is ten to the tenth power.
+\spadcommand{10 ** 10}
+$$
+10000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the last result minus one.
+\spadcommand{\% - 1}
+$$
+9999999999 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the last result.
+\spadcommand{\%\%(-1)}
+$$
+9999999999 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the result from step number 1.
+\spadcommand{\%\%(1)}
+$$
+10000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Some Types}
+\label{ugIntroTypes}
+Everything in Axiom has a type.  The type determines what operations
+you can perform on an object and how the object can be used.
+Chapter~\ref{ugTypes} on page~\pageref{ugTypes} is dedicated to the
+interactive use of types.  Several of the final chapters discuss how
+types are built and how they are organized in the Axiom library.
+
+Positive integers are given type {\bf PositiveInteger}.
+\spadcommand{8}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+Negative ones are given type {\bf Integer}.  This fine
+distinction is helpful to the Axiom interpreter.
+
+\spadcommand{-8}
+$$
+-8 
+$$
+\returnType{Type: Integer}
+
+Here a positive integer exponent gives a polynomial result.
+\spadcommand{x**8}
+$$
+x \sp 8 
+$$
+\returnType{Type: Polynomial Integer}
+
+Here a negative integer exponent produces a fraction.
+\spadcommand{x**(-8)}
+$$
+1 \over {x \sp 8} 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+\subsection{Symbols, Variables, Assignments, and Declarations}
+\label{ugIntroAssign}
+A {\it symbol} is a literal used for the input of things like
+the ``variables'' in polynomials and power series.
+
+We use the three symbols $x$, $y$, and $z$ in
+entering this polynomial.
+\spadcommand{(x - y*z)**2}
+$$
+{{y \sp 2} \  {z \sp 2}} -{2 \  x \  y \  z}+{x \sp 2} 
+$$
+\returnType{Type: Polynomial Integer}
+
+A symbol has a name beginning with an uppercase or lowercase
+alphabetic \index{symbol!naming} character, ``{\tt \%}'', or
+``{\tt !}''.  Successive characters (if any) can be any of the
+above, digits, or ``{\tt ?}''.  Case is distinguished: the symbol
+{\tt points} is different from the symbol {\tt Points}.
+
+A symbol can also be used in Axiom as a {\it variable}.  A variable
+refers to a value.  To {\sl assign} a value to a variable,
+\index{variable!naming} the operator ``{\tt :=}'' \index{assignment}
+is used.\footnote{Axiom actually has two forms of assignment: 
+{\it immediate} assignment, as discussed here, and {\it delayed
+assignment}.  See Section \ref{ugLangAssign} on page~\pageref{ugLangAssign}
+for details.}  A variable initially has no restrictions on the kinds
+of \index{declaration} values to which it can refer.
+
+This assignment gives the value $4$ (an integer) to
+a variable named $x$.
+\spadcommand{x := 4}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+This gives the value $z + 3/5$ (a polynomial)  to $x$.
+\spadcommand{x := z + 3/5}
+$$
+z+{3 \over 5} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+To restrict the types of objects that can be assigned to a variable,
+use a {\it declaration}
+\spadcommand{y : Integer}
+\returnType{Type: Void}
+
+After a variable is declared to be of some type, only values
+of that type can be assigned to that variable.
+\spadcommand{y := 89}
+$$
+89 
+$$
+\returnType{Type: Integer}
+
+The declaration for $y$ forces values assigned to $y$ to
+be converted to integer values.
+\spadcommand{y := sin \%pi}
+$$
+0 
+$$
+\returnType{Type: Integer}
+
+If no such conversion is possible,
+Axiom refuses to assign a value to $y$.
+\spadcommand{y := 2/3}
+\begin{verbatim}
+   Cannot convert right-hand side of assignment
+   2
+   -
+   3
+
+      to an object of the type Integer of the left-hand side.
+\end{verbatim}
+
+A type declaration can also be given together with an assignment.
+The declaration can assist Axiom in choosing the correct
+operations to apply.
+\spadcommand{f : Float := 2/3}
+$$
+0.6666666666\ 6666666667 
+$$
+\returnType{Type: Float}
+
+Any number of expressions can be given on input line.
+Just separate them by semicolons.
+Only the result of evaluating the last expression is displayed.
+
+These two expressions have the same effect as
+the previous single expression.
+
+\spadcommand{f : Float; f := 2/3}
+$$
+0.6666666666\ 6666666667 
+$$
+\returnType{Type: Float}
+
+The type of a symbol is either {\tt Symbol}
+or {\tt Variable({\it name})} where {\it name} is the name
+of the symbol.
+
+By default, the interpreter
+gives this symbol the type {\tt Variable(q)}.
+
+\spadcommand{q}
+$$
+q 
+$$
+\returnType{Type: Variable q}
+
+When multiple symbols are involved, {\tt Symbol} is used.
+\spadcommand{[q, r]}
+$$
+\left[
+q,  r 
+\right]
+$$
+\returnType{Type: List OrderedVariableList [q,r]}
+
+What happens when you try to use a symbol that is the name of a variable?
+\spadcommand{f}
+$$
+0.6666666666\ 6666666667 
+$$
+\returnType{Type: Float}
+
+Use a single quote ``{\tt '}'' before \index{quote} the name to get the symbol.
+
+\spadcommand{'f}
+$$
+f 
+$$
+\returnType{Type: Variable f}
+
+Quoting a name creates a symbol by preventing evaluation of the name
+as a variable.  Experience will teach you when you are most likely
+going to need to use a quote.  We try to point out the location of
+such trouble spots.
+
+\subsection{Conversion}
+\label{ugIntroConversion}
+Objects of one type can usually be ``converted'' to objects of several
+other types.  To {\sl convert} an object to a new type, use the ``{\tt ::}'' 
+infix operator.\footnote{Conversion is discussed in detail in
+\ref{ugTypesConvert} on page~\pageref{ugTypesConvert}.}  For example,
+to display an object, it is necessary to convert the object to type
+{\tt OutputForm}.
+
+This produces a polynomial with rational number coefficients.
+
+\spadcommand{p := r**2 + 2/3}
+$$
+{r \sp 2}+{2 \over 3} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+Create a quotient of polynomials with integer coefficients
+by using ``{\tt ::}''.
+
+\spadcommand{p :: Fraction Polynomial Integer }
+$$
+{{3 \  {r \sp 2}}+2} \over 3 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+Some conversions can be performed automatically when Axiom tries
+to evaluate your input.  Others conversions must be explicitly
+requested.
+
+\subsection{Calling Functions}
+\label{ugIntroCallFun}
+As we saw earlier, when you want to add or subtract two values, you
+place the arithmetic operator ``{\tt +}'' or ``{\tt -}'' between the two
+arguments denoting the values.  To use most other Axiom
+operations, however, you use another syntax: \index{function!calling}
+write the name of the operation first, then an open parenthesis, then
+each of the arguments separated by commas, and, finally, a closing
+parenthesis.  If the operation takes only one argument and the
+argument is a number or a symbol, you can omit the parentheses.
+
+This calls the operation {\bf factor} with the single integer argument $120$.
+
+\spadcommand{factor(120)}
+$$
+{2 \sp 3} \  3 \  5 
+$$
+\returnType{Type: Factored Integer}
+
+This is a call to {\bf divide} with the two integer arguments
+$125$ and $7$.
+\spadcommand{divide(125,7)}
+$$
+\left[
+{quotient={17}},  {remainder=6} 
+\right]
+$$
+\returnType{Type: Record(quotient: Integer, remainder: Integer)}
+
+This calls {\bf quatern} with four floating-point arguments.
+\spadcommand{quatern(3.4,5.6,2.9,0.1)}
+$$
+{3.4}+{{5.6} \  i}+{{2.9} \  j}+{{0.1} \  k} 
+$$
+\returnType{Type: Quaternion Float}
+
+This is the same as {\bf factorial}(10).
+\spadcommand{factorial 10}
+$$
+3628800 
+$$
+\returnType{Type: PositiveInteger}
+
+An operations that returns a {\tt Boolean} value (that is,
+{\tt true} or {\tt false}) frequently has a name suffixed with
+a question mark (``?'').  For example, the {\bf even?}
+operation returns {\tt true} if its integer argument is an even
+number, {\tt false} otherwise.
+
+An operation that can be destructive on one or more arguments
+usually has a name ending in a exclamation point (``!'').
+This actually means that it is {\it allowed} to update its
+arguments but it is not {\it required} to do so. For example,
+the underlying representation of a collection type may not allow
+the very last element to removed and so an empty object may be
+returned instead. Therefore, it is important that you use the
+object returned by the operation and not rely on a physical
+change having occurred within the object. Usually, destructive
+operations are provided for efficiency reasons.
+
+\subsection{Some Predefined Macros}
+\label{ugIntroMacros}
+Axiom provides several macros for your convenience.\footnote{See
+\ref{ugUserMacros} on page~\pageref{ugUserMacros} for a discussion on
+how to write your own macros.}  Macros are names
+\index{macro!predefined} (or forms) that expand to larger expressions
+for commonly used values.
+
+\begin{center}
+\begin{tabular}{ll}
+{\it \%i}             &  The square root of -1. \\
+{\it \%e}             &  The base of the natural logarithm. \\
+{\it \%pi}            &  $\pi$. \\
+{\it \%infinity}      &  $\infty$. \\
+{\it \%plusInfinity}  &  $+\infty$. \\
+{\it \%minusInfinity} &  $-\infty$.
+\end{tabular}
+\end{center}
+\index{\%i}
+\index{\%e}
+\index{\%pi}
+\index{pi@{$\pi$ (= \%pi)}}
+\index{\%infinity}
+\index{infinity@{$\infty$ (= \%infinity)}}
+\index{\%plusInfinity}
+\index{\%minusInfinity}
+
+To display all the macros (along with anything you have
+defined in the workspace), issue the system command {\tt )display all}.
+
+\subsection{Long Lines}
+\label{ugIntroLong}
+When you enter Axiom expressions from your keyboard, there will
+be times when they are too long to fit on one line.  Axiom does
+not care how long your lines are, so you can let them continue from
+the right margin to the left side of the next line.
+
+Alternatively, you may want to enter several shorter lines and have
+Axiom glue them together.  To get this glue, put an underscore
+(\_) at the end of each line you wish to continue.
+
+\begin{verbatim}
+2_
++_
+3
+\end{verbatim}
+is the same as if you had entered
+\begin{verbatim}
+2+3
+\end{verbatim}
+
+Axiom statements in an input file
+(see Section \ref{ugInOutIn} on page~\pageref{ugInOutIn}),
+can use indentation to indicate the program structure .
+(see Section \ref{ugLangBlocks} on page~\pageref{ugLangBlocks}).
+
+\subsection{Comments}
+\label{ugIntroComments}
+Comment statements begin with two consecutive hyphens or two
+consecutive plus signs and continue until the end of the line.
+
+The comment beginning with ``{\tt --}'' is ignored by Axiom.
+\spadcommand{2 + 3   -- this is rather simple, no?}
+$$
+5 
+$$
+\returnType{Type: PositiveInteger}
+
+There is no way to write long multi-line comments other than starting
+each line with ``{\tt --}'' or ``{\tt ++}''.
+
+\section{Numbers}
+\label{ugIntroNumbers}
+Axiom distinguishes very carefully between different kinds of
+numbers, how they are represented and what their properties are.  Here
+are a sampling of some of these kinds of numbers and some things you
+can do with them.
+
+Integer arithmetic is always exact.
+\spadcommand{11**13 * 13**11 * 17**7 - 19**5 * 23**3}
+$$
+25387751112538918594666224484237298 
+$$
+\returnType{Type: PositiveInteger}
+
+Integers can be represented in factored form.
+\spadcommand{factor 643238070748569023720594412551704344145570763243}
+$$
+{{11} \sp {13}} \  {{13} \sp {11}} \  {{17} \sp 7} \  {{19} \sp 5} \  {{23} 
+\sp 3} \  {{29} \sp 2} 
+$$
+\returnType{Type: Factored Integer}
+
+Results stay factored when you do arithmetic.
+Note that the $12$ is automatically factored for you.
+\spadcommand{\% * 12}
+\index{radix}
+$$
+{2 \sp 2} \  3 \  {{11} \sp {13}} \  {{13} \sp {11}} \  {{17} \sp 7} \  {{19} 
+\sp 5} \  {{23} \sp 3} \  {{29} \sp 2} 
+$$
+\returnType{Type: Factored Integer}
+
+Integers can also be displayed to bases other than 10.
+This is an integer in base 11.
+\spadcommand{radix(25937424601,11)}
+$$
+10000000000 
+$$
+\returnType{Type: RadixExpansion 11}
+
+Roman numerals are also available for those special occasions.
+\index{Roman numerals}
+
+\spadcommand{roman(1992)}
+$$
+{\rm MCMXCII }
+$$
+\returnType{Type: RomanNumeral}
+
+Rational number arithmetic is also exact.
+
+\spadcommand{r := 10 + 9/2 + 8/3 + 7/4 + 6/5 + 5/6 + 4/7 + 3/8 + 2/9}
+$$
+{55739} \over {2520} 
+$$
+\returnType{Type: Fraction Integer}
+
+To factor fractions, you have to pmap {\bf factor} onto the numerator
+and denominator.
+
+\spadcommand{map(factor,r)}
+$$
+{{139} \  {401}} \over {{2 \sp 3} \  {3 \sp 2} \  5 \  7} 
+$$
+\returnType{Type: Fraction Factored Integer}
+
+{\tt SingleInteger} refers to machine word-length integers.
+
+In English, this expression means ``$11$ as a small integer''.
+\spadcommand{11@SingleInteger}
+$$
+11 
+$$
+\returnType{Type: SingleInteger}
+
+Machine double-precision floating-point numbers are also available for
+numeric and graphical applications.
+\spadcommand{123.21@DoubleFloat}
+$$
+123.21000000000001 
+$$
+\returnType{Type: DoubleFloat}
+
+The normal floating-point type in Axiom, {\tt Float}, is a
+software implementation of floating-point numbers in which the
+exponent and the mantissa may have any number of digits.
+The types {\tt Complex(Float)} and
+{\tt Complex(DoubleFloat)} are the corresponding software
+implementations of complex floating-point numbers.
+
+This is a floating-point approximation to about twenty digits.
+\index{floating point} The ``{\tt ::}'' is used here to change from
+one kind of object (here, a rational number) to another (a
+floating-point number).
+
+\spadcommand{r :: Float}
+$$
+22.1186507936 50793651 
+$$
+\returnType{Type: Float}
+
+Use \spadfunFrom{digits}{Float} to change the number of digits in
+the representation.
+This operation returns the previous value so you can reset it
+later.
+\spadcommand{digits(22)}
+$$
+20 
+$$
+\returnType{Type: PositiveInteger}
+
+To $22$ digits of precision, the number
+$e^{\pi {\sqrt {163.0}}}$ appears to be an integer.
+\spadcommand{exp(\%pi * sqrt 163.0)}
+$$
+26253741 2640768744.0 
+$$
+\returnType{Type: Float}
+
+Increase the precision to forty digits and try again.
+\spadcommand{digits(40);  exp(\%pi * sqrt 163.0)}
+$$
+26253741\ 2640768743.9999999999\ 9925007259\ 76 
+$$
+\returnType{Type: Float}
+
+Here are complex numbers with rational numbers as real and
+\index{complex numbers} imaginary parts.
+\spadcommand{(2/3 + \%i)**3}
+$$
+-{{46} \over {27}}+{{1 \over 3} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+The standard operations on complex numbers are available.
+\spadcommand{conjugate \% }
+$$
+-{{46} \over {27}} -{{1 \over 3} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+You can factor complex integers.
+\spadcommand{factor(89 - 23 * \%i)}
+$$
+-{{\left( 1+i 
+\right)}
+\  {{\left( 2+i 
+\right)}
+\sp 2} \  {{\left( 3+{2 \  i} 
+\right)}
+\sp 2}} 
+$$
+\returnType{Type: Factored Complex Integer}
+
+Complex numbers with floating point parts are also available.
+\spadcommand{exp(\%pi/4.0 * \%i)}
+$$
+{0.7071067811\ 8654752440\ 0844362104\ 8490392849} + 
+$$
+$$
+{{0.7071067811\ 8654752440\ 0844362104\ 8490392848} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+The real and imaginary parts can be symbolic.
+\spadcommand{complex(u,v)}
+$$
+u+{v \  i} 
+$$
+\returnType{Type: Complex Polynomial Integer}
+
+Of course, you can do complex arithmetic with these also.
+\spadcommand{\% ** 2}
+$$
+-{v \sp 2}+{u \sp 2}+{2 \  u \  v \  i} 
+$$
+\returnType{Type: Complex Polynomial Integer}
+
+Every rational number has an exact representation as a
+repeating decimal expansion
+\spadcommand{decimal(1/352)}
+$$
+0.{00284}{\overline {09}} 
+$$
+\returnType{Type: DecimalExpansion}
+
+A rational number can also be expressed as a continued fraction.
+
+\spadcommand{continuedFraction(6543/210)}
+$$
+{31}+ \zag{1}{6}+ \zag{1}{2}+ \zag{1}{1}+ \zag{1}{3} 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+Also, partial fractions can be used and can be displayed in a
+\index{partial fraction}
+compact format
+\index{fraction!partial}
+\spadcommand{partialFraction(1,factorial(10))}
+$$
+{{159} \over {2 \sp 8}} -{{23} \over {3 \sp 4}} -{{12} \over {5 \sp 2}}+{1 
+\over 7} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+or expanded format.
+\spadcommand{padicFraction(\%)}
+$$
+{1 \over 2}+{1 \over {2 \sp 4}}+{1 \over {2 \sp 5}}+{1 \over {2 \sp 6}}+{1 
+\over {2 \sp 7}}+{1 \over {2 \sp 8}} -{2 \over {3 \sp 2}} -{1 \over {3 \sp 
+3}} -{2 \over {3 \sp 4}} -{2 \over 5} -{2 \over {5 \sp 2}}+{1 \over 7} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+Like integers, bases (radices) other than ten can be used for rational
+numbers.
+Here we use base eight.
+\spadcommand{radix(4/7, 8)}
+$$
+0.{\overline 4} 
+$$
+\returnType{Type: RadixExpansion 8}
+
+Of course, there are complex versions of these as well.
+Axiom decides to make the result a complex rational number.
+\spadcommand{\% + 2/3*\%i}
+$$
+{4 \over 7}+{{2 \over 3} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+You can also use Axiom to manipulate fractional powers.
+\index{radical}
+\spadcommand{(5 + sqrt 63 + sqrt 847)**(1/3)}
+$$
+\root {3} \of {{{{14} \  {\sqrt {7}}}+5}} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+You can also compute with integers modulo a prime.
+\spadcommand{x : PrimeField 7 := 5}
+$$
+5 
+$$
+\returnType{Type: PrimeField 7}
+
+Arithmetic is then done modulo $7$.
+\spadcommand{x**3}
+$$
+6 
+$$
+\returnType{Type: PrimeField 7}
+
+Since $7$ is prime, you can invert nonzero values.
+\spadcommand{1/x}
+$$
+3 
+$$
+\returnType{Type: PrimeField 7}
+
+You can also compute modulo an integer that is not a prime.
+\spadcommand{y : IntegerMod 6 := 5}
+$$
+5 
+$$
+\returnType{Type: IntegerMod 6}
+
+All of the usual arithmetic operations are available.
+\spadcommand{y**3}
+$$
+5 
+$$
+\returnType{Type: IntegerMod 6}
+
+Inversion is not available if the modulus is not a prime number.
+Modular arithmetic and prime fields are discussed in Section
+\ref{ugxProblemFinitePrime} on page~\pageref{ugxProblemFinitePrime}.
+
+\spadcommand{1/y}
+\begin{verbatim}
+   There are 12 exposed and 13 unexposed library operations named / 
+      having 2 argument(s) but none was determined to be applicable. 
+      Use HyperDoc Browse, or issue
+                                )display op /
+      to learn more about the available operations. Perhaps 
+      package-calling the operation or using coercions on the arguments
+      will allow you to apply the operation.
+ 
+   Cannot find a definition or applicable library operation named / 
+      with argument type(s) 
+                               PositiveInteger
+                                IntegerMod 6
+      
+      Perhaps you should use "@" to indicate the required return type, 
+      or "$" to specify which version of the function you need.
+\end{verbatim}
+
+This defines $a$ to be an algebraic number, that is,
+a root of a polynomial equation.
+\spadcommand{a := rootOf(a**5 + a**3 + a**2 + 3,a)}
+$$
+a 
+$$
+\returnType{Type: Expression Integer}
+
+Computations with $a$ are reduced according to the polynomial equation.
+\spadcommand{(a + 1)**10}
+$$
+-{{85} \  {a \sp 4}} -{{264} \  {a \sp 3}} -{{378} \  {a \sp 2}} -{{458} \  
+a} -{287} 
+$$
+\returnType{Type: Expression Integer}
+
+Define $b$ to be an algebraic number involving $a$.
+\spadcommand{b := rootOf(b**4 + a,b)}
+$$
+b 
+$$
+\returnType{Type: Expression Integer}
+
+Do some arithmetic.
+\spadcommand{2/(b - 1)}
+$$
+2 \over {b -1} 
+$$
+\returnType{Type: Expression Integer}
+
+To expand and simplify this, call {\it ratDenom}
+to rationalize the denominator.
+\spadcommand{ratDenom(\%)}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^3}}+{{\left({a^
+4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^2}}+ 
+\\
+\\
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\  b}+{a^4}-{a^
+3}+{2 \ {a^2}}- a + 1 
+\end{array}
+$$
+
+\returnType{Type: Expression Integer}
+
+If we do this, we should get $b$.
+\spadcommand{2/\%+1}
+$$
+{\left(
+\begin{array}{@{}l}
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^3}}+{{\left({a^
+4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^2}}+ 
+\\
+\\
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\  b}+{a^4}-{a^
+3}+{2 \ {a^2}}- a + 3 
+\end{array}
+\right)}\over{\left(
+\begin{array}{@{}l}
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^3}}+{{\left({a^
+4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\ {b^2}}+ 
+\\
+\\
+\displaystyle
+{{\left({a^4}-{a^3}+{2 \ {a^2}}- a + 1 \right)}\  b}+{a^4}-{a^
+3}+{2 \ {a^2}}- a + 1 
+\end{array}
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+But we need to rationalize the denominator again.
+
+\spadcommand{ratDenom(\%)}
+$$
+b 
+$$
+\returnType{Type: Expression Integer}
+
+Types {\tt Quaternion} and {\tt Octonion} are also available.
+Multiplication of quaternions is non-commutative, as expected.
+
+\spadcommand{q:=quatern(1,2,3,4)*quatern(5,6,7,8) - quatern(5,6,7,8)*quatern(1,2,3,4)}
+$$
+-{8 \  i}+{{16} \  j} -{8 \  k} 
+$$
+\returnType{Type: Quaternion Integer}
+
+\section{Data Structures}
+\label{ugIntroCollect}
+Axiom has a large variety of data structures available.  Many
+data structures are particularly useful for interactive computation
+and others are useful for building applications.  The data structures
+of Axiom are organized into {\sl category hierarchies}.
+
+A {\it list} \footnote{Lists are discussed in Section \ref{ListXmpPage} on
+page~\pageref{ListXmpPage}} is the most commonly used data structure in
+Axiom for holding objects all of the same type. The name {\it list} is
+short for ``linked-list of nodes.'' Each node consists of a value
+(\spadfunFrom{first}{List}) and a link (\spadfunFrom{rest}{List}) that
+points to the next node, or to a distinguished value denoting the
+empty list.  To get to, say, the third element, Axiom starts at the
+front of the list, then traverses across two links to the third node.
+
+Write a list of elements using square brackets with commas separating
+the elements.
+\spadcommand{u := [1,-7,11]}
+$$
+\left[
+1,  -7,  {11} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+This is the value at the third node.  Alternatively, you can say $u.3$.
+\spadcommand{first rest rest u}
+$$
+11 
+$$
+\returnType{Type: PositiveInteger}
+
+Many operations are defined on lists, such as: {\bf empty?}, to test
+that a list has no elements; {\bf cons}$(x,l)$, to create a new list
+with {\bf first} element $x$ and {\bf rest} $l$; {\bf reverse}, to
+create a new list with elements in reverse order; and {\bf sort}, to
+arrange elements in order.
+
+An important point about lists is that they are ``mutable'': their
+constituent elements and links can be changed ``in place.''
+To do this, use any of the operations whose names end with the
+character ``{\tt !}''.
+
+The operation \spadfunFrom{concat!}{List}$(u,v)$ replaces the
+last link of the list $u$ to point to some other list $v$.
+Since $u$ refers to the original list, this change is seen by $u$.
+\spadcommand{concat!(u,[9,1,3,-4]); u}
+$$
+\left[
+1,  -7,  {11},  9,  1,  3,  -4 
+\right]
+$$
+\returnType{Type: List Integer}
+
+A {\it cyclic list} is a list with a ``cycle'': \index{list!cyclic} a
+link pointing back to an earlier node of the list.  \index{cyclic
+list} To create a cycle, first get a node somewhere down the list.
+\spadcommand{lastnode := rest(u,3)}
+$$
+\left[
+9,  1,  3,  -4 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Use \spadfunFrom{setrest!}{List} to change the link emanating from
+that node to point back to an earlier part of the list.
+
+\spadcommand{setrest!(lastnode,rest(u,2)); u}
+$$
+\left[
+1,  -7,  {\overline {{11},  9}} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+A {\it stream} is a structure that (potentially) has an infinite
+number of distinct elements. Think of a stream as an
+``infinite list'' where elements are computed successively.
+\footnote{Streams are discussed in Section{StreamXmpPage} on
+page~\pageref{StreamXmpPage}}
+
+Create an infinite stream of factored integers.  Only a certain number
+of initial elements are computed and displayed.
+
+\spadcommand{[factor(i) for i in 2.. by 2]}
+$$
+\left[
+2,  {2 \sp 2},  {2 \  3},  {2 \sp 3},  {2 \  5},  {{2 \sp 2} \  3}, 
+ {2 \  7},  {2 \sp 4},  {2 \  {3 \sp 2}},  {{2 \sp 2} \  5},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Factored Integer}
+
+Axiom represents streams by a collection of already-computed
+elements together with a function to compute the next element ``on
+demand.''  Asking for the $n$-th element causes elements
+$1$ through $n$ to be evaluated.
+\spadcommand{\%.36}
+$$
+{2 \sp 3} \  {3 \sp 2} 
+$$
+\returnType{Type: Factored Integer}
+
+Streams can also be finite or cyclic.
+They are implemented by a linked list structure similar to lists
+and have many of the same operations.
+For example, {\bf first} and {\bf rest} are used to access
+elements and successive nodes of a stream.
+
+A {\it one-dimensional array} is another data structure used to hold
+objects of the same type \footnote{OnedimensionalArray is discussed in
+Section \ref{OneDimensionalArrayXmpPage} on
+page~\pageref{OneDimensionalArrayXmpPage}}. Unlike lists,
+one-dimensional arrays are inflexible---they are
+\index{array!one-dimensional} implemented using a fixed block of
+storage.  Their advantage is that they give quick and equal access
+time to any element.
+
+A simple way to create a one-dimensional array is to apply the
+operation {\bf oneDimensionalArray} to a list of elements.
+\spadcommand{a := oneDimensionalArray [1, -7, 3, 3/2]}
+$$
+\left[
+1,  -7,  3,  {3 \over 2} 
+\right]
+$$
+\returnType{Type: OneDimensionalArray Fraction Integer}
+
+One-dimensional arrays are also mutable: you can change their
+constituent elements ``in place.''
+\spadcommand{a.3 := 11; a}
+$$
+\left[
+1,  -7,  {11},  {3 \over 2} 
+\right]
+$$
+\returnType{Type: OneDimensionalArray Fraction Integer}
+
+However, one-dimensional arrays are not flexible structures.
+You cannot destructively {\bf concat!} them together.
+\spadcommand{concat!(a,oneDimensionalArray [1,-2])}
+\begin{verbatim}
+   There are 5 exposed and 0 unexposed library operations named concat!
+      having 2 argument(s) but none was determined to be applicable. 
+      Use HyperDoc Browse, or issue
+                             )display op concat!
+      to learn more about the available operations. Perhaps 
+      package-calling the operation or using coercions on the arguments
+      will allow you to apply the operation.
+ 
+   Cannot find a definition or applicable library operation named 
+      concat! with argument type(s) 
+                    OneDimensionalArray Fraction Integer
+                         OneDimensionalArray Integer
+      
+      Perhaps you should use "@" to indicate the required return type, 
+      or "$" to specify which version of the function you need.
+\end{verbatim}
+
+Examples of datatypes similar to {\tt OneDimensionalArray}
+are: {\tt Vector} (vectors are mathematical structures
+implemented by one-dimensional arrays), {\tt String} (arrays
+of ``characters,'' represented by byte vectors), and
+{\tt Bits} (represented by ``bit vectors'').
+
+A vector of 32 bits, each representing the {\bf Boolean} value
+${\tt true}$.
+\spadcommand{bits(32,true)}
+$$
+\mbox{\tt "11111111111111111111111111111111"} 
+$$
+\returnType{Type: Bits}
+
+A {\it flexible array} \footnote{FlexibleArray is discussed in Section
+\ref{FlexibleArrayXmpPage} on page~\pageref{FlexibleArrayXmpPage}} is
+a cross between a list \index{array!flexible} and a one-dimensional
+array. Like a one-dimensional array, a flexible array occupies a fixed
+block of storage.  Its block of storage, however, has room to expand.
+When it gets full, it grows (a new, larger block of storage is
+allocated); when it has too much room, it contracts.
+
+Create a flexible array of three elements.
+\spadcommand{f := flexibleArray [2, 7, -5]}
+$$
+\left[
+2,  7,  -5 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Insert some elements between the second and third elements.
+\spadcommand{insert!(flexibleArray [11, -3],f,2)}
+$$
+\left[
+2,  {11},  -3,  7,  -5 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Flexible arrays are used to implement ``heaps.'' A {\it heap} is an
+example of a data structure called a {\it priority queue}, where
+elements are ordered with respect to one another. A heap
+\footnote{Heap is discussed in Section \ref{HeapXmpPage} on
+page~\pageref{HeapXmpPage}} is organized so as to optimize insertion
+and extraction of maximum elements.  The {\bf extract!} operation
+returns the maximum element of the heap, after destructively removing
+that element and reorganizing the heap so that the next maximum
+element is ready to be delivered.
+
+An easy way to create a heap is to apply the operation {\it heap}
+to a list of values.
+\spadcommand{h := heap [-4,7,11,3,4,-7]}
+$$
+\left[
+{11},  4,  7,  -4,  3,  -7 
+\right]
+$$
+\returnType{Type: Heap Integer}
+
+This loop extracts elements one-at-a-time from $h$ until the heap
+is exhausted, returning the elements as a list in the order they were
+extracted.
+\spadcommand{[extract!(h) while not empty?(h)]}
+$$
+\left[
+{11},  7,  4,  3,  -4,  -7 
+\right]
+$$
+\returnType{Type: List Integer}
+
+A {\it binary tree} is a ``tree'' with at most two branches
+\index{tree} per node: it is either empty, or else is a node
+consisting of a value, and a left and right subtree (again, binary
+trees). \footnote{BinarySearchTrees are discussed in Section 
+\ref{BinarySearchTreeXmpPage} on page~\pageref{BinarySearchTreeXmpPage}}
+Examples of binary tree types are {\tt BinarySearchTree}, 
+{\tt PendantTree}, {\tt TournamentTree}, and {\tt BalancedBinaryTree}.
+
+A {\it binary search tree} is a binary tree such that,
+\index{tree!binary search} for each node, the value of the node is
+\index{binary search tree} greater than all values (if any) in the
+left subtree, and less than or equal all values (if any) in the right
+subtree.
+\spadcommand{binarySearchTree [5,3,2,9,4,7,11]}
+$$
+\left[
+{\left[ 2,  3,  4 
+\right]},
+ 5,  {\left[ 7,  9,  {11} 
+\right]}
+\right]
+$$
+\returnType{Type: BinarySearchTree PositiveInteger}
+
+A {\it balanced binary tree} is useful for doing modular computations.
+\index{balanced binary tree} Given a list $lm$ of moduli,
+\index{tree!balanced binary} {\bf modTree}$(a,lm)$ produces
+a balanced binary tree with the values $a \bmod m$ at its leaves.
+\spadcommand{modTree(8,[2,3,5,7])}
+$$
+\left[
+0,  2,  3,  1 
+\right]
+$$
+\returnType{Type: List Integer}
+
+A {\it set} is a collection of elements where duplication and order is
+irrelevant. \footnote{Sets are discussed in Section \ref{SetXmpPage}
+on page~\pageref{SetXmpPage}} Sets are always finite and have no
+corresponding structure like streams for infinite collections.
+
+Create sets using braces ``\{`` and ``\}'' rather than brackets.
+
+\spadcommand{fs := set[1/3,4/5,-1/3,4/5]}
+$$
+\left\{
+-{1 \over 3},  {1 \over 3},  {4 \over 5} 
+\right\}
+$$
+\returnType{Type: Set Fraction Integer}
+
+A {\it multiset} is a set that keeps track of the number of duplicate
+values. \footnote{Multisets are discussed in Section
+\ref{MultisetXmpPage} on page~\pageref{MultisetXmpPage}}
+
+For all the primes $p$ between 2 and 1000, find the
+distribution of $p \bmod 5$.
+\spadcommand{multiset [x rem 5 for x in primes(2,1000)]}
+$$
+\left\{
+0,  {{42} \mbox{\rm : } 3},  {{40} \mbox{\rm : } 1},  {{38} \mbox{\rm : 
+} 4},  {{47} \mbox{\rm : } 2} 
+\right\}
+$$
+\returnType{Type: Multiset Integer}
+
+A {\it table} is conceptually a set of ``key--value'' pairs and is a
+generalization of a multiset. For examples of tables, see 
+{\tt AssociationList}, {\tt HashTable}, {\tt KeyedAccessFile}, 
+{\tt Library}, {\tt SparseTable}, {\tt StringTable}, and {\tt Table}.  The
+domain {\tt Table(Key, Entry)} provides a general-purpose type for
+tables with {\it values} of type $Entry$ indexed by {\it keys} of type
+$Key$.
+
+Compute the above distribution of primes using tables.  First, let
+$t$ denote an empty table of keys and values, each of type {\tt Integer}.
+\spadcommand{t : Table(Integer,Integer) := empty()}
+$$
+{\rm table}() 
+$$
+\returnType{Type: Table(Integer,Integer)}
+
+We define a function {\bf howMany} to return the number of values
+of a given modulus $k$ seen so far.  It calls
+{\bf search}$(k,t)$ which returns the number of values
+stored under the key $k$ in table $t$, or {\tt ``failed''}
+if no such value is yet stored in $t$ under $k$.
+
+In English, this says ``Define $howMany(k)$ as follows.
+First, let $n$ be the value of {\it search}$(k,t)$.
+Then, if $n$ has the value $"failed"$, return the value
+$1$; otherwise return $n + 1$.''
+\spadcommand{howMany(k) == (n:=search(k,t); n case "failed" => 1; n+1)}
+\returnType{Type: Void}
+
+Run through the primes to create the table, then print the table.
+The expression {\tt t.m := howMany(m)} updates the value in table $t$
+stored under key $m$.
+\spadcommand{for p in primes(2,1000) repeat (m:= p rem 5; t.m:= howMany(m)); t}
+\begin{verbatim}
+   Compiling function howMany with type Integer -> Integer 
+\end{verbatim}
+$$
+{\rm table }
+\left(
+{{2={47}},  {4={38}},  {1={40}},  {3={42}},  {0=1}} 
+\right)
+$$
+\returnType{Type: Table(Integer,Integer)}
+
+A {\it record} is an example of an inhomogeneous collection of
+objects.\footnote{See \ref{ugTypesRecords} on
+page~\pageref{ugTypesRecords} for details.}  A record consists of a
+set of named {\it selectors} that can be used to access its
+components.  \index{Record@{\sf Record}}
+
+Declare that $daniel$ can only be
+assigned a record with two prescribed fields.
+\spadcommand{daniel : Record(age : Integer, salary : Float)}
+\returnType{Type: Void}
+
+Give $daniel$ a value, using square brackets to enclose the values of
+the fields.
+\spadcommand{daniel := [28, 32005.12]}
+$$
+\left[
+{age={28}},  {salary={32005.12}} 
+\right]
+$$
+\returnType{Type: Record(age: Integer,salary: Float)}
+
+Give $daniel$ a raise.
+\spadcommand{daniel.salary := 35000; daniel}
+$$
+\left[
+{age={28}},  {salary={35000.0}} 
+\right]
+$$
+\returnType{Type: Record(age: Integer,salary: Float)}
+
+A {\it union} is a data structure used when objects have multiple
+types.\footnote{See \ref{ugTypesUnions} on
+page~\pageref{ugTypesUnions} for details.}  \index{Union@{\sf Union}}
+
+Let $dog$ be either an integer or a string value.
+\spadcommand{dog: Union(licenseNumber: Integer, name: String)}
+\returnType{Type: Void}
+
+Give $dog$ a name.
+\spadcommand{dog := "Whisper"}
+$$
+\mbox{\tt "Whisper"} 
+$$
+\returnType{Type: Union(name: String,...)}
+
+All told, there are over forty different data structures in Axiom.
+Using the domain constructors described in Chapter \ref{ugDomains} on
+page~\pageref{ugDomains}, you can add your own data structure or
+extend an existing one.  Choosing the right data structure for your
+application may be the key to obtaining good performance.
+
+\section{Expanding to Higher Dimensions}
+\label{ugIntroTwoDim}
+To get higher dimensional aggregates, you can create one-dimensional
+aggregates with elements that are themselves aggregates, for example,
+lists of lists, one-dimensional arrays of lists of multisets, and so
+on.  For applications requiring two-dimensional homogeneous
+aggregates, you will likely find {\it two-dimensional arrays}
+\index{matrix} and {\it matrices} most useful.
+\index{array!two-dimensional}
+
+The entries in {\tt TwoDimensionalArray} and {\tt Matrix} objects are
+all the same type, except that those for {\tt Matrix} must belong to a
+{\tt Ring}.  You create and access elements in roughly the same way.
+Since matrices have an understood algebraic structure, certain
+algebraic operations are available for matrices but not for arrays.
+Because of this, we limit our discussion here to {\tt Matrix}, that
+can be regarded as an extension of {\tt TwoDimensionalArray}. See {\tt
+TwoDimensionalArray} for more information about arrays.  For more
+information about Axiom's linear algebra facilities, see {\tt Matrix},
+{\tt Permanent}, {\tt SquareMatrix}, {\tt Vector}, see Section
+\ref{ugProblemEigen} on page~\pageref{ugProblemEigen} (computation of
+eigenvalues and eigenvectors), and Section \ref{ugProblemLinPolEqn} on
+page~\pageref{ugProblemLinPolEqn} (solution of linear and polynomial
+equations).
+
+You can create a matrix from a list of lists, \index{matrix!creating}
+where each of the inner lists represents a row of the matrix.
+\spadcommand{m := matrix([ [1,2], [3,4] ])}
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+3 & 4 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+The ``collections'' construct (see \ref{ugLangIts} on
+page~\pageref{ugLangIts}) is useful for creating matrices whose
+entries are given by formulas.  \index{matrix!Hilbert}
+\spadcommand{matrix([ [1/(i + j - x) for i in 1..4] for j in 1..4])}
+$$
+\left[
+\begin{array}{cccc}
+-{1 \over {x -2}} & -{1 \over {x -3}} & -{1 \over {x -4}} & -{1 \over {x -5}} \\ 
+-{1 \over {x -3}} & -{1 \over {x -4}} & -{1 \over {x -5}} & -{1 \over {x -6}} \\ 
+-{1 \over {x -4}} & -{1 \over {x -5}} & -{1 \over {x -6}} & -{1 \over {x -7}} \\ 
+-{1 \over {x -5}} & -{1 \over {x -6}} & -{1 \over {x -7}} & -{1 \over {x -8}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Fraction Polynomial Integer}
+
+Let $vm$ denote the three by three Vandermonde matrix.
+\spadcommand{vm := matrix [ [1,1,1], [x,y,z], [x*x,y*y,z*z] ]}
+$$
+\left[
+\begin{array}{ccc}
+1 & 1 & 1 \\ 
+x & y & z \\ 
+{x \sp 2} & {y \sp 2} & {z \sp 2} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Integer}
+
+Use this syntax to extract an entry in the matrix.
+
+\spadcommand{vm(3,3)}
+$$
+z \sp 2 
+$$
+\returnType{Type: Polynomial Integer}
+
+You can also pull out a {\bf row} or a {\bf column}.
+
+\spadcommand{column(vm,2)}
+$$
+\left[
+1,  y,  {y \sp 2} 
+\right]
+$$
+\returnType{Type: Vector Polynomial Integer}
+
+You can do arithmetic.
+
+\spadcommand{vm * vm}
+$$
+\left[
+\begin{array}{ccc}
+{{x \sp 2}+x+1} & {{y \sp 2}+y+1} & {{z \sp 2}+z+1} \\ 
+{{{x \sp 2} \  z}+{x \  y}+x} & {{{y \sp 2} \  z}+{y \sp 2}+x} & {{z \sp 
+3}+{y \  z}+x} \\ 
+{{{x \sp 2} \  {z \sp 2}}+{x \  {y \sp 2}}+{x \sp 2}} & {{{y \sp 2} \  {z \sp 
+2}}+{y \sp 3}+{x \sp 2}} & {{z \sp 4}+{{y \sp 2} \  z}+{x \sp 2}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Integer}
+
+You can perform operations such as
+{\bf transpose}, {\bf trace}, and {\bf determinant}.
+\spadcommand{factor determinant vm}
+$$
+{\left( y -x 
+\right)}
+\  {\left( z -y 
+\right)}
+\  {\left( z -x 
+\right)}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+\section{Writing Your Own Functions}
+\label{ugIntroYou}
+Axiom provides you with a very large library of predefined
+operations and objects to compute with.  You can use the Axiom
+library of constructors to create new objects dynamically of quite
+arbitrary complexity.  For example, you can make lists of matrices of
+fractions of polynomials with complex floating point numbers as
+coefficients.  Moreover, the library provides a wealth of operations
+that allow you to create and manipulate these objects.
+
+For many applications, you need to interact with the interpreter and
+write some Axiom programs to tackle your application.
+Axiom allows you to write functions interactively,
+\index{function} thereby effectively extending the system library.
+Here we give a few simple examples, leaving the details to
+Chapter \ref{ugUser} on page~\pageref{ugUser}.
+
+We begin by looking at several ways that you can define the
+``factorial'' function in Axiom.  The first way is to give a
+\index{function!piece-wise definition} piece-wise definition of the
+function.  \index{piece-wise function definition} This method is best
+for a general recurrence relation since the pieces are gathered
+together and compiled into an efficient iterative function.
+Furthermore, enough previously computed values are automatically saved
+so that a subsequent call to the function can pick up from where it
+left off.
+
+Define the value of {\bf fact} at $0$.
+\spadcommand{fact(0) == 1}
+\returnType{Type: Void}
+
+Define the value of {\bf fact}(n) for general $n$.
+\spadcommand{fact(n) == n*fact(n-1)}
+\returnType{Type: Void}
+
+Ask for the value at $50$.  The resulting function created by
+Axiom computes the value by iteration.
+
+\spadcommand{fact(50)}
+\begin{verbatim}
+   Compiling function fact with type Integer -> Integer 
+   Compiling function fact as a recurrence relation.
+\end{verbatim}
+$$
+30414093201713378043612608166064768844377641568960512000000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+A second definition uses an {\tt if-then-else} and recursion.
+\spadcommand{fac(n) == if n < 3 then n else n * fac(n - 1)}
+\returnType{Type: Void}
+
+This function is less efficient than the previous version since
+each iteration involves a recursive function call.
+\spadcommand{fac(50)}
+$$
+30414093201713378043612608166064768844377641568960512000000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+A third version directly uses iteration.
+\spadcommand{fa(n) == (a := 1; for i in 2..n repeat a := a*i; a)}
+\returnType{Type: Void}
+
+This is the least space-consumptive version.
+\spadcommand{fa(50)}
+\begin{verbatim}
+   Compiling function fac with type Integer -> Integer 
+\end{verbatim}
+$$
+30414093201713378043612608166064768844377641568960512000000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+A final version appears to construct a large list and then reduces over
+it with multiplication.
+\spadcommand{f(n) == reduce(*,[i for i in 2..n])}
+\returnType{Type: Void}
+
+In fact, the resulting computation is optimized into an efficient
+iteration loop equivalent to that of the third version.
+\spadcommand{f(50)}
+\begin{verbatim}
+Compiling function f with type 
+   PositiveInteger -> PositiveInteger 
+\end{verbatim}
+$$
+30414093201713378043612608166064768844377641568960512000000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+The library version uses an algorithm that is different from the four
+above because it highly optimizes the recurrence relation definition of
+{\bf factorial}.
+
+\spadcommand{factorial(50)}
+$$
+30414093201713378043612608166064768844377641568960512000000000000 
+$$
+\returnType{Type: PositiveInteger}
+
+You are not limited to one-line functions in Axiom.  If you place your
+function definitions in {\bf .input} files \index{file!input} (see
+\ref{ugInOutIn} on page~\pageref{ugInOutIn}), you can have multi-line
+functions that use indentation for grouping.
+
+Given $n$ elements, {\bf diagonalMatrix} creates an
+$n$ by $n$ matrix with those elements down the diagonal.
+This function uses a permutation matrix
+that interchanges the $i$th and $j$th rows of a matrix
+by which it is right-multiplied.
+
+This function definition shows a style of definition that can be used
+in {\bf .input} files.  Indentation is used to create {\sl blocks}:
+sequences of expressions that are evaluated in sequence except as
+modified by control statements such as {\tt if-then-else} and {\tt return}.
+
+\begin{verbatim}
+permMat(n, i, j) ==
+  m := diagonalMatrix
+    [(if i = k or j = k then 0 else 1)
+      for k in 1..n]
+  m(i,j) := 1
+  m(j,i) := 1
+  m
+\end{verbatim}
+
+This creates a four by four matrix that interchanges the second and third
+rows.
+\spadcommand{p := permMat(4,2,3)}
+\begin{verbatim}
+   Compiling function permMat with type (PositiveInteger,
+      PositiveInteger,PositiveInteger) -> Matrix Integer 
+\end{verbatim}
+$$
+\left[
+\begin{array}{cccc}
+1 & 0 & 0 & 0 \\ 
+0 & 0 & 1 & 0 \\ 
+0 & 1 & 0 & 0 \\ 
+0 & 0 & 0 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+Create an example matrix to permute.
+\spadcommand{m := matrix [ [4*i + j for j in 1..4] for i in 0..3]}
+$$
+\left[
+\begin{array}{cccc}
+1 & 2 & 3 & 4 \\ 
+5 & 6 & 7 & 8 \\ 
+9 & {10} & {11} & {12} \\ 
+{13} & {14} & {15} & {16} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+Interchange the second and third rows of m.
+\spadcommand{permMat(4,2,3) * m}
+$$
+\left[
+\begin{array}{cccc}
+1 & 2 & 3 & 4 \\ 
+9 & {10} & {11} & {12} \\ 
+5 & 6 & 7 & 8 \\ 
+{13} & {14} & {15} & {16} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+A function can also be passed as an argument to another function,
+which then applies the function or passes it off to some other
+function that does.  You often have to declare the type of a function
+that has functional arguments.
+
+This declares {\bf t} to be a two-argument function that returns a
+{\tt Float}.  The first argument is a function that takes one
+{\tt Float} argument and returns a {\tt Float}.
+
+\spadcommand{t : (Float -> Float, Float) -> Float}
+\returnType{Type: Void}
+
+This is the definition of {\bf t}.
+
+\spadcommand{t(fun, x) == fun(x)**2 + sin(x)**2}
+\returnType{Type: Void}
+
+We have not defined a {\bf cos} in the workspace. The one from the
+Axiom library will do.
+
+\spadcommand{t(cos, 5.2058)}
+$$
+1.0 
+$$
+\returnType{Type: Float}
+
+Here we define our own (user-defined) function.
+\spadcommand{cosinv(y) == cos(1/y)}
+\returnType{Type: Void}
+
+Pass this function as an argument to {\bf t}.
+\spadcommand{t(cosinv, 5.2058)}
+$$
+1.7392237241\ 8005164925\ 4147684772\ 932520785 
+$$
+\returnType{Type: Float}
+
+Axiom also has pattern matching capabilities for
+\index{simplification}
+simplification
+\index{pattern matching}
+of expressions and for defining new functions by rules.
+For example, suppose that you want to apply regularly a transformation
+that groups together products of radicals:
+$$\sqrt{a}\sqrt{b} \mapsto \sqrt{ab}, \quad
+(\forall a)(\forall b)$$
+Note that such a transformation is not generally correct.
+Axiom never uses it automatically.
+
+Give this rule the name {\bf groupSqrt}.
+\spadcommand{groupSqrt := rule(sqrt(a) * sqrt(b) == sqrt(a*b))}
+$$
+{ \%C \  {\sqrt {a}} \  {\sqrt {b}}} \mbox{\rm == } { \%C \  {\sqrt {{a \  
+b}}}} 
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Here is a test expression.
+\spadcommand{a := (sqrt(x) + sqrt(y) + sqrt(z))**4}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{{\left({{\left({4 \  z}+{4 \  y}+{{12}\  x}\right)}\ {\sqrt{y}}}+
+{{\left({4 \  z}+{{12}\  y}+{4 \  x}\right)}\ {\sqrt{x}}}\right)}\ {\sqrt{z}}}+
+ 
+\\
+\\
+\displaystyle
+{{\left({{12}\  z}+{4 \  y}+{4 \  x}\right)}\ {\sqrt{x}}\ {\sqrt{y}}}+
+{z^2}+{{\left({6 \  y}+{6 \  x}\right)}\  z}+{y^2}+{6 \  x \  
+y}+{x^2}
+\end{array}
+$$
+\returnType{Type: Expression Integer}
+
+The rule
+{\bf groupSqrt} successfully simplifies the expression.
+\spadcommand{groupSqrt a}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{{\left({4 \  z}+{4 \  y}+{{12}\  x}\right)}\ {\sqrt{y \  z}}}+
+{{\left({4 \  z}+{{12}\  y}+{4 \  x}\right)}\ {\sqrt{x \  z}}}+
+ 
+\\
+\\
+\displaystyle
+{{\left({{12}\  z}+{4 \  y}+{4 \  x}\right)}\ {\sqrt{x \  y}}}+
+{z^2}+{{\left({6 \  y}+{6 \  x}\right)}\  z}+{y^2}+{6 \  x \  
+y}+{x^2}
+\end{array}
+$$
+\returnType{Type: Expression Integer}
+
+\section{Polynomials}
+\label{ugIntroVariables}
+Polynomials are the commonly used algebraic types in symbolic
+computation.  \index{polynomial} Interactive users of Axiom
+generally only see one type of polynomial: {\tt Polynomial(R)}.
+This type represents polynomials in any number of unspecified
+variables over a particular coefficient domain $R$.  This type
+represents its coefficients {\sl sparsely}: only terms with non-zero
+coefficients are represented.
+
+In building applications, many other kinds of polynomial
+representations are useful.  Polynomials may have one variable or
+multiple variables, the variables can be named or unnamed, the
+coefficients can be stored sparsely or densely.  So-called
+``distributed multivariate polynomials'' store polynomials as
+coefficients paired with vectors of exponents.  This type is
+particularly efficient for use in algorithms for solving systems of
+non-linear polynomial equations.
+
+The polynomial constructor most familiar to the interactive user
+is {\tt Polynomial}.
+\spadcommand{(x**2 - x*y**3 +3*y)**2}
+$$
+{{x \sp 2} \  {y \sp 6}} -{6 \  x \  {y \sp 4}} -{2 \  {x \sp 3} \  {y \sp 
+3}}+{9 \  {y \sp 2}}+{6 \  {x \sp 2} \  y}+{x \sp 4} 
+$$
+\returnType{Type: Polynomial Integer}
+
+If you wish to restrict the variables used,
+{\tt UnivariatePolynomial} provides polynomials in one variable.
+
+\spadcommand{p: UP(x,INT) := (3*x-1)**2 * (2*x + 8)}
+$$
+{{18} \  {x \sp 3}}+{{60} \  {x \sp 2}} -{{46} \  x}+8 
+$$
+\returnType{Type: UnivariatePolynomial(x,Integer)}
+
+The constructor {\tt MultivariatePolynomial} provides polynomials
+in one or more specified variables.
+
+\spadcommand{m: MPOLY([x,y],INT) := (x**2-x*y**3+3*y)**2}
+$$
+{x \sp 4} -{2 \  {y \sp 3} \  {x \sp 3}}+{{\left( {y \sp 6}+{6 \  y} 
+\right)}
+\  {x \sp 2}} -{6 \  {y \sp 4} \  x}+{9 \  {y \sp 2}} 
+$$
+\returnType{Type: MultivariatePolynomial([x,y],Integer)}
+
+You can change the way the polynomial appears by modifying the variable
+ordering in the explicit list.
+\spadcommand{m :: MPOLY([y,x],INT)}
+$$
+{{x \sp 2} \  {y \sp 6}} -{6 \  x \  {y \sp 4}} -{2 \  {x \sp 3} \  {y \sp 
+3}}+{9 \  {y \sp 2}}+{6 \  {x \sp 2} \  y}+{x \sp 4} 
+$$
+\returnType{Type: MultivariatePolynomial([y,x],Integer)}
+
+The constructor {\tt DistributedMultivariatePolynomial} provides
+polynomials in one or more specified variables with the monomials
+ordered lexicographically.
+
+\spadcommand{m :: DMP([y,x],INT)}
+$$
+{{y \sp 6} \  {x \sp 2}} -{6 \  {y \sp 4} \  x} -{2 \  {y \sp 3} \  {x \sp 
+3}}+{9 \  {y \sp 2}}+{6 \  y \  {x \sp 2}}+{x \sp 4} 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([y,x],Integer)}
+
+The constructor
+{\tt HomogeneousDistributedMultivariatePolynomial} is similar
+except that the monomials are ordered by total order refined by
+reverse lexicographic order.
+\spadcommand{m :: HDMP([y,x],INT)}
+$$
+{{y \sp 6} \  {x \sp 2}} -{2 \  {y \sp 3} \  {x \sp 3}} -{6 \  {y \sp 4} \  
+x}+{x \sp 4}+{6 \  y \  {x \sp 2}}+{9 \  {y \sp 2}} 
+$$
+\returnType{Type: HomogeneousDistributedMultivariatePolynomial([y,x],Integer)}
+
+More generally, the domain constructor
+{\tt GeneralDistributedMultivariatePolynomial} allows the user to
+provide an arbitrary predicate to define his own term ordering.  These
+last three constructors are typically used in Gr\"{o}bner basis
+applications and
+when a flat (that is, non-recursive) display is wanted and the term
+ordering is critical for controlling the computation.
+
+\section{Limits}
+\label{ugIntroCalcLimits}
+
+Axiom's {\bf limit} function is usually used to evaluate
+limits of quotients where the numerator and denominator \index{limit}
+both tend to zero or both tend to infinity.  To find the limit of an
+expression $f$ as a real variable $x$ tends to a limit
+value $a$, enter {\tt limit(f, x=a)}.  Use
+{\bf complexLimit} if the variable is complex.  Additional
+information and examples of limits are in 
+Section \ref{ugProblemLimits} on page~\pageref{ugProblemLimits}.
+
+You can take limits of functions with parameters.
+\index{limit!of function with parameters}
+\spadcommand{g := csc(a*x) / csch(b*x)}
+$$
+{\csc 
+\left(
+{{a \  x}} 
+\right)}
+\over {\csch 
+\left(
+{{b \  x}} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+As you can see, the limit is expressed in terms of the parameters.
+\spadcommand{limit(g,x=0)}
+$$
+b \over a 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+A variable may also approach plus or minus infinity:
+\spadcommand{h := (1 + k/x)**x}
+$$
+{{x+k} \over x} \sp x 
+$$
+\returnType{Type: Expression Integer}
+
+Use {\tt \%plusInfinity} and {\tt \%minusInfinity} to
+denote $\infty$ and $-\infty$.
+\spadcommand{limit(h,x=\%plusInfinity)}
+$$
+e \sp k 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+A function can be defined on both sides of a particular value, but
+may tend to different limits as its variable approaches that value from the
+left and from the right.
+
+\spadcommand{limit(sqrt(y**2)/y,y = 0)}
+$$
+\left[
+{leftHandLimit=-1},  {rightHandLimit=1} 
+\right]
+$$
+\returnType{Type: Union(Record(leftHandLimit: Union(OrderedCompletion Expression Integer,"failed"),rightHandLimit: Union(OrderedCompletion Expression Integer,"failed")),...)}
+
+As $x$ approaches $0$ along the real axis, {\tt exp(-1/x**2)}
+tends to $0$.
+
+\spadcommand{limit(exp(-1/x**2),x = 0)}
+$$
+0 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+However, if $x$ is allowed to approach $0$ along any path in the
+complex plane, the limiting value of {\tt exp(-1/x**2)} depends on the
+path taken because the function has an essential singularity at $x=0$.
+This is reflected in the error message returned by the function.
+\spadcommand{complexLimit(exp(-1/x**2),x = 0)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+\section{Series}
+\label{ugIntroSeries}
+
+Axiom also provides power series.  \index{series!power} By default,
+Axiom tries to compute and display the first ten elements of a series.
+Use {\tt )set streams calculate} to change the default value to
+something else.  For the purposes of this document, we have used this
+system command to display fewer than ten terms.  For more information
+about working with series, see \ref{ugProblemSeries} on
+page~\pageref{ugProblemSeries}.
+
+You can convert a functional expression to a power series by using the
+operation {\bf series}.  In this example, {\tt sin(a*x)} is
+expanded in powers of $(x - 0)$, that is, in powers of $x$.
+\spadcommand{series(sin(a*x),x = 0)}
+$$
+{a \  x} -{{{a \sp 3} \over 6} \  {x \sp 3}}+{{{a \sp 5} \over {120}} \  {x 
+\sp 5}} -{{{a \sp 7} \over {5040}} \  {x \sp 7}}+{{{a \sp 9} \over {362880}} 
+\  {x \sp 9}} -{{{a \sp {11}} \over {39916800}} \  {x \sp {11}}}+{O 
+\left(
+{{x \sp {12}}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+This expression expands {\tt sin(a*x)} in powers of {\tt (x - \%pi/4)}.
+\spadcommand{series(sin(a*x),x = \%pi/4)}
+$$
+{\sin 
+\left({{{a \  \pi} \over 4}}\right)}+
+{a \  {\cos \left({{{a \  \pi} \over 4}} \right)}
+\  {\left( x -{\pi \over 4} \right)}}-
+\hbox{\hskip 2.0cm}
+$$
+$$
+{{{{a \sp 2} \  {\sin \left({{{a \  \pi} \over 4}} \right)}}\over 2} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 2}} -
+{{{{a \sp 3} \  {\cos \left({{{a \  \pi} \over 4}} \right)}}\over 6} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 3}} +
+$$
+$$
+{{{{a \sp 4} \  {\sin \left({{{a \  \pi} \over 4}} \right)}}\over {24}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 4}} +
+{{{{a \sp 5} \  {\cos \left({{{a \  \pi} \over 4}} \right)}}\over {120}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 5}} -
+$$
+$$
+{{{{a \sp 6} \  {\sin \left({{{a \  \pi} \over 4}} \right)}}\over {720}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 6}} -
+{{{{a \sp 7} \  {\cos \left({{{a \  \pi} \over 4}} \right)}}\over {5040}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 7}} +
+$$
+$$
+{{{{a \sp 8} \  {\sin \left({{{a \  \pi} \over 4}} \right)}}\over {40320}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 8}} +
+{{{{a \sp 9} \  {\cos \left({{{a \  \pi} \over 4}} \right)}}\over {362880}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp 9}} -
+$$
+$$
+{{{{a \sp {10}} \  {\sin \left({{{a \  \pi} \over 4}} \right)}}
+\over {3628800}} 
+\  {{\left( x -{\pi \over 4} \right)}\sp {10}}} +
+{O \left({{{\left( x -{\pi \over 4} \right)}\sp {11}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,pi/4)}
+
+Axiom provides \index{series!Puiseux} {\it Puiseux series:}
+\index{Puiseux series} series with rational number exponents.  The
+first argument to {\bf series} is an in-place function that
+computes the $n$-th coefficient.  (Recall that the
+``{\tt +->}'' is an infix operator meaning ``maps to.'')
+\spadcommand{series(n +-> (-1)**((3*n - 4)/6)/factorial(n - 1/3),x=0,4/3..,2)}
+%%NOTE: the paper book shows O(x^4) but Axiom computes O(x^5)
+$$
+{x \sp {4 \over 3}} -{{1 \over 6} \  {x \sp {{10} \over 3}}}+{O 
+\left(
+{{x \sp 5}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+Once you have created a power series, you can perform arithmetic
+operations on that series.  We compute the Taylor expansion of $1/(1-x)$.
+\index{series!Taylor}
+\spadcommand{f := series(1/(1-x),x = 0)}
+$$
+1+x+{x \sp 2}+{x \sp 3}+{x \sp 4}+{x \sp 5}+{x \sp 6}+{x \sp 7}+{x \sp 8}+{x 
+\sp 9}+{x \sp {10}}+{O 
+\left(
+{{x \sp {11}}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+Compute the square of the series.
+\spadcommand{f ** 2}
+$$
+1+{2 \  x}+{3 \  {x \sp 2}}+{4 \  {x \sp 3}}+{5 \  {x \sp 4}}+{6 \  {x \sp 
+5}}+{7 \  {x \sp 6}}+{8 \  {x \sp 7}}+{9 \  {x \sp 8}}+{{10} \  {x \sp 
+9}}+{{11} \  {x \sp {10}}}+{O 
+\left(
+{{x \sp {11}}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+The usual elementary functions
+({\bf log}, {\bf exp}, trigonometric functions, and so on)
+are defined for power series.
+\spadcommand{f := series(1/(1-x),x = 0)}
+$$
+1+x+{x \sp 2}+{x \sp 3}+{x \sp 4}+{x \sp 5}+{x \sp 6}+{x \sp 7}+{x \sp 8}+{x 
+\sp 9}+{x \sp {10}}+{O 
+\left(
+{{x \sp {11}}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{g := log(f)}
+$$
+\begin{array}{@{}l}
+x+
+{{1 \over 2} \  {x \sp 2}}+
+{{1 \over 3} \  {x \sp 3}}+
+{{1 \over 4} \  {x \sp 4}}+
+{{1 \over 5} \  {x \sp 5}}+
+{{1 \over 6} \  {x \sp 6}}+
+{{1 \over 7} \  {x \sp 7}}+
+\\
+\\
+\displaystyle
+{{1 \over 8} \  {x \sp 8}}+
+{{1 \over 9} \  {x \sp 9}}+
+{{1 \over {10}} \  {x \sp {10}}}+
+{{1 \over {11}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{exp(g)}
+$$
+1+x+{x \sp 2}+{x \sp 3}+{x \sp 4}+{x \sp 5}+{x \sp 6}+{x \sp 7}+{x \sp 8}+{x 
+\sp 9}+{x \sp {10}}+{O 
+\left(
+{{x \sp {11}}} 
+\right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+% Warning: currently there are (interpreter) problems with converting
+% rational functions and polynomials to power series.
+
+Here is a way to obtain numerical approximations of
+$e$ from the Taylor series expansion of {\bf exp}(x).
+First create the desired Taylor expansion.
+\spadcommand{f := taylor(exp(x))}
+$$
+1+x+{{1 \over 2} \  {x \sp 2}}+{{1 \over 6} \  {x \sp 3}}+{{1 \over {24}} \  
+{x \sp 4}}+{{1 \over {120}} \  {x \sp 5}}+{{1 \over {720}} \  {x \sp 6}} +
+\hbox{\hskip 1.0cm}
+$$
+$$
+{{1 
+\over {5040}} \  {x \sp 7}} + 
+{{1 \over {40320}} \  {x \sp 8}}+{{1 \over 
+{362880}} \  {x \sp 9}}+{{1 \over {3628800}} \  {x \sp {10}}}+{O 
+\left(
+{{x \sp {11}}} 
+\right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,0)}
+
+Evaluate the series at the value $1.0$.
+% Warning: syntax for evaluating power series may change.
+As you see, you get a sequence of partial sums.
+\spadcommand{eval(f,1.0)}
+$$
+\left[
+{1.0},  {2.0},  {2.5},  {2.6666666666 666666667},  \hbox{\hskip 3.0cm}
+\right.
+$$
+$${2.7083333333 333333333},  {2.7166666666 666666667},  \hbox{\hskip 1.0cm}
+$$
+$${2.7180555555 555555556},  {2.7182539682 53968254},  \hbox{\hskip 1.1cm}
+$$
+$$\left.
+{2.7182787698 412698413},  {2.7182815255 731922399},  \ldots 
+\hbox{\hskip 0.4cm}
+\right]
+$$
+\returnType{Type: Stream Expression Float}
+
+\section{Derivatives}
+\label{ugIntroCalcDeriv}
+
+Use the Axiom function {\bf D} to differentiate an
+\index{derivative} expression.  \index{differentiation}
+
+To find the derivative of an expression $f$ with respect to a
+variable $x$, enter {\bf D}(f, x).
+
+\spadcommand{f := exp exp x}
+$$
+e \sp {e \sp x} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{D(f, x)}
+$$
+{e \sp x} \  {e \sp {e \sp x}} 
+$$
+\returnType{Type: Expression Integer}
+
+An optional third argument $n$ in {\bf D} asks Axiom for the $n$-th
+derivative of $f$.  This finds the fourth derivative of $f$ with
+respect to $x$.
+
+\spadcommand{D(f, x, 4)}
+$$
+{\left( {{e \sp x} \sp 4}+{6 \  {{e \sp x} \sp 3}}+{7 \  {{e \sp x} \sp 
+2}}+{e \sp x} 
+\right)}
+\  {e \sp {e \sp x}} 
+$$
+\returnType{Type: Expression Integer}
+
+You can also compute partial derivatives by specifying the order of
+\index{differentiation!partial}
+differentiation.
+\spadcommand{g := sin(x**2 + y)}
+$$
+\sin 
+\left(
+{{y+{x \sp 2}}} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{D(g, y)}
+$$
+\cos 
+\left(
+{{y+{x \sp 2}}} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{D(g, [y, y, x, x])}
+$$
+{4 \  {x \sp 2} \  {\sin 
+\left(
+{{y+{x \sp 2}}} 
+\right)}}
+-{2 \  {\cos 
+\left(
+{{y+{x \sp 2}}} 
+\right)}}
+$$
+\returnType{Type: Expression Integer}
+
+Axiom can manipulate the derivatives (partial and iterated) of
+\index{differentiation!formal} expressions involving formal operators.
+All the dependencies must be explicit.
+
+This returns $0$ since F (so far) does not explicitly depend on $x$.
+
+\spadcommand{D(F,x)}
+$$
+0 
+$$
+\returnType{Type: Polynomial Integer}
+
+Suppose that we have F a function of $x$, $y$, and $z$,
+where $x$ and $y$ are themselves functions of $z$.
+
+Start by declaring that $F$, $x$, and $y$ are operators.
+\index{operator}
+
+\spadcommand{F := operator 'F; x := operator 'x; y := operator 'y}
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+You can use F, $x$, and $y$ in expressions.
+
+\spadcommand{a := F(x z, y z, z**2) + x y(z+1)}
+$$
+{x 
+\left(
+{{y 
+\left(
+{{z+1}} 
+\right)}}
+\right)}+{F
+\left(
+{{x 
+\left(
+{z} 
+\right)},
+ {y 
+\left(
+{z} 
+\right)},
+ {z \sp 2}} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+Differentiate formally with respect to $z$.
+The formal derivatives appearing in $dadz$ are not just formal symbols,
+but do represent the derivatives of $x$, $y$, and F.
+
+\spadcommand{dadz := D(a, z)}
+$$
+\begin{array}{@{}l}
+\displaystyle
+{2 \  z \ {{F_{, 3}}\left({{x \left({z}\right)}, {y \left({z}\right)},
+ {z^2}}\right)}}+{{{y_{\ }^{,}}\left({z}\right)}\ {{F_{, 2}}\left({{x 
+\left({z}\right)}, {y \left({z}\right)}, {z^2}}\right)}}+
+ 
+\\
+\\
+\displaystyle
+{{{x_{\ }^{,}}\left({z}\right)}\ {{F_{, 1}}\left({{x \left({z}\right)},
+ {y \left({z}\right)}, {z^2}}\right)}}+{{{x_{\ }^{,}}\left({y 
+\left({z + 1}\right)}\right)}\ {{y_{\ }^{,}}\left({z + 1}\right)}}
+\end{array}
+$$
+\returnType{Type: Expression Integer}
+
+You can evaluate the above for particular functional values of
+F, $x$, and $y$.  If $x(z)$ is {\bf exp}(z) and $y(z)$ is {\bf log}(z+1), 
+then evaluates {\tt dadz}.
+
+\spadcommand{eval(eval(dadz, 'x, z +-> exp z), 'y, z +-> log(z+1))}
+$$
+{\left(
+\begin{array}{@{}l}
+\displaystyle
+{{\left({2 \ {z^2}}+{2 \  z}\right)}\ {{F_{, 3}}\left({{e^z},
+ {\log \left({z + 1}\right)}, {z^2}}\right)}}+
+\\
+\\
+\displaystyle
+{{F_{, 2}}\left({{e^
+z}, {\log \left({z + 1}\right)}, {z^2}}\right)}+ 
+\\
+\\
+\displaystyle
+{{\left(z + 1 \right)}\ {e^z}\ {{F_{, 1}}\left({{e^z}, {\log 
+\left({z + 1}\right)}, {z^2}}\right)}}+ z + 1 
+\end{array}
+\right)}\over{z + 1}
+$$
+\returnType{Type: Expression Integer}
+
+You obtain the same result by first evaluating $a$ and
+then differentiating.
+
+\spadcommand{eval(eval(a, 'x, z +-> exp z), 'y, z +-> log(z+1))}
+$$
+{F 
+\left(
+{{e \sp z},  {\log 
+\left(
+{{z+1}} 
+\right)},
+ {z \sp 2}} 
+\right)}+z+2
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{D(\%, z)}
+$$
+{\left(
+\begin{array}{@{}l}
+\displaystyle
+{{\left({2 \ {z^2}}+{2 \  z}\right)}\ {{F_{, 3}}\left({{e^
+z}, {\log \left({z + 1}\right)}, {z^2}}\right)}}+
+\\
+\\
+\displaystyle
+{{F_{, 2}}\left({{e^z}, {\log \left({z + 1}\right)}, {z^2}}\right)}+
+\\
+\\
+\displaystyle
+{{\left(z 
++ 1 \right)}\ {e^z}\ {{F_{, 1}}\left({{e^z}, {\log \left({z 
++ 1}\right)}, {z^2}}\right)}}+ z + 1
+\end{array}
+\right)}
+\over{z + 1}
+$$
+\returnType{Type: Expression Integer}
+
+\section{Integration}
+\label{ugIntroIntegrate}
+
+Axiom has extensive library facilities for integration.
+\index{integration}
+
+The first example is the integration of a fraction with denominator
+that factors into a quadratic and a quartic irreducible polynomial.
+The usual partial fraction approach used by most other computer
+algebra systems either fails or introduces expensive unneeded
+algebraic numbers.
+
+We use a factorization-free algorithm.
+\spadcommand{integrate((x**2+2*x+1)/((x+1)**6+1),x)}
+$$
+{\arctan 
+\left(
+{{{x \sp 3}+{3 \  {x \sp 2}}+{3 \  x}+1}} 
+\right)}
+\over 3 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+When real parameters are present, the form of the integral can depend on
+the signs of some expressions.
+
+Rather than query the user or make sign assumptions, Axiom returns
+all possible answers.
+\spadcommand{integrate(1/(x**2 + a),x)}
+$$
+\left[
+{{\log 
+\left(
+{{{{{\left( {x \sp 2} -a 
+\right)}
+\  {\sqrt {-a}}}+{2 \  a \  x}} \over {{x \sp 2}+a}}} 
+\right)}
+\over {2 \  {\sqrt {-a}}}},  {{\arctan 
+\left(
+{{{x \  {\sqrt {a}}} \over a}} 
+\right)}
+\over {\sqrt {a}}} 
+\right]
+$$
+\returnType{Type: Union(List Expression Integer,...)}
+
+The {\bf integrate} operation generally assumes that all
+parameters are real.  The only exception is when the integrand has
+complex valued quantities.
+
+If the parameter is complex instead of real, then the notion of sign
+is undefined and there is a unique answer.  You can request this
+answer by ``prepending'' the word ``complex'' to the command name:
+
+\spadcommand{complexIntegrate(1/(x**2 + a),x)}
+%%NOTE: the expression in the book is different but they differentiate
+%%to exactly the same answer.
+$$
+{{\log 
+\left(
+{{{{x \  {\sqrt {-a}}}+a} \over {\sqrt {-a}}}} 
+\right)}
+-{\log 
+\left(
+{{{{x \  {\sqrt {-a}}} -a} \over {\sqrt {-a}}}} 
+\right)}}
+\over {2 \  {\sqrt {-a}}} 
+$$
+\returnType{Type: Expression Integer}
+
+The following two examples illustrate the limitations of table-based
+approaches.  The two integrands are very similar, but the answer to
+one of them requires the addition of two new algebraic numbers.
+
+This one is the easy one.
+The next one looks very similar
+but the answer is much more complicated.
+\spadcommand{integrate(x**3 / (a+b*x)**(1/3),x)}
+$$
+{{\left( {{120} \  {b \sp 3} \  {x \sp 3}} -{{135} \  a \  {b \sp 2} \  {x 
+\sp 2}}+{{162} \  {a \sp 2} \  b \  x} -{{243} \  {a \sp 3}} 
+\right)}
+\  {{\root {3} \of {{{b \  x}+a}}} \sp 2}} \over {{440} \  {b \sp 4}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Only an algorithmic approach is guaranteed to find what new constants
+must be added in order to find a solution.
+
+\spadcommand{integrate(1 / (x**3 * (a+b*x)**(1/3)),x)}
+$$
+\left(
+\begin{array}{@{}l}
+-{2 \  {b \sp 2} \  {x \sp 2} \  {\sqrt {3}} \  {\log 
+\left(
+{{{{\root {3} \of {a}} \  {{\root {3} \of {{{b \  x}+a}}} \sp 2}}+{{{\root 
+{3} \of {a}} \sp 2} \  {\root {3} \of {{{b \  x}+a}}}}+a}} 
+\right)}}+
+\\
+\\
+\displaystyle
+{4\  {b \sp 2} \  {x \sp 2} \  {\sqrt {3}} \  {\log 
+\left(
+{{{{{\root {3} \of {a}} \sp 2} \  {\root {3} \of {{{b \  x}+a}}}} -a}} 
+\right)}}+
+\\
+\\
+\displaystyle
+{{12}\  {b \sp 2} \  {x \sp 2} \  {\arctan 
+\left(
+{{{{2 \  {\sqrt {3}} \  {{\root {3} \of {a}} \sp 2} \  {\root {3} \of {{{b \  
+x}+a}}}}+{a \  {\sqrt {3}}}} \over {3 \  a}}} 
+\right)}}+
+\\
+\\
+\displaystyle
+{{\left(
+{{12} \  b \  x} -{9 \  a} 
+\right)}
+\  {\sqrt {3}} \  {\root {3} \of {a}} \  {{\root {3} \of {{{b \  x}+a}}} \sp 
+2}}
+\end{array}
+\right)
+\over {{18} \  {a \sp 2} \  {x \sp 2} \  {\sqrt {3}} \  {\root {3} \of 
+{a}}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Some computer algebra systems use heuristics or table-driven
+approaches to integration.  When these systems cannot determine the
+answer to an integration problem, they reply ``I don't know.''  Axiom
+uses an algorithm which is a {\sl decision procedure} for integration.
+If Axiom returns the original integral that conclusively proves that
+an integral cannot be expressed in terms of elementary functions.
+
+When Axiom returns an integral sign, it has proved that no answer
+exists as an elementary function.
+
+\spadcommand{integrate(log(1 + sqrt(a*x + b)) / x,x)}
+$$
+\int \sp{\displaystyle x} {{{\log 
+\left(
+{{{\sqrt {{b+{ \%Q \  a}}}}+1}} 
+\right)}
+\over \%Q} \  {d \%Q}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Axiom can handle complicated mixed functions much beyond what you
+can find in tables.
+
+Whenever possible, Axiom tries to express the answer using the
+functions present in the integrand.
+
+\spadcommand{integrate((sinh(1+sqrt(x+b))+2*sqrt(x+b)) / (sqrt(x+b) * (x + cosh(1+sqrt(x + b)))), x)}
+%%NOTE: the book has the same answer with a trailing ``+4'' term.
+%%This term is not generated by Axiom
+$$
+{2 \  {\log 
+\left(
+{{{-{2 \  {\cosh 
+\left(
+{{{\sqrt {{x+b}}}+1}} 
+\right)}}
+-{2 \  x}} \over {{\sinh 
+\left(
+{{{\sqrt {{x+b}}}+1}} 
+\right)}
+-{\cosh 
+\left(
+{{{\sqrt {{x+b}}}+1}} 
+\right)}}}}
+\right)}}
+-{2 \  {\sqrt {{x+b}}}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+A strong structure-checking algorithm in Axiom finds hidden algebraic
+relationships between functions.
+
+\spadcommand{integrate(tan(atan(x)/3),x)}
+%%NOTE: the book has a trailing ``+16'' term in the numerator
+%%This is not generated by Axiom
+$$
+\left(
+\begin{array}{@{}l}
+{8 \  {\log 
+\left(
+{{{3 \  {{\tan 
+\left(
+{{{\arctan 
+\left(
+{x} 
+\right)}
+\over 3}} 
+\right)}
+\sp 2}} -1}} 
+\right)}}
+-{3 \  {{\tan 
+\left(
+{{{\arctan 
+\left(
+{x} 
+\right)}
+\over 3}} 
+\right)}
+\sp 2}}+
+\\
+\\
+\displaystyle
+{{18} \  x \  {\tan 
+\left(
+{{{\arctan 
+\left(
+{x} 
+\right)}
+\over 3}} 
+\right)}}
+\end{array}
+\right)
+\over {18} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+The discovery of this algebraic relationship is necessary for correct
+integration of this function.
+Here are the details:
+\begin{enumerate}
+\item
+If $x=\tan t$ and $g=\tan (t/3)$ then the following 
+algebraic relation is true: $${g^3-3xg^2-3g+x=0}$$
+\item
+Integrate $g$ using this algebraic relation; this produces:
+$${{(24g^2 - 8)\log(3g^2 - 1) + (81x^2 + 24)g^2 + 72xg - 27x^2 - 16}
+\over{54g^2 - 18}}$$
+\item
+Rationalize the denominator, producing:
+$${8\log(3g^2-1) - 3g^2 + 18xg + 16} \over {18}$$
+Replace $g$ by the initial definition
+$g = \tan(\arctan(x)/3)$
+to produce the final result.
+\end{enumerate}
+
+This is an example of a mixed function where
+the algebraic layer is over the transcendental one.
+\spadcommand{integrate((x + 1) / (x*(x + log x) ** (3/2)), x)}
+$$
+-{{2 \  {\sqrt {{{\log 
+\left(
+{x} 
+\right)}+x}}}}
+\over {{\log 
+\left(
+{x} 
+\right)}+x}}
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+While incomplete for non-elementary functions, Axiom can
+handle some of them.
+\spadcommand{integrate(exp(-x**2) * erf(x) / (erf(x)**3 - erf(x)**2 - erf(x) + 1),x)}
+$$
+{{{\left( {\erf 
+\left(
+{x} 
+\right)}
+-1 
+\right)}
+\  {\sqrt {\pi}} \  {\log 
+\left(
+{{{{\erf 
+\left(
+{x} 
+\right)}
+-1} \over {{\erf 
+\left(
+{x} 
+\right)}+1}}}
+\right)}}
+-{2 \  {\sqrt {\pi}}}} \over {{8 \  {\erf 
+\left(
+{x} 
+\right)}}
+-8} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+More examples of Axiom's integration capabilities are discussed in
+Section \ref{ugProblemIntegration} on page~\pageref{ugProblemIntegration}.
+
+\section{Differential Equations}
+\label{ugIntroDiffEqns}
+The general approach used in integration also carries over to the
+solution of linear differential equations.
+
+Let's solve some differential equations.
+Let $y$ be the unknown function in terms of $x$.
+\spadcommand{y := operator 'y}
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+Here we solve a third order equation with polynomial coefficients.
+\spadcommand{deq := x**3 * D(y x, x, 3) + x**2 * D(y x, x, 2) - 2 * x * D(y x, x) + 2 * y x = 2 * x**4}
+$$
+{{{x \sp 3} \  {{y \sb {{\ }} \sp {,,,}} 
+\left(
+{x} 
+\right)}}+{{x
+\sp 2} \  {{y \sb {{\ }} \sp {,,}} 
+\left(
+{x} 
+\right)}}
+-{2 \  x \  {{y \sb {{\ }} \sp {,}} 
+\left(
+{x} 
+\right)}}+{2
+\  {y 
+\left(
+{x} 
+\right)}}}={2
+\  {x \sp 4}} 
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{solve(deq, y, x)}
+%%NOTE: the book has a different solution and it appears to be 
+%%less complicated than this one.
+$$
+\begin{array}{@{}l}
+\left[
+{particular={{{x \sp 5} -{{10} \  {x \sp 3}}+{{20} \  {x \sp 2}}+4} \over 
+{{15} \  x}}}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{basis={\left[ {{{2 \  {x \sp 3}} -{3 \  {x \sp 2}}+1} 
+\over x},  {{{x \sp 3} -1} \over x},  {{{x \sp 3} -{3 \  {x \sp 2}} -1} 
+\over x} 
+\right]}}
+\right]
+\end{array}
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: List Expression Integer),...)}
+
+
+Here we find all the algebraic function solutions of the equation.
+\spadcommand{deq := (x**2 + 1) * D(y x, x, 2) + 3 * x * D(y x, x) + y x = 0}
+$$
+{{{\left( {x \sp 2}+1 
+\right)}
+\  {{y \sb {{\ }} \sp {,,}} 
+\left(
+{x} 
+\right)}}+{3
+\  x \  {{y \sb {{\ }} \sp {,}} 
+\left(
+{x} 
+\right)}}+{y
+\left(
+{x} 
+\right)}}=0
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{solve(deq, y, x)}
+$$
+\left[
+{particular=0},  
+{basis={\left[ {1 \over {\sqrt {{{x \sp 2}+1}}}},  
+{{\log 
+\left(
+{{{\sqrt {{{x \sp 2}+1}}} -x}} 
+\right)}
+\over {\sqrt {{{x \sp 2}+1}}}} 
+\right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: List Expression Integer),...)}
+
+Coefficients of differential equations can come from arbitrary
+constant fields.  For example, coefficients can contain algebraic
+numbers.
+
+This example has solutions whose logarithmic derivative is an
+algebraic function of degree two.
+
+\spadcommand{eq := 2*x**3 * D(y x,x,2) + 3*x**2 * D(y x,x) - 2 * y x}
+$$
+{2 \  {x \sp 3} \  {{y \sb {{\ }} \sp {,,}} 
+\left(
+{x} 
+\right)}}+{3
+\  {x \sp 2} \  {{y \sb {{\ }} \sp {,}} 
+\left(
+{x} 
+\right)}}
+-{2 \  {y 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{solve(eq,y,x).basis}
+$$
+\left[
+{e \sp {\left( -{2 \over {\sqrt {x}}} 
+\right)}},
+ {e \sp {2 \over {\sqrt {x}}}} 
+\right]
+$$
+\returnType{Type: List Expression Integer}
+
+Here's another differential equation to solve.
+\spadcommand{deq := D(y x, x) = y(x) / (x + y(x) * log y x)}
+$$
+{{y \sb {{\ }} \sp {,}} 
+\left(
+{x} 
+\right)}={{y
+\left(
+{x} 
+\right)}
+\over {{{y 
+\left(
+{x} 
+\right)}
+\  {\log 
+\left(
+{{y 
+\left(
+{x} 
+\right)}}
+\right)}}+x}}
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{solve(deq, y, x)}
+$$
+{{{y 
+\left(
+{x} 
+\right)}
+\  {{\log 
+\left(
+{{y 
+\left(
+{x} 
+\right)}}
+\right)}
+\sp 2}} -{2 \  x}} \over {2 \  {y 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Rather than attempting to get a closed form solution of
+a differential equation, you instead might want to find an
+approximate solution in the form of a series.
+
+Let's solve a system of nonlinear first order equations and get a
+solution in power series.  Tell Axiom that $x$ is also an
+operator.
+
+\spadcommand{x := operator 'x}
+$$
+x 
+$$
+\returnType{Type: BasicOperator}
+
+Here are the two equations forming our system.
+\spadcommand{eq1 := D(x(t), t) = 1 + x(t)**2}
+$$
+{{x \sb {{\ }} \sp {,}} 
+\left(
+{t} 
+\right)}={{{x
+\left(
+{t} 
+\right)}
+\sp 2}+1} 
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{eq2 := D(y(t), t) = x(t) * y(t)}
+$$
+{{y \sb {{\ }} \sp {,}} 
+\left(
+{t} 
+\right)}={{x
+\left(
+{t} 
+\right)}
+\  {y 
+\left(
+{t} 
+\right)}}
+$$
+\returnType{Type: Equation Expression Integer}
+
+We can solve the system around $t = 0$ with the initial
+conditions $x(0) = 0$ and $y(0) = 1$.  Notice that since
+we give the unknowns in the order $[x, y]$, the answer is a list
+of two series in the order 
+$[{\rm series\ for\ }x(t), {\rm series\ for\ }y(t)]$.
+
+\spadcommand{seriesSolve([eq2, eq1], [x, y], t = 0, [y(0) = 1, x(0) = 0])}
+$$
+\left[
+{\ t+
+{{1 \over 3} \  {t \sp 3}}+
+{{2 \over {15}} \  {t \sp 5}}+
+{{{17} \over {315}} \  {t \sp 7}}+
+{{{62} \over {2835}} \  {t \sp 9}}+
+{O \left({{t \sp {11}}} \right)}},
+\right. 
+\hbox{\hskip 2.0cm}
+$$
+$$
+\hbox{\hskip 0.4cm}
+\left.
+{1+
+{{1 \over 2} \  {t \sp 2}}+
+{{5 \over {24}} \  {t \sp 4}}+
+{{{61} \over {720}} \  {t \sp 6}}+
+{{{277} \over {8064}} \  {t \sp 8}}+
+{{{50521} \over {3628800}} \  {t \sp {10}}}+
+{O \left({{t \sp {11}}}\right)}}
+\right]
+$$
+\returnType{Type: List UnivariateTaylorSeries(Expression Integer,t,0)}
+
+\section{Solution of Equations}
+\label{ugIntroSolution}
+Axiom also has state-of-the-art algorithms for the solution of
+systems of polynomial equations.  When the number of equations and
+unknowns is the same, and you have no symbolic coefficients, you can
+use {\bf solve} for real roots and {\bf complexSolve} for
+complex roots.  In each case, you tell Axiom how accurate you
+want your result to be.  All operations in the {\it solve} family
+return answers in the form of a list of solution sets, where each
+solution set is a list of equations.
+
+A system of two equations involving a symbolic parameter $t$.
+\spadcommand{S(t) == [x**2-2*y**2 - t,x*y-y-5*x + 5]}
+\returnType{Type: Void}
+
+Find the real roots of $S(19)$ with
+rational arithmetic, correct to within $1/10^{20}$.
+\spadcommand{solve(S(19),1/10**20)}
+$$
+\left[
+{\left[ {y=5},  {x=-{{2451682632253093442511} \over 
+{295147905179352825856}}} 
+\right]},
+\right.
+$$
+$$
+\left.
+{\left[ {y=5},  {x={{2451682632253093442511} \over 
+{295147905179352825856}}} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Polynomial Fraction Integer}
+
+Find the complex roots of $S(19)$ with floating
+point coefficients to $20$ digits accuracy in the mantissa.
+
+\spadcommand{complexSolve(S(19),10.e-20)}
+$$
+\left[
+{\left[ {y={5.0}},  {x={8.3066238629 180748526}} \right]},
+\right.
+$$
+$$
+{\left[ {y={5.0}},  {x=-{8.3066238629 180748526}} \right]},
+$$
+$$
+\left.
+{\left[ {y=-{{3.0} \  i}},  {x={1.0}} \right]},
+{\left[ {y={{3.0} \  i}},  {x={1.0}} \right]}
+\right]
+$$
+\returnType{Type: List List Equation Polynomial Complex Float}
+
+If a system of equations has symbolic coefficients and you want
+a solution in radicals, try {\bf radicalSolve}.
+\spadcommand{radicalSolve(S(a),[x,y])}
+$$
+\left[
+{\left[ {x=-{\sqrt {{a+{50}}}}}, {y=5} \right]},
+{\left[ {x={\sqrt {{a+{50}}}}}, {y=5} \right]},
+\right.
+$$
+$$
+\hbox{\hskip 0.7cm}
+\left.
+{\left[ {x=1}, {y={\sqrt {{{-a+1} \over 2}}}} \right]},
+{\left[ {x=1}, {y=-{\sqrt {{{-a+1} \over 2}}}} \right]}
+\right]
+$$
+\returnType{Type: List List Equation Expression Integer}
+
+For systems of equations with symbolic coefficients, you can apply
+{\bf solve}, listing the variables that you want Axiom to
+solve for.  For polynomial equations, a solution cannot usually be
+expressed solely in terms of the other variables.  Instead, the
+solution is presented as a ``triangular'' system of equations, where
+each polynomial has coefficients involving only the succeeding
+variables. This is analogous to converting a linear system of
+equations to ``triangular form''.
+
+A system of three equations in five variables.
+\spadcommand{eqns := [x**2 - y + z,x**2*z + x**4 - b*y, y**2 *z - a - b*x]}
+$$
+\left[
+{z -y+{x \sp 2}},  {{{x \sp 2} \  z} -{b \  y}+{x \sp 4}},  {{{y \sp 2} \  
+z} -{b \  x} -a} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+Solve the system for unknowns $[x,y,z]$,
+reducing the solution to triangular form.
+\spadcommand{solve(eqns,[x,y,z])}
+$$
+\left[
+{\left[ {x=-{a \over b}},  {y=0},  {z=-{{a \sp 2} \over {b \sp 2}}} 
+\right]},
+\right.
+\hbox{\hskip 10.0cm}
+$$
+$$
+\left.
+\begin{array}{@{}l}
+\left[
+{x={{{z \sp 3}+{2 \  b \  {z \sp 2}}+{{b \sp 2} \  z} -a} \over b}}, 
+{y={z+b}}, 
+\right.
+\hbox{\hskip 10.0cm}
+\\
+\\
+\displaystyle
+{z \sp 6}+{4 \  b \  {z \sp 5}}+
+{6 \  {b \sp 2} \  {z \sp 4}}+
+{{\left( {4 \  {b \sp 3}} -{2 \  a} \right)}\  {z \sp 3}}+
+{{\left( {b \sp 4} -{4 \  a \  b} \right)}\  {z \sp 2}}-
+\hbox{\hskip 4.0cm}
+\\
+\\
+\displaystyle
+\left.
+{2 \  a \  {b \sp 2} \  z} -{b \sp 3}+{a \sp 2}=0
+\right]
+\end{array}
+\right]
+\hbox{\hskip 7.0cm}
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+\section{System Commands}
+\label{ugIntroSysCmmands}
+We conclude our tour of Axiom with a brief discussion of
+{\it system commands}.  System commands are special statements
+that start with a closing parenthesis ({\tt )}). They are used
+to control or display your Axiom environment, start the
+HyperDoc system, issue operating system commands and leave
+Axiom.  For example, {\tt )system} is used to issue commands
+to the operating system from Axiom.  Here
+is a brief description of some of these commands.  For more
+information on specific commands, see Appendix A 
+on page~\pageref{ugSysCmd}.
+
+Perhaps the most important user command is the {\tt )clear all}
+command that initializes your environment.  Every section and
+subsection in this document has an invisible {\tt )clear all} that is
+read prior to the examples given in the section.  {\tt )clear all}
+gives you a fresh, empty environment with no user variables defined
+and the step number reset to $1$.  The {\tt )clear} command
+can also be used to selectively clear values and properties of system
+variables.
+
+Another useful system command is {\tt )read}.  A preferred way to
+develop an application in Axiom is to put your interactive
+commands into a file, say {\bf my.input} file.  To get Axiom to
+read this file, you use the system command {\tt )read my.input}.
+If you need to make changes to your approach or definitions, go into
+your favorite editor, change {\bf my.input}, then {\tt )read
+my.input} again.
+
+Other system commands include: {\tt )history}, to display
+previous input and/or output lines; {\tt )display}, to display
+properties and values of workspace variables; and {\tt )what}.
+
+Issue {\tt )what} to get a list of Axiom objects that
+contain a given substring in their name.
+\spadcommand{)what operations integrate}
+\begin{verbatim}
+
+Operations whose names satisfy the above pattern(s):
+
+HermiteIntegrate       algintegrate           complexIntegrate       
+expintegrate           extendedIntegrate      fintegrate             
+infieldIntegrate       integrate              internalIntegrate      
+internalIntegrate0     lazyGintegrate         lazyIntegrate          
+lfintegrate            limitedIntegrate       monomialIntegrate      
+nagPolygonIntegrate    palgintegrate          pmComplexintegrate     
+pmintegrate            primintegrate          tanintegrate           
+   
+To get more information about an operation such as 
+limitedIntegrate , issue the command )display op limitedIntegrate
+      
+\end{verbatim}
+
+\subsection{Undo}
+\label{ugIntroUndo}
+A useful system command is {\tt )undo}.  Sometimes while computing
+interactively with Axiom, you make a mistake and enter an
+incorrect definition or assignment.  Or perhaps you need to try one of
+several alternative approaches, one after another, to find the best
+way to approach an application.  For this, you will find the
+{\it undo} facility of Axiom helpful.
+
+System command {\tt )undo n} means ``undo back to step
+$n$''; it restores the values of user variables to those that
+existed immediately after input expression $n$ was evaluated.
+Similarly, {\tt )undo -n} undoes changes caused by the last
+$n$ input expressions.  Once you have done an {\tt )undo},
+you can continue on from there, or make a change and {\bf redo} all
+your input expressions from the point of the {\tt )undo} forward.
+The {\tt )undo} is completely general: it changes the environment
+like any user expression.  Thus you can {\tt )undo} any previous
+undo.
+
+Here is a sample dialogue between user and Axiom.
+
+``Let me define
+two mutually dependent functions $f$ and $g$ piece-wise.''
+\spadcommand{f(0) == 1; g(0) == 1}
+\returnType{Type: Void}
+
+``Here is the general term for $f$.''
+\spadcommand{f(n) == e/2*f(n-1) - x*g(n-1)}
+\returnType{Type: Void}
+
+``And here is the general term for $g$.''
+\spadcommand{g(n) == -x*f(n-1) + d/3*g(n-1)}
+\returnType{Type: Void}
+
+``What is value of $f(3)$?''
+\spadcommand{f(3)}
+$$
+-{x \sp 3}+{{\left( e+{{1 \over 3} \  d} 
+\right)}
+\  {x \sp 2}}+{{\left( -{{1 \over 4} \  {e \sp 2}} -{{1 \over 6} \  d \  e} 
+-{{1 \over 9} \  {d \sp 2}} 
+\right)}
+\  x}+{{1 \over 8} \  {e \sp 3}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+``Hmm, I think I want to define $f$ differently.
+Undo to the environment right after I defined $f$.''
+\spadcommand{)undo 2}
+
+``Here is how I think I want $f$ to be defined instead.''
+\spadcommand{f(n) == d/3*f(n-1) - x*g(n-1)}
+\begin{verbatim}
+   1 old definition(s) deleted for function or rule f 
+\end{verbatim}
+\returnType{Type: Void}
+
+Redo the computation from expression $3$ forward.
+\spadcommand{)undo )redo}
+\begin{verbatim}
+g(n) == -x*f(n-1) + d/3*g(n-1)
+ 
+                                                                   Type: Void
+f(3)
+ 
+   Compiling function g with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function g as a recurrence relation.
+
++++ |*1;g;1;G82322;AUX| redefined
+
++++ |*1;g;1;G82322| redefined
+   Compiling function g with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function g as a recurrence relation.
+
++++ |*1;g;1;G82322;AUX| redefined
+
++++ |*1;g;1;G82322| redefined
+   Compiling function f with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function f as a recurrence relation.
+
++++ |*1;f;1;G82322;AUX| redefined
+
++++ |*1;f;1;G82322| redefined
+\end{verbatim}
+$$
+-{x \sp 3}+{d \  {x \sp 2}} -{{1 \over 3} \  {d \sp 2} \  x}+{{1 \over {27}} 
+\  {d \sp 3}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+``I want my old definition of
+$f$ after all. Undo the undo and restore
+the environment to that immediately after $(4)$.''
+\spadcommand{)undo 4}
+
+``Check that the value of $f(3)$ is restored.''
+\spadcommand{f(3)}
+\begin{verbatim}
+   Compiling function g with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function g as a recurrence relation.
+
++++ |*1;g;1;G82322;AUX| redefined
+
++++ |*1;g;1;G82322| redefined
+   Compiling function g with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function g as a recurrence relation.
+
++++ |*1;g;1;G82322;AUX| redefined
+
++++ |*1;g;1;G82322| redefined
+   Compiling function f with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function f as a recurrence relation.
+
++++ |*1;f;1;G82322;AUX| redefined
+
++++ |*1;f;1;G82322| redefined
+\end{verbatim}
+$$
+-{x \sp 3}+{{\left( e+{{1 \over 3} \  d} 
+\right)}
+\  {x \sp 2}}+{{\left( -{{1 \over 4} \  {e \sp 2}} -{{1 \over 6} \  d \  e} 
+-{{1 \over 9} \  {d \sp 2}} 
+\right)}
+\  x}+{{1 \over 8} \  {e \sp 3}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+After you have gone off on several tangents, then backtracked to
+previous points in your conversation using {\tt )undo}, you might
+want to save all the ``correct'' input commands you issued,
+disregarding those undone.  The system command {\tt )history
+)write mynew.input} writes a clean straight-line program onto the file
+{\bf mynew.input} on your disk.
+
+\section{Graphics}
+\label{ugIntroGraphics}
+Axiom has a two- and three-dimensional drawing and rendering
+\index{graphics} package that allows you to draw, shade, color,
+rotate, translate, map, clip, scale and combine graphic output of
+Axiom computations.  The graphics interface is capable of
+plotting functions of one or more variables and plotting parametric
+surfaces.  Once the graphics figure appears in a window, move your
+mouse to the window and click.  A control panel appears immediately
+and allows you to interactively transform the object.
+
+This is an example of Axiom's two-dimensional plotting.
+From the 2D Control Panel you can rescale the plot, turn axes and units
+on and off and save the image, among other things.
+This PostScript image was produced by clicking on the
+{\bf PS} 2D Control Panel button.
+\spadgraph{draw(cos(5*t/8), t=0..16*\%pi, coordinates==polar)}
+% window was 256 x 256
+%\epsffile[72 72 300 300]{ps/rose-1.ps}
+\begin{figure}[htbp]
+\includegraphics[bbllx=14, bblly=14, bburx=176, bbury=186]{ps/p28a.eps}
+\caption{$J_0(\sqrt{x^2+y^2})$ for $-20 \leq x,y \leq 20$}
+\label{tpdhere}
+\end{figure}
+
+This is an example of Axiom's three-dimensional plotting.
+It is a monochrome graph of the complex arctangent
+function.
+The image displayed was rotated and had the ``shade'' and ``outline''
+display options set from the 3D Control Panel.
+The PostScript output was produced by clicking on the
+{\bf save} 3D Control Panel button and then
+clicking on the {\bf PS} button.
+See Section \ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}
+for more details and examples of Axiom's numeric and graphics capabilities.
+
+\spadgraph{draw((x,y) +-> real atan complex(x,y), -\%pi..\%pi, -\%pi..\%pi, colorFunction == (x,y) +-> argument atan complex(x,y))}
+% window was 256 x 256
+%\epsffile[72 72 285 285]{ps/atan-1.ps}
+\begin{figure}[htbp]
+\includegraphics[bbllx=14, bblly=14, bburx=175, bbury=185]{ps/p28b.eps}
+\caption{atan}
+\label{tpdhere1}
+\end{figure}
+
+An exhibit of Axiom images is given later.  For a description of the
+commands and programs that produced these figures, see
+\ref{ugAppGraphics} on page~\pageref{ugAppGraphics}.  PostScript
+\index{PostScript} output is available so that Axiom images can be
+printed.\footnote{PostScript is a trademark of Adobe Systems
+Incorporated, registered in the United States.}  See \ref{ugGraph} on
+page~\pageref{ugGraph} for more examples and details about using
+Axiom's graphics facilities.
+
+This concludes your tour of Axiom.
+To disembark, issue the system command {\tt )quit} to leave Axiom
+and return to the operating system.
+
+\setcounter{chapter}{1}
+
+\chapter{Using Types and Modes}
+\begin{quote}
+Only recently have I begun to realize that the problem is not merely
+one of technical mastery or the competent application of the rules 
+\ldots
+but that there is actually something else which is guiding these
+rules. It actually involves a different level of mastery. It's quite
+a different process to do it right; and every single act that you 
+do can be done in that sense well or badly. But even assuming that 
+you have got the technical part clear, the creation of this quality
+is a much more complicated process of the most utterly absorbing and
+fascinating dimensions. It is in fact a major creative or artistic 
+act -- every single little thing you do -- \ldots
+
+-- Christopher Alexander
+
+(from Patterns of Software by Richard Gabriel)
+
+\end{quote}
+\label{ugTypes}
+
+In this chapter we look at the key notion of {\it type} and its
+generalization {\it mode}.  We show that every Axiom object has a type
+that determines what you can do with the object.  In particular, we
+explain how to use types to call specific functions from particular
+parts of the library and how types and modes can be used to create new
+objects from old.  We also look at {\tt Record} and {\tt Union} types
+and the special type {\tt Any}.  Finally, we give you an idea of how
+Axiom manipulates types and modes internally to resolve ambiguities.
+
+\section{The Basic Idea}
+\label{ugTypesBasic}
+
+The Axiom world deals with many kinds of objects.  There are
+mathematical objects such as numbers and polynomials, data structure
+objects such as lists and arrays, and graphics objects such as points
+and graphic images.  Functions are objects too.
+
+Axiom organizes objects using the notion of domain of computation, or
+simply {\it domain}.  Each domain denotes a class of objects.  The
+class of objects it denotes is usually given by the name of the
+domain: {\tt Integer} for the integers, {\tt Float} for floating-point
+numbers, and so on.  The convention is that the first letter of a
+domain name is capitalized.  Similarly, the domain 
+{\tt Polynomial(Integer)} denotes ``polynomials with integer
+coefficients.''  Also, {\tt Matrix(Float)} denotes ``matrices with
+floating-point entries.''
+
+Every basic Axiom object belongs to a unique domain.  The integer $3$
+belongs to the domain {\tt Integer} and the polynomial $x + 3$ belongs
+to the domain {\tt Polynomial(Integer)}.  The domain of an object is
+also called its {\it type}.  Thus we speak of ``the type 
+{\tt Integer}'' and ``the type {\tt Polynomial(Integer)}.''
+
+After an Axiom computation, the type is displayed toward the
+right-hand side of the page (or screen).
+\spadcommand{-3}
+$$
+-3 
+$$
+\returnType{Type: Integer}
+
+Here we create a rational number but it looks like the last result.
+The type however tells you it is different.  You cannot identify the
+type of an object by how Axiom displays the object.
+\spadcommand{-3/1}
+$$
+-3 
+$$
+\returnType{Type: Fraction Integer}
+
+When a computation produces a result of a simpler type, Axiom leaves
+the type unsimplified.  Thus no information is lost.
+\spadcommand{x + 3 - x}
+$$
+3 
+$$
+\returnType{Type: Polynomial Integer}
+
+This seldom matters since Axiom retracts the answer to the
+simpler type if it is necessary.
+\spadcommand{factorial(\%)}
+$$
+6 
+$$
+\returnType{Type: Expression Integer}
+
+When you issue a positive number, the type {\tt PositiveInteger} is
+printed.  Surely, $3$ also has type {\tt Integer}!  The curious reader
+may now have two questions.  First, is the type of an object not
+unique?  Second, how is {\tt PositiveInteger} related to {\tt
+Integer}?
+\spadcommand{3}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+Any domain can be refined to a {\it subdomain} by a membership 
+{\tt predicate}. A {\tt predicate} is a function that, when applied to an
+object of the domain, returns either {\tt true} or {\tt false}.  For
+example, the domain {\tt Integer} can be refined to the subdomain 
+{\tt PositiveInteger}, the set of integers $x$ such that $x > 0$, by giving
+the Axiom predicate $x +-> x > 0$.  Similarly, Axiom can define
+subdomains such as ``the subdomain of diagonal matrices,'' ``the
+subdomain of lists of length two,'' ``the subdomain of monic
+irreducible polynomials in $x$,'' and so on.  Trivially, any domain is
+a subdomain of itself.
+
+While an object belongs to a unique domain, it can belong to any
+number of subdomains.  Any subdomain of the domain of an object can be
+used as the {\it type} of that object.  The type of $3$ is indeed both
+{\tt Integer} and {\tt PositiveInteger} as well as any other subdomain
+of integer whose predicate is satisfied, such as ``the prime
+integers,'' ``the odd positive integers between 3 and 17,'' and so on.
+
+\subsection{Domain Constructors}
+\label{ugTypesBasicDomainCons}
+
+In Axiom, domains are objects.  You can create them, pass them to
+functions, and, as we'll see later, test them for certain properties.
+
+In Axiom, you ask for a value of a function by applying its name
+to a set of arguments.
+
+To ask for ``the factorial of $7$'' you enter this expression to
+Axiom.  This applies the function {\tt factorial} to the value $7$ to
+compute the result.
+\spadcommand{factorial(7)}
+$$
+5040 
+$$
+\returnType{Type: PositiveInteger}
+
+Enter the type {\tt Polynomial (Integer)} as an expression to Axiom.
+This looks much like a function call as well.  It is!  The result is
+appropriately stated to be of type {\tt Domain}, which according to
+our usual convention, denotes the class of all domains.
+\spadcommand{Polynomial(Integer)}
+$$
+\mbox{\rm Polynomial Integer} 
+$$
+\returnType{Type: Domain}
+
+The most basic operation involving domains is that of building a new
+domain from a given one.  To create the domain of ``polynomials over
+the integers,'' Axiom applies the function {\tt Polynomial} to the
+domain {\tt Integer}.  A function like {\tt Polynomial} is called a
+{\it domain constructor} or, \index{constructor!domain} more simply, a
+{\it constructor}.  A domain constructor is a function that creates a
+domain.  An argument to a domain constructor can be another domain or,
+in general, an arbitrary kind of object.  {\tt Polynomial} takes a
+single domain argument while {\tt SquareMatrix} takes a positive
+integer as an argument to give its dimension and a domain argument to
+give the type of its components.
+
+What kinds of domains can you use as the argument to {\tt Polynomial}
+or {\tt SquareMatrix} or {\tt List}?  Well, the first two are
+mathematical in nature.  You want to be able to perform algebraic
+operations like ``{\tt +}'' and ``{\tt *}'' on polynomials and square
+matrices, and operations such as {\bf determinant} on square
+matrices.  So you want to allow polynomials of integers {\it and}
+polynomials of square matrices with complex number coefficients and,
+in general, anything that ``makes sense.'' At the same time, you don't
+want Axiom to be able to build nonsense domains such as ``polynomials
+of strings!''
+
+In contrast to algebraic structures, data structures can hold any kind
+of object.  Operations on lists such as \spadfunFrom{insert}{List},
+\spadfunFrom{delete}{List}, and \spadfunFrom{concat}{List} just
+manipulate the list itself without changing or operating on its
+elements.  Thus you can build {\tt List} over almost any datatype,
+including itself.
+
+Create a complicated algebraic domain.
+\spadcommand{List (List (Matrix (Polynomial (Complex (Fraction (Integer))))))}
+$$
+\mbox{\rm List List Matrix Polynomial Complex Fraction Integer} 
+$$
+\returnType{Type: Domain}
+
+Try to create a meaningless domain.
+\spadcommand{Polynomial(String)}
+\begin{verbatim}
+   Polynomial String is not a valid type.
+\end{verbatim}
+
+Evidently from our last example, Axiom has some mechanism that tells
+what a constructor can use as an argument.  This brings us to the
+notion of {\it category}.  As domains are objects, they too have a
+domain.  The domain of a domain is a category.  A category is simply a
+type whose members are domains.
+
+A common algebraic category is {\tt Ring}, the class of all domains
+that are ``rings.''  A ring is an algebraic structure with constants
+$0$ and $1$ and operations \spadopFrom{+}{Ring}, \spadopFrom{-}{Ring},
+and \spadopFrom{*}{Ring}.  These operations are assumed ``closed''
+with respect to the domain, meaning that they take two objects of the
+domain and produce a result object also in the domain.  The operations
+are understood to satisfy certain ``axioms,'' certain mathematical
+principles providing the algebraic foundation for rings.  For example,
+the {\it additive inverse axiom} for rings states: \begin{center}
+Every element $x$ has an additive inverse $y$ such that $x + y = 0$.
+\end{center} The prototypical example of a domain that is a ring is
+the integers.  Keep them in mind whenever we mention {\tt Ring}.
+
+Many algebraic domain constructors such as {\tt Complex}, 
+{\tt Polynomial}, {\tt Fraction}, take rings as arguments and return rings
+as values.  You can use the infix operator ``$has$'' to ask a domain
+if it belongs to a particular category.
+
+All numerical types are rings.  Domain constructor {\tt Polynomial}
+builds ``the ring of polynomials over any other ring.''
+\spadcommand{Polynomial(Integer) has Ring}
+$$
+{\rm true}
+$$
+\returnType{Type: Boolean}
+
+Constructor {\tt List} never produces a ring.
+\spadcommand{List(Integer) has Ring}
+$$
+{\rm false}
+$$
+\returnType{Type: Boolean}
+
+The constructor {\tt Matrix(R)} builds ``the domain of all matrices
+over the ring $R$.'' This domain is never a ring since the operations
+``{\tt +}'', ``{\tt -}'', and ``{\tt *}'' on matrices of arbitrary
+shapes are undefined.
+\spadcommand{Matrix(Integer) has Ring}
+$$
+{\rm false}
+$$
+\returnType{Type: Boolean}
+
+Thus you can never build polynomials over matrices.
+\spadcommand{Polynomial(Matrix(Integer))}
+\begin{verbatim}
+   Polynomial Matrix Integer is not a valid type.
+\end{verbatim}
+
+Use {\tt SquareMatrix(n,R)} instead.  For any positive integer $n$, it
+builds ``the ring of $n$ by $n$ matrices over $R$.''
+\spadcommand{Polynomial(SquareMatrix(7,Complex(Integer)))}
+$$
+\mbox{\rm Polynomial SquareMatrix(7,Complex Integer)} 
+$$
+\returnType{Type: Domain}
+
+Another common category is {\tt Field}, the class of all fields.
+\index{field} A field is a ring with additional operations.  For
+example, a field has commutative multiplication and a closed operation
+\spadopFrom{/}{Field} for the division of two elements.  {\tt Integer}
+is not a field since, for example, $3/2$ does not have an integer
+result.  The prototypical example of a field is the rational numbers,
+that is, the domain {\tt Fraction(Integer)}.  In general, the
+constructor {\tt Fraction} takes an IntegralDomain, which is a ring
+with additional properties, as an argument and returns a field. 
+\footnote{Actually, the argument domain must have some additional
+so as to belong to the category {\tt IntegralDomain}}
+Other domain constructors, such as {\tt Complex}, build fields only if their
+argument domain is a field.
+
+The complex integers (often called the ``Gaussian integers'') do not form
+a field.
+\spadcommand{Complex(Integer) has Field}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+But fractions of complex integers do.
+\spadcommand{Fraction(Complex(Integer)) has Field}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+The algebraically equivalent domain of complex rational numbers is a field
+since domain constructor {\tt Complex} produces a field whenever its
+argument is a field.
+\spadcommand{Complex(Fraction(Integer)) has Field}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+The most basic category is {\tt Type}.  \index{Type} It denotes the
+class of all domains and subdomains. Note carefully that {\tt Type}
+does not denote the class of all types.  The type of all categories is
+{\tt Category}.  The type of {\tt Type} itself is undefined.  Domain
+constructor {\tt List} is able to build ``lists of elements from
+domain $D$'' for arbitrary $D$ simply by requiring that $D$ belong to
+category {\tt Type}.
+
+Now, you may ask, what exactly is a category?  \index{category} Like
+domains, categories can be defined in the Axiom language.  A category
+is defined by three components:
+%
+\begin{enumerate}
+\item a name (for example, {\tt Ring}),
+used to refer to the class of domains that the category represents;
+\item a set of operations, used to refer to the operations that
+the domains of this class support
+(for example, ``{\tt +}'', ``{\tt -}'', and ``{\tt *}'' for rings); and
+\item an optional list of other categories that this category extends.
+\end{enumerate}
+%
+This last component is a new idea.  And it is key to the design of
+Axiom!  Because categories can extend one another, they form
+hierarchies.  Detailed charts showing the category hierarchies
+in Axiom are displayed in Appendix (TPDHERE).  There you see
+that all categories are extensions of {\tt Type} and that {\tt Field}
+is an extension of {\tt Ring}.
+
+The operations supported by the domains of a category are called the
+{\sl exports} of that category because these are the operations made
+available for system-wide use.  The exports of a domain of a given
+category are not only the ones explicitly mentioned by the category.
+Since a category extends other categories, the operations of these
+other categories---and all categories these other categories
+extend---are also exported by the domains.
+
+For example, polynomial domains belong to {\tt PolynomialCategory}.
+This category explicitly mentions some twenty-nine operations on
+polynomials, but it extends eleven other categories (including 
+{\tt Ring}).  As a result, the current system has over one hundred
+operations on polynomials.
+
+If a domain belongs to a category that extends, say, {\tt Ring}, it is
+convenient to say that the domain exports {\tt Ring}.  The name of the
+category thus provides a convenient shorthand for the list of
+operations exported by the category.  Rather than listing operations
+such as \spadopFrom{+}{Ring} and \spadopFrom{*}{Ring} of {\tt Ring}
+each time they are needed, the definition of a type simply asserts
+that it exports category {\tt Ring}.
+
+The category name, however, is more than a shorthand.  The name 
+{\tt Ring}, in fact, implies that the operations exported by rings are
+required to satisfy a set of ``axioms'' associated with the name 
+{\tt Ring}. This subtle but important feature distinguishes Axiom from
+other abstract datatype designs.
+
+Why is it not correct to assume that some type is a ring if it exports
+all of the operations of {\tt Ring}?  Here is why.  Some languages
+such as {\bf APL} \index{APL} denote the {\tt Boolean} constants
+{\tt true} and {\tt false} by the integers $1$ and $0$ respectively, then use
+``{\tt +}'' and ``{\tt *}'' to denote the logical operators {\bf or} and
+{\bf and}.  But with these definitions {\tt Boolean} is not a
+ring since the additive inverse axiom is violated. That is, there is
+no inverse element $a$ such that $1 + a = 0$, or, in the usual terms:
+{\tt true or a = false}.  This alternative definition of {\tt Boolean}
+can be easily and correctly implemented in Axiom, since {\tt Boolean}
+simply does not assert that it is of category {\tt Ring}.  This
+prevents the system from building meaningless domains such as 
+{\tt Polynomial(Boolean)} and then wrongfully applying algorithms that
+presume that the ring axioms hold.
+
+Enough on categories. To learn more about them, see Chapter
+\ref{ugCategories} on page~\pageref{ugCategories}.  
+We now return to our discussion of domains.
+
+Domains {\it export} a set of operations to make them available for
+system-wide use.  {\tt Integer}, for example, exports the operations
+\spadopFrom{+}{Integer} and \spadopFrom{=}{Integer} given by the
+signatures \spadopFrom{+}{Integer}:
+\spadsig{(Integer,Integer)}{Integer} and \spadopFrom{=}{Integer}:
+\spadsig{(Integer,Integer)}{Boolean}, respectively.  Each of these
+operations takes two {\tt Integer} arguments.  The
+\spadopFrom{+}{Integer} operation also returns an {\tt Integer} but
+\spadopFrom{=}{Integer} returns a {\tt Boolean}: {\tt true} or {\tt false}.
+The operations exported by a domain usually manipulate objects of the
+domain---but not always.
+
+The operations of a domain may actually take as arguments, and return
+as values, objects from any domain.  For example, {\tt Fraction
+(Integer)} exports the operations \spadopFrom{/}{Fraction}:
+\spadsig{(Integer,Integer)}{Fraction(Integer)} and
+\spadfunFrom{characteristic}{Fraction}:
+\spadsig{}{NonNegativeInteger}.
+
+Suppose all operations of a domain take as arguments and return as
+values, only objects from {\it other} domains.  \index{package} This
+kind of domain \index{constructor!package} is what Axiom calls a {\it
+package}.
+
+A package does not designate a class of objects at all.  Rather, a
+package is just a collection of operations.  Actually the bulk of the
+Axiom library of algorithms consists of packages.  The facilities for
+factorization; integration; solution of linear, polynomial, and
+differential equations; computation of limits; and so on, are all
+defined in packages.  Domains needed by algorithms can be passed to a
+package as arguments or used by name if they are not ``variable.''
+Packages are useful for defining operations that convert objects of
+one type to another, particularly when these types have different
+parameterizations.  As an example, the package {\tt PolynomialFunction2(R,S)} 
+defines operations that convert polynomials
+over a domain $R$ to polynomials over $S$.  To convert an object from
+{\tt Polynomial(Integer)} to {\tt Polynomial(Float)}, Axiom builds the
+package {\tt PolynomialFunctions2(Integer,Float)} in order to create
+the required conversion function.  (This happens ``behind the scenes''
+for you: see \ref{ugTypesConvert} on page~\pageref{ugTypesConvert}
+for details on how to convert objects.)
+
+Axiom categories, domains and packages and all their contained
+functions are written in the Axiom programming language and have been
+compiled into machine code.  This is what comprises the Axiom 
+{\it library}.  We will show you how to use these
+domains and their functions and how to write your own functions.
+
+\section{Writing Types and Modes}
+\label{ugTypesWriting}
+
+We have already seen in the last section \ref{ugTypesBasic} on
+page~\pageref{ugTypesBasic} several examples of types.  Most of these
+examples had either no arguments (for example, {\tt Integer}) or one
+argument (for example, {\tt Polynomial (Integer)}).  In this section
+we give details about writing arbitrary types.  We then define modes
+and discuss how to write them.  We conclude the section with a
+discussion on constructor abbreviations.
+
+When might you need to write a type or mode?  You need to do so when
+you declare variables.
+\spadcommand{a : PositiveInteger}
+\returnType{Type: Void}
+
+You need to do so when you declare functions 
+(See Section \ref{ugTypesDeclare} on page~\pageref{ugTypesDeclare}),
+\spadcommand{f : Integer -> String}
+\returnType{Type: Void}
+
+You need to do so when you convert an object from one type to another
+(See Section \ref{ugTypesConvert} on page~\pageref{ugTypesConvert}).
+\spadcommand{factor(2 :: Complex(Integer))}
+$$
+-{i \  {{\left( 1+i 
+\right)}
+\sp 2}} 
+$$
+\returnType{Type: Factored Complex Integer}
+
+\spadcommand{(2 = 3)\$Integer}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+You need to do so when you give computation target type information
+(See Section \ref{ugTypesPkgCall} on page~\pageref{ugTypesPkgCall}).
+\spadcommand{(2 = 3)@Boolean}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\subsection{Types with No Arguments}
+\label{ugTypesWritingZero}
+
+A constructor with no arguments can be written either
+\index{type!using parentheses} with or without
+\index{parentheses!using with types} trailing opening and closing
+parentheses ``{\tt ()}''.
+
+\begin{center}
+{\tt Boolean()} is the same as {\tt Boolean} \\
+{\tt Integer()} is the same as {\tt Integer} \\
+{\tt String()} is the same as {\tt String} \\
+{\tt Void()} is the same as {\tt Void} 
+\end{center}
+
+It is customary to omit the parentheses.
+
+\subsection{Types with One Argument}
+\label{ugTypesWritingOne}
+
+A constructor with one argument can frequently be 
+\index{type!using parentheses} written with no 
+\index{parentheses!using with types} parentheses.  Types nest from 
+right to left so that {\tt Complex Fraction Polynomial Integer} 
+is the same as {\tt Complex (Fraction (Polynomial (Integer)))}.  
+You need to use parentheses to force the application of a constructor 
+to the correct argument, but you need not use any more than is necessary 
+to remove ambiguities.
+
+Here are some guidelines for using parentheses (they are possibly slightly
+more restrictive than they need to be).
+
+If the argument is an expression like $2 + 3$
+then you must enclose the argument in parentheses.
+\spadcommand{e : PrimeField(2 + 3)}
+\returnType{Type: Void}
+
+If the type is to be used with package calling
+then you must enclose the argument in parentheses.
+\spadcommand{content(2)\$Polynomial(Integer)}
+$$
+2 
+$$
+\returnType{Type: Integer}
+
+Alternatively, you can write the type without parentheses
+then enclose the whole type expression with parentheses.
+\spadcommand{content(2)\$(Polynomial Complex Fraction Integer)}
+$$
+2 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+If you supply computation target type information 
+(See Section \ref{ugTypesPkgCall} on page~\pageref{ugTypesPkgCall}) 
+then you should enclose the argument in parentheses.
+\spadcommand{(2/3)@Fraction(Polynomial(Integer))}
+$$
+2 \over 3 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+If the type itself has parentheses around it and we are not in the
+case of the first example above, then the parentheses can usually be
+omitted.
+\spadcommand{(2/3)@Fraction(Polynomial Integer)}
+$$
+2 \over 3 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+If the type is used in a declaration and the argument is a single-word
+type, integer or symbol, then the parentheses can usually be omitted.
+\spadcommand{(d,f,g) : Complex Polynomial Integer}
+\returnType{Type: Void}
+
+\subsection{Types with More Than One Argument}
+\label{ugTypesWritingMore}
+
+If a constructor \index{type!using parentheses} has more than
+\index{parentheses!using with types} one argument, you must use
+parentheses.  Some examples are \\
+
+{\tt UnivariatePolynomial(x, Float)} \\ 
+{\tt MultivariatePolynomial([z,w,r], Complex Float)} \\ 
+{\tt SquareMatrix(3, Integer)} \\ 
+{\tt FactoredFunctions2(Integer,Fraction Integer)} 
+
+\subsection{Modes}
+\label{ugTypesWritingModes}
+
+A {\it mode} is a type that possibly is a question mark ({\tt ?}) or
+contains one in an argument position.  For example, the following are
+all modes.\\
+
+{\tt ?} \\
+{\tt Polynomial ?} \\
+{\tt Matrix Polynomial ?} \\
+{\tt SquareMatrix(3,?)} \\
+{\tt Integer} \\
+{\tt OneDimensionalArray(Float)}
+
+As is evident from these examples, a mode is a type with a part that
+is not specified (indicated by a question mark).  Only one ``{\tt ?}'' is
+allowed per mode and it must appear in the most deeply nested argument
+that is a type. Thus {\tt ?(Integer)}, {\tt Matrix(? (Polynomial))},
+{\tt SquareMatrix(?, Integer)} (it requires a numeric argument)
+and {\tt SquareMatrix(?, ?)} are all
+invalid.  The question mark must take the place of a domain, not data.
+This rules out, for example, the two {\tt SquareMatrix} expressions.
+
+Modes can be used for declarations (See Section \ref{ugTypesDeclare}
+on page~\pageref{ugTypesDeclare}) and conversions (Section
+\ref{ugTypesConvert} on page~\pageref{ugTypesConvert}).  However, you
+cannot use a mode for package calling or giving target type information.
+
+\subsection{Abbreviations}
+\label{ugTypesWritingAbbr}
+
+Every constructor has an abbreviation that
+\index{abbreviation!constructor} you can freely
+\index{constructor!abbreviation} substitute for the constructor name.
+In some cases, the abbreviation is nothing more than the capitalized
+version of the constructor name.
+
+\boxed{4.6in}{
+
+\vskip 0.1cm
+Aside from allowing types to be written more concisely, abbreviations
+are used by Axiom to name various system files for constructors (such
+as library filenames, test input files and example files).  Here are
+some common abbreviations.
+
+\begin{center}
+\begin{tabular}{ll}
+\small{\tt COMPLEX}   abbreviates {\tt Complex}             &
+\small{\tt DFLOAT}    abbreviates {\tt DoubleFloat}         \\
+\small{\tt EXPR}      abbreviates {\tt Expression}          &
+\small{\tt FLOAT}     abbreviates {\tt Float}               \\
+\small{\tt FRAC}      abbreviates {\tt Fraction}            &
+\small{\tt INT}       abbreviates {\tt Integer}             \\
+\small{\tt MATRIX}    abbreviates {\tt Matrix}              &
+\small{\tt NNI}       abbreviates {\tt NonNegativeInteger}  \\
+\small{\tt PI}        abbreviates {\tt PositiveInteger}     &
+\small{\tt POLY}      abbreviates {\tt Polynomial}          \\
+\small{\tt STRING}    abbreviates {\tt String}              &
+\small{\tt UP}        abbreviates {\tt UnivariatePolynomial}\\
+\end{tabular}
+\end{center}
+\vskip 0.1cm
+}
+
+You can combine both full constructor names and abbreviations in a
+type expression.  Here are some types using abbreviations.
+
+\begin{center}
+\begin{tabular}{rcl}
+{\tt POLY INT} & is the same as & {\tt Polynomial(INT)} \\
+{\tt POLY(Integer)} & is the same as & {\tt Polynomial(Integer)} \\
+{\tt POLY(Integer)} & is the same as & {\tt Polynomial(INT)} \\
+{\tt FRAC(COMPLEX(INT))} & is the same as & {\tt Fraction Complex Integer} \\
+{\tt FRAC(COMPLEX(INT))} & is the same as & {\tt FRAC(Complex Integer)} 
+\end{tabular}
+\end{center}
+
+There are several ways of finding the names of constructors and their
+abbreviations.  For a specific constructor, use {\tt )abbreviation
+query}.  \index{abbreviation} You can also use the {\tt )what} system
+command to see the names and abbreviations of constructors.
+\index{what} For more information about {\tt )what}, see
+\ref{ugSysCmdwhat} on page~\pageref{ugSysCmdwhat}.
+
+{\tt )abbreviation query} can be abbreviated (no pun intended) to 
+{\tt )abb q}.
+\spadcommand{)abb q Integer}
+\begin{verbatim}
+   INT abbreviates domain Integer 
+\end{verbatim}
+
+The {\tt )abbreviation query} command lists the constructor name if
+you give the abbreviation.  Issue {\tt )abb q} if you want to see the
+names and abbreviations of all Axiom constructors.  
+\spadcommand{)abb q DMP} 
+\begin{verbatim}
+   DMP abbreviates domain DistributedMultivariatePolynomial 
+\end{verbatim}
+
+Issue this to see all packages whose
+names contain the string ``ode''.  \index{what packages}
+\spadcommand{)what packages ode}
+\begin{verbatim}
+---------------------- Packages -----------------------
+
+Packages with names matching patterns:
+     ode 
+
+ EXPRODE  ExpressionSpaceODESolver     
+ FCPAK1   FortranCodePackage1
+ GRAY     GrayCode                     
+ LODEEF   ElementaryFunctionLODESolver
+ NODE1    NonLinearFirstOrderODESolver 
+ ODECONST ConstantLODE
+ ODEEF    ElementaryFunctionODESolver  
+ ODEINT   ODEIntegration
+ ODEPAL   PureAlgebraicLODE            
+ ODERAT   RationalLODE
+ ODERED   ReduceLODE                   
+ ODESYS   SystemODESolver
+ ODETOOLS ODETools
+ UTSODE   UnivariateTaylorSeriesODESolver
+ UTSODETL UTSodetools
+\end{verbatim}
+
+\section{Declarations}
+\label{ugTypesDeclare}
+
+A {\it declaration} is an expression used to restrict the type of
+values that can be assigned to variables.  A colon ``{\tt :}'' is always
+used after a variable or list of variables to be declared.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+For a single variable, the syntax for declaration is
+\begin{center}
+{\it variableName $:$ typeOrMode}
+\end{center}
+
+For multiple variables, the syntax is
+\begin{center}
+{\tt ($\hbox{\it variableName}_{1}$, $\hbox{\it variableName}_{2}$, 
+\ldots $\hbox{\it variableName}_{N}$): {\it typeOrMode}}
+\end{center}
+\vskip 0.1cm
+}
+
+You can always combine a declaration with an assignment.  When you do,
+it is equivalent to first giving a declaration statement, then giving
+an assignment.  For more information on assignment, see
+Section \ref{ugIntroAssign} on page~\pageref{ugIntroAssign} and 
+Section \ref{ugLangAssign} on page~\pageref{ugLangAssign}.  
+To see how to declare your own functions, 
+see \ref{ugUserDeclare} on page~\pageref{ugUserDeclare}.
+
+This declares one variable to have a type.
+\spadcommand{a : Integer}
+\returnType{Type: Void}
+
+This declares several variables to have a type.
+\spadcommand{(b,c) : Integer}
+\returnType{Type: Void}
+
+$a$, $b$ and $c$ can only hold integer values.
+\spadcommand{a := 45}
+$$
+45 
+$$
+\returnType{Type: Integer}
+
+If a value cannot be converted to a declared type,
+an error message is displayed.
+\spadcommand{b := 4/5}
+\begin{verbatim}
+ 
+   Cannot convert right-hand side of assignment
+   4
+   -
+   5
+
+      to an object of the type Integer of the left-hand side.
+\end{verbatim}
+
+This declares a variable with a mode.
+\spadcommand{n : Complex ?}
+\returnType{Type: Void}
+
+This declares several variables with a mode.
+\spadcommand{(p,q,r) : Matrix Polynomial ?}
+\returnType{Type: Void}
+
+This complex object has integer real and imaginary parts.
+\spadcommand{n := -36 + 9 * \%i}
+$$
+-{36}+{9 \  i} 
+$$
+\returnType{Type: Complex Integer}
+
+This complex object has fractional symbolic real and imaginary parts.
+\spadcommand{n := complex(4/(x + y),y/x)}
+$$
+{4 \over {y+x}}+{{y \over x} \  i} 
+$$
+\returnType{Type: Complex Fraction Polynomial Integer}
+
+This matrix has entries that are polynomials with integer
+coefficients.
+\spadcommand{p := [ [1,2],[3,4],[5,6] ]}
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+3 & 4 \\ 
+5 & 6 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Integer}
+
+This matrix has a single entry that is a polynomial with
+rational number coefficients.
+\spadcommand{q := [ [x - 2/3] ]}
+$$
+\left[
+\begin{array}{c}
+{x -{2 \over 3}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Fraction Integer}
+
+This matrix has entries that are polynomials with complex integer
+coefficients.
+
+\spadcommand{r := [ [1-\%i*x,7*y+4*\%i] ]}
+$$
+\left[
+\begin{array}{cc}
+{-{i \  x}+1} & {{7 \  y}+{4 \  i}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Complex Integer}
+
+Note the difference between this and the next example.
+This is a complex object with polynomial real and imaginary parts.
+
+\spadcommand{f : COMPLEX POLY ? := (x + y*\%i)**2}
+$$
+-{y \sp 2}+{x \sp 2}+{2 \  x \  y \  i} 
+$$
+\returnType{Type: Complex Polynomial Integer}
+
+This is a polynomial with complex integer coefficients.  The objects
+are convertible from one to the other.  See \ref{ugTypesConvert} on
+page~\pageref{ugTypesConvert} for more information.
+
+\spadcommand{g : POLY COMPLEX ? := (x + y*\%i)**2}
+$$
+-{y \sp 2}+{2 \  i \  x \  y}+{x \sp 2} 
+$$
+\returnType{Type: Polynomial Complex Integer}
+
+\section{Records}
+\label{ugTypesRecords}
+
+A {\tt Record} is an object composed of one or more other objects,
+\index{Record} each of which is referenced \index{selector!record}
+with \index{record!selector} a {\it selector}.  Components can all
+belong to the same type or each can have a different type.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for writing a {\tt Record} type is \begin{center} {\tt
+Record($\hbox{\it selector}_{1}$:$\hbox{\it type}_{1}$,
+$\hbox{\it selector}_{2}$:$\hbox{\it type}_{2}$, \ldots,
+$\hbox{\it selector}_{N}$:$\hbox{\it type}_{N}$)} \end{center} You must be
+careful if a selector has the same name as a variable in the
+workspace.  If this occurs, precede the selector name by a single
+\index{quote} quote.\\
+}
+
+Record components are implicitly ordered.  All the components of a
+record can be set at once by assigning the record a bracketed {\it
+tuple} of values of the proper length. For example:
+\spadcommand{r : Record(a:Integer, b: String) := [1, "two"]}  
+$$
+\left[
+{a=1},  {b= \mbox{\tt "two"} } 
+\right]
+$$
+\returnType{Type: Record(a: Integer,b: String)}
+To access a component of a record $r$, write the name $r$, followed by
+a period, followed by a selector.
+
+The object returned by this computation is a record with two components: a
+$quotient$ part and a $remainder$ part.
+\spadcommand{u := divide(5,2)}
+$$
+\left[
+{quotient=2},  {remainder=1} 
+\right]
+$$
+\returnType{Type: Record(quotient: Integer,remainder: Integer)}
+
+This is the quotient part.
+\spadcommand{u.quotient}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the remainder part.
+\spadcommand{u.remainder}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+You can use selector expressions on the left-hand side of an assignment
+to change destructively the components of a record.
+\spadcommand{u.quotient := 8978}
+$$
+8978 
+$$
+\returnType{Type: PositiveInteger}
+
+The selected component $quotient$ has the value $8978$, which is what
+is returned by the assignment.  Check that the value of $u$ was
+modified.
+\spadcommand{u}
+$$
+\left[
+{quotient={8978}},  {remainder=1} 
+\right]
+$$
+\returnType{Type: Record(quotient: Integer,remainder: Integer)}
+
+Selectors are evaluated.  Thus you can use variables that evaluate to
+selectors instead of the selectors themselves.
+\spadcommand{s := 'quotient}
+$$
+quotient 
+$$
+\returnType{Type: Variable quotient}
+
+Be careful!  A selector could have the same name as a variable in the
+workspace.  If this occurs, precede the selector name by a single
+quote, as in $u.'quotient$.  \index{selector!quoting}
+\spadcommand{divide(5,2).s}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+Here we declare that the value of $bd$ has two components: a string,
+to be accessed via {\tt name}, and an integer, to be accessed via
+{\tt birthdayMonth}.
+\spadcommand{bd : Record(name : String, birthdayMonth : Integer)}
+\returnType{Type: Void}
+
+You must initially set the value of the entire {\tt Record} at once.
+\spadcommand{bd := ["Judith", 3]}
+$$
+\left[
+{name= \mbox{\tt "Judith"} },  {birthdayMonth=3} 
+\right]
+$$
+\returnType{Type: Record(name: String,birthdayMonth: Integer)}
+
+Once set, you can change any of the individual components.
+\spadcommand{bd.name := "Katie"}
+$$
+\mbox{\tt "Katie"} 
+$$
+\returnType{Type: String}
+
+Records may be nested and the selector names can be shared at
+different levels.
+\spadcommand{r : Record(a : Record(b: Integer, c: Integer), b: Integer)}
+\returnType{Type: Void}
+
+The record $r$ has a $b$ selector at two different levels.
+Here is an initial value for $r$.
+\spadcommand{r := [ [1,2], 3 ]}
+$$
+\left[
+{a={\left[ {b=1},  {c=2} 
+\right]}},
+ {b=3} 
+\right]
+$$
+\returnType{Type: Record(a: Record(b: Integer,c: Integer),b: Integer)}
+
+This extracts the $b$ component from the $a$ component of $r$.
+\spadcommand{r.a.b}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+This extracts the $b$ component from $r$.
+\spadcommand{r.b}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+You can also use spaces or parentheses to refer to {\tt Record}
+components.  This is the same as $r.a$.
+\spadcommand{r(a)}
+$$
+\left[
+{b=1},  {c=2} 
+\right]
+$$
+\returnType{Type: Record(b: Integer,c: Integer)}
+This is the same as $r.b$.
+\spadcommand{r b}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the same as $r.b := 10$.
+\spadcommand{r(b) := 10}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+Look at $r$ to make sure it was modified.
+\spadcommand{r}
+$$
+\left[
+{a={\left[ {b=1},  {c=2} 
+\right]}},
+ {b={10}} 
+\right]
+$$
+\returnType{Type: Record(a: Record(b: Integer,c: Integer),b: Integer)}
+
+\section{Unions}
+\label{ugTypesUnions}
+
+Type {\tt Union} is used for objects that can be of any of a specific
+finite set of types.  \index{Union} Two versions of unions are
+available, one with selectors (like records) and one without.
+\index{union}
+
+\subsection{Unions Without Selectors}
+\label{ugTypesUnionsWOSel}
+
+The declaration $x : Union(Integer, String, Float)$ states that $x$
+can have values that are integers, strings or ``big'' floats.  If, for
+example, the {\tt Union} object is an integer, the object is said to
+belong to the {\tt Integer} {\it branch} of the {\tt Union}.  Note
+that we are being a bit careless with the language here.  Technically,
+the type of $x$ is always {\tt Union(Integer, String, Float)}.  If it
+belongs to the {\tt Integer} branch, $x$ may be converted to an object
+of type {\tt Integer}.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for writing a {\tt Union} type without selectors is
+\begin{center}
+{\tt Union($\hbox{\it type}_{1}$, $\hbox{\it type}_{2}$, 
+\ldots, $\hbox{\it type}+{N}$)}
+\end{center}
+The types in a union without selectors must be distinct.\\
+}
+
+It is possible to create unions like {\tt Union(Integer, PositiveInteger)} 
+but they are difficult to work with because of the overlap in the branch 
+types.  See below for the rules Axiom uses for converting something into 
+a union object.
+
+The {\tt case} infix \index{case} operator returns a {\tt Boolean} and can
+be used to determine the branch in which an object lies.
+
+This function displays a message stating in which branch of the 
+{\tt Union} the object (defined as $x$ above) lies.
+
+\begin{verbatim}
+sayBranch(x : Union(Integer,String,Float)) : Void  ==
+  output
+    x case Integer => "Integer branch"
+    x case String  => "String branch"
+    "Float branch"
+\end{verbatim}
+
+This tries {\bf sayBranch} with an integer.
+\spadcommand{sayBranch 1}
+\begin{verbatim}
+Compiling function sayBranch with type Union(Integer,String,Float)
+    -> Void 
+ Integer branch
+\end{verbatim}
+\returnType{Type: Void}
+
+This tries {\bf sayBranch} with a string.
+\spadcommand{sayBranch "hello"}
+\begin{verbatim}
+   String branch
+\end{verbatim}
+\returnType{Type: Void}
+
+This tries {\bf sayBranch} with a floating-point number.
+\spadcommand{sayBranch 2.718281828}
+\begin{verbatim}
+   Float branch
+\end{verbatim}
+\returnType{Type: Void}
+
+There are two things of interest about this particular
+example to which we would like to draw your attention.
+\begin{enumerate}
+\item Axiom normally converts a result to the target value
+before passing it to the function.
+If we left the declaration information out of this function definition
+then the {\bf sayBranch} call would have been attempted with an
+{\tt Integer} rather than a {\tt Union}, and an error would have
+resulted.
+\item The types in a {\tt Union} are searched in the order given.
+So if the type were given as
+
+%\noindent
+{\tt sayBranch(x: Union(String,Integer,Float,Any)): Void}
+
+then the result would have been ``String branch'' because there
+is a conversion from {\tt Integer} to {\tt String}.
+\end{enumerate}
+
+Sometimes {\tt Union} types can have extremely long names.  Axiom
+therefore abbreviates the names of unions by printing the type of the
+branch first within the {\tt Union} and then eliding the remaining
+types with an ellipsis ({\tt ...}).
+
+Here the {\tt Integer} branch is displayed first.  Use ``{\tt ::}'' to
+create a {\tt Union} object from an object.
+\spadcommand{78 :: Union(Integer,String)}
+$$
+78 
+$$
+\returnType{Type: Union(Integer,...)}
+
+Here the {\tt String} branch is displayed first.
+\spadcommand{s := "string" :: Union(Integer,String)}
+$$
+\mbox{\tt "string"} 
+$$
+\returnType{Type: Union(String,...)}
+
+Use {\tt typeOf} to see the full and actual {\tt Union} type. \index{typeOf}
+\spadcommand{typeOf s}
+$$
+Union(Integer,String) 
+$$
+\returnType{Type: Domain}
+
+A common operation that returns a union is \spadfunFrom{exquo}{Integer}
+which returns the ``exact quotient'' if the quotient is exact,
+\spadcommand{three := exquo(6,2)}
+$$
+3 
+$$
+\returnType{Type: Union(Integer,...)}
+
+and {\tt "failed"} if the quotient is not exact.
+\spadcommand{exquo(5,2)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+A union with a {\tt "failed"} is frequently used to indicate the failure
+or lack of applicability of an object.  As another example, assign an
+integer a variable $r$ declared to be a rational number.
+\spadcommand{r: FRAC INT := 3}
+$$
+3 
+$$
+\returnType{Type: Fraction Integer}
+
+The operation \spadfunFrom{retractIfCan}{Fraction} tries to retract
+the fraction to the underlying domain {\tt Integer}.  It produces a
+union object.  Here it succeeds.
+\spadcommand{retractIfCan(r)}
+$$
+3 
+$$
+\returnType{Type: Union(Integer,...)}
+
+Assign it a rational number.
+\spadcommand{r := 3/2}
+$$
+3 \over 2 
+$$
+\returnType{Type: Fraction Integer}
+
+Here the retraction fails.
+\spadcommand{retractIfCan(r)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+\subsection{Unions With Selectors}
+\label{ugTypesUnionsWSel}
+
+Like records (\ref{ugTypesRecords} on page~\pageref{ugTypesRecords}),
+you can write {\tt Union} types \index{selector!union} with selectors.
+\index{union!selector}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for writing a {\tt Union} type with selectors is
+\begin{center}
+{\tt Union($\hbox{\it selector}_{1}$:$\hbox{\it type}_{1}$, 
+$\hbox{\it selector}_{2}$:$\hbox{\it type}_{2}$, \ldots, 
+$\hbox{\it selector}_{N}$:$\hbox{\it type}_{N}$)}
+\end{center}
+You must be careful if a selector has the same name as a variable in
+the workspace.  If this occurs, precede the selector name by a single
+\index{quote} quote.  \index{selector!quoting} It is an error to use a
+selector that does not correspond to the branch of the {\tt Union} in
+which the element actually lies.  \\
+}
+
+Be sure to understand the difference between records and unions with
+selectors.  \index{union!difference from record} Records can have more
+than one component and the selectors are used to refer to the
+components.  \index{record!difference from union} Unions always have
+one component but the type of that one component can vary.  An object
+of type {\tt Record(a: Integer, b: Float, c: String)} contains an
+integer {\it and} a float {\it and} a string.  An object of type 
+{\tt Union(a: Integer, b: Float, c: String)} contains an integer 
+{\it or} a float {\it or} a string.
+
+Here is a version of the {\bf sayBranch} function (cf.
+\ref{ugTypesUnionsWOSel} on page~\pageref{ugTypesUnionsWOSel}) that
+works with a union with selectors.  It displays a message stating in
+which branch of the {\tt Union} the object lies.
+
+\begin{verbatim}
+sayBranch(x:Union(i:Integer,s:String,f:Float)):Void==
+  output
+    x case i => "Integer branch"
+    x case s  => "String branch"
+    "Float branch"
+\end{verbatim}
+
+Note that {\tt case} uses the selector name as its right-hand argument.
+\index{case} If you accidentally use the branch type on the right-hand
+side of {\tt case}, {\tt false} will be returned.
+
+Declare variable $u$ to have a union type with selectors.
+\spadcommand{u : Union(i : Integer, s : String)}
+\returnType{Type: Void}
+
+Give an initial value to $u$.
+\spadcommand{u := "good morning"}
+$$
+\mbox{\tt "good morning"} 
+$$
+\returnType{Type: Union(s: String,...)}
+
+Use $case$ to determine in which branch of a {\tt Union} an object lies.
+\spadcommand{u case i}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{u case s}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+To access the element in a particular branch, use the selector.
+\spadcommand{u.s}
+$$
+\mbox{\tt "good morning"} 
+$$
+\returnType{Type: String}
+
+\section{The ``Any'' Domain}
+\label{ugTypesAnyNone}
+
+With the exception of objects of type {\tt Record}, all Axiom data
+structures are homogenous, that is, they hold objects all of the same
+type.  \index{Any} If you need to get around this, you can use type
+{\tt Any}.  Using {\tt Any}, for example, you can create lists whose
+elements are integers, rational numbers, strings, and even other
+lists.
+
+Declare $u$ to have type {\tt Any}.
+\spadcommand{u: Any}
+\returnType{Type: Void}
+
+Assign a list of mixed type values to $u$
+\spadcommand{u := [1, 7.2, 3/2, x**2, "wally"]}
+$$
+\left[
+1,  {7.2},  {3 \over 2},  {x \sp 2},  \mbox{\tt "wally"} 
+\right]
+$$
+\returnType{Type: List Any}
+
+When we ask for the elements, Axiom displays these types.
+\spadcommand{u.1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Actually, these objects belong to {\tt Any} but Axiom
+automatically converts them to their natural types for you.
+\spadcommand{u.3}
+$$
+3 \over 2 
+$$
+\returnType{Type: Fraction Integer}
+
+Since type {\tt Any} can be anything, it can only belong to type 
+{\tt Type}.  Therefore it cannot be used in algebraic domains.
+\spadcommand{v : Matrix(Any)}
+\begin{verbatim}
+   Matrix Any is not a valid type.
+\end{verbatim}
+
+Perhaps you are wondering how Axiom internally represents objects of
+type {\tt Any}.  An object of type {\tt Any} consists not only a data
+part representing its normal value, but also a type part (a 
+{\it badge}) giving \index{badge} its type.  For example, the value $1$ of
+type {\tt PositiveInteger} as an object of type {\tt Any} internally
+looks like $[1,{\tt PositiveInteger()}]$.
+
+When should you use {\tt Any} instead of a {\tt Union} type?  For a
+{\tt Union}, you must know in advance exactly which types you are
+going to
+allow.  For {\tt Any}, anything that comes along can be accommodated.
+
+\section{Conversion}
+\label{ugTypesConvert}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Conversion is the process of changing an object of one type into an
+object of another type.  The syntax for conversion is:
+$$
+{\it object} {\tt ::} {\it newType}
+$$
+}
+
+By default, $3$ has the type {\tt PositiveInteger}.
+\spadcommand{3}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+We can change this into an object of type {\tt Fraction Integer}
+by using ``{\tt ::}''.
+\spadcommand{3 :: Fraction Integer}
+$$
+3 
+$$
+\returnType{Type: Fraction Integer}
+
+A {\it coercion} is a special kind of conversion that Axiom is allowed
+to do automatically when you enter an expression.  Coercions are
+usually somewhat safer than more general conversions.  The Axiom
+library contains operations called {\bf coerce} and {\bf convert}.
+Only the {\bf coerce} operations can be used by the interpreter to
+change an object into an object of another type unless you explicitly
+use a {\tt ::}.
+
+By now you will be quite familiar with what types and modes look like.
+It is useful to think of a type or mode as a pattern for what you want
+the result to be.
+
+Let's start with a square matrix of polynomials with complex rational
+number coefficients. \index{SquareMatrix}
+\spadcommand{m : SquareMatrix(2,POLY COMPLEX FRAC INT)}
+\returnType{Type: Void}
+
+\spadcommand{m := matrix [ [x-3/4*\%i,z*y**2+1/2],[3/7*\%i*y**4 - x,12-\%i*9/5] ]}
+$$
+\left[
+\begin{array}{cc}
+{x -{{3 \over 4} \  i}} & {{{y \sp 2} \  z}+{1 \over 2}} \\ 
+{{{3 \over 7} \  i \  {y \sp 4}} -x} & {{12} -{{9 \over 5} \  i}} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Polynomial Complex Fraction Integer)}
+
+We first want to interchange the {\tt Complex} and {\tt Fraction}
+layers.  We do the conversion by doing the interchange in the type
+expression.
+\spadcommand{m1 := m :: SquareMatrix(2,POLY FRAC COMPLEX INT)}
+$$
+\left[
+\begin{array}{cc}
+{x -{{3 \  i} \over 4}} & {{{y \sp 2} \  z}+{1 \over 2}} \\ 
+{{{{3 \  i} \over 7} \  {y \sp 4}} -x} & {{{60} -{9 \  i}} \over 5} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Polynomial Fraction Complex Integer)}
+
+Interchange the {\tt Polynomial} and the {\tt Fraction} levels.
+\spadcommand{m2 := m1 :: SquareMatrix(2,FRAC POLY COMPLEX INT)}
+$$
+\left[
+\begin{array}{cc}
+{{{4 \  x} -{3 \  i}} \over 4} & {{{2 \  {y \sp 2} \  z}+1} \over 2} \\ 
+{{{3 \  i \  {y \sp 4}} -{7 \  x}} \over 7} & {{{60} -{9 \  i}} \over 5} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Fraction Polynomial Complex Integer)}
+
+Interchange the {\tt Polynomial} and the {\tt Complex} levels.
+\spadcommand{m3 := m2 :: SquareMatrix(2,FRAC COMPLEX POLY INT)}
+$$
+\left[
+\begin{array}{cc}
+{{{4 \  x} -{3 \  i}} \over 4} & {{{2 \  {y \sp 2} \  z}+1} \over 2} \\ 
+{{-{7 \  x}+{3 \  {y \sp 4} \  i}} \over 7} & {{{60} -{9 \  i}} \over 5} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Fraction Complex Polynomial Integer)}
+
+All the entries have changed types, although in comparing the
+last two results only the entry in the lower left corner looks different.
+We did all the intermediate steps to show you what Axiom can do.
+
+In fact, we could have combined all these into one conversion.
+\spadcommand{m :: SquareMatrix(2,FRAC COMPLEX POLY INT)}
+$$
+\left[
+\begin{array}{cc}
+{{{4 \  x} -{3 \  i}} \over 4} & {{{2 \  {y \sp 2} \  z}+1} \over 2} \\ 
+{{-{7 \  x}+{3 \  {y \sp 4} \  i}} \over 7} & {{{60} -{9 \  i}} \over 5} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Fraction Complex Polynomial Integer)}
+
+There are times when Axiom is not be able to do the conversion in one
+step.  You may need to break up the transformation into several
+conversions in order to get an object of the desired type.
+
+We cannot move either {\tt Fraction} or {\tt Complex} above (or to the
+left of, depending on how you look at it) {\tt SquareMatrix} because
+each of these levels requires that its argument type have commutative
+multiplication, whereas {\tt SquareMatrix} does not. That is because
+{\tt Fraction} requires that its argument belong to the category 
+{\tt IntegralDomain} and \index{category} {\tt Complex} requires that its
+argument belong to {\tt CommutativeRing}. 
+See \ref{ugTypesBasic} on page~\pageref{ugTypesBasic} for a
+brief discussion of categories. The {\tt Integer} level did not move
+anywhere because it does not allow any arguments.  We also did not
+move the {\tt SquareMatrix} part anywhere, but we could have.
+
+Recall that $m$ looks like this.
+
+\spadcommand{m}
+$$
+\left[
+\begin{array}{cc}
+{x -{{3 \over 4} \  i}} & {{{y \sp 2} \  z}+{1 \over 2}} \\ 
+{{{3 \over 7} \  i \  {y \sp 4}} -x} & {{12} -{{9 \over 5} \  i}} 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Polynomial Complex Fraction Integer)}
+
+If we want a polynomial with matrix coefficients rather than a matrix
+with polynomial entries, we can just do the conversion.
+
+\spadcommand{m :: POLY SquareMatrix(2,COMPLEX FRAC INT)}
+$$
+{{\left[ 
+\begin{array}{cc}
+0 & 1 \\ 
+0 & 0 
+\end{array}
+\right]}
+\  {y \sp 2} \  z}+{{\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+{{3 \over 7} \  i} & 0 
+\end{array}
+\right]}
+\  {y \sp 4}}+{{\left[ 
+\begin{array}{cc}
+1 & 0 \\ 
+-1 & 0 
+\end{array}
+\right]}
+\  x}+{\left[ 
+\begin{array}{cc}
+-{{3 \over 4} \  i} & {1 \over 2} \\ 
+0 & {{12} -{{9 \over 5} \  i}} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Polynomial SquareMatrix(2,Complex Fraction Integer)}
+
+We have not yet used modes for any conversions.  Modes are a great
+shorthand for indicating the type of the object you want.  Instead of
+using the long type expression in the last example, we could have
+simply said this.
+
+\spadcommand{m :: POLY ?}
+$$
+{{\left[ 
+\begin{array}{cc}
+0 & 1 \\ 
+0 & 0 
+\end{array}
+\right]}
+\  {y \sp 2} \  z}+{{\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+{{3 \over 7} \  i} & 0 
+\end{array}
+\right]}
+\  {y \sp 4}}+{{\left[ 
+\begin{array}{cc}
+1 & 0 \\ 
+-1 & 0 
+\end{array}
+\right]}
+\  x}+{\left[ 
+\begin{array}{cc}
+-{{3 \over 4} \  i} & {1 \over 2} \\ 
+0 & {{12} -{{9 \over 5} \  i}} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Polynomial SquareMatrix(2,Complex Fraction Integer)}
+
+We can also indicate more structure if we want the entries of the
+matrices to be fractions.
+
+\spadcommand{m :: POLY SquareMatrix(2,FRAC ?)}
+$$
+{{\left[ 
+\begin{array}{cc}
+0 & 1 \\ 
+0 & 0 
+\end{array}
+\right]}
+\  {y \sp 2} \  z}+{{\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+{{3 \  i} \over 7} & 0 
+\end{array}
+\right]}
+\  {y \sp 4}}+{{\left[ 
+\begin{array}{cc}
+1 & 0 \\ 
+-1 & 0 
+\end{array}
+\right]}
+\  x}+{\left[ 
+\begin{array}{cc}
+-{{3 \  i} \over 4} & {1 \over 2} \\ 
+0 & {{{60} -{9 \  i}} \over 5} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Polynomial SquareMatrix(2,Fraction Complex Integer)}
+
+\section{Subdomains Again}
+\label{ugTypesSubdomains}
+
+A {\it subdomain} {\rm S} of a domain {\rm D} is a domain consisting of
+\begin{enumerate} 
+\item those elements of {\rm D} that satisfy some 
+{\it predicate} (that is, a test that returns {\tt true} or {\tt false}) and 
+\item a subset of the operations of {\rm D}.  
+\end{enumerate} 
+Every domain is a subdomain of itself, trivially satisfying the
+membership test: {\tt true}.
+
+Currently, there are only two system-defined subdomains in Axiom that
+receive substantial use.  {\tt PositiveInteger} and 
+{\tt NonNegativeInteger} are subdomains of {\tt Integer}.  An element $x$
+of {\tt NonNegativeInteger} is an integer that is greater than or
+equal to zero, that is, satisfies $x >= 0$.  An element $x$ of 
+{\tt PositiveInteger} is a nonnegative integer that is, in fact, greater
+than zero, that is, satisfies $x > 0$.  Not all operations from 
+{\tt Integer} are available for these subdomains.  For example, negation
+and subtraction are not provided since the subdomains are not closed
+under those operations.  When you use an integer in an expression,
+Axiom assigns to it the type that is the most specific subdomain whose
+predicate is satisfied.
+
+This is a positive integer.
+\spadcommand{5}
+$$
+5 
+$$
+\returnType{Type: PositiveInteger}
+
+This is a nonnegative integer.
+\spadcommand{0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+This is neither of the above.
+\spadcommand{-5}
+$$
+-5 
+$$
+\returnType{Type: Integer}
+
+Furthermore, unless you are assigning an integer to a declared variable
+or using a conversion, any integer result has as type the most
+specific subdomain.
+\spadcommand{(-2) - (-3)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{0 :: Integer}
+$$
+0 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{x : NonNegativeInteger := 5}
+$$
+5 
+$$
+\returnType{Type: NonNegativeInteger}
+
+When necessary, Axiom converts an integer object into one belonging to
+a less specific subdomain.  For example, in $3-2$, the arguments to
+\spadopFrom{-}{Integer} are both elements of {\tt PositiveInteger},
+but this type does not provide a subtraction operation.  Neither does
+{\tt NonNegativeInteger}, so $3$ and $2$ are viewed as elements of
+{\tt Integer}, where their difference can be calculated.  The result
+is $1$, which Axiom then automatically assigns the type 
+{\tt PositiveInteger}.
+
+Certain operations are very sensitive to the subdomains to which their
+arguments belong.  This is an element of {\tt PositiveInteger}.
+\spadcommand{2 ** 2}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+This is an element of {\tt Fraction Integer}.
+\spadcommand{2 ** (-2)}
+$$
+1 \over 4 
+$$
+\returnType{Type: Fraction Integer}
+
+It makes sense then that this is a list of elements of {\tt
+PositiveInteger}.
+\spadcommand{[10**i for i in 2..5]}
+$$
+\left[
+{100},  {1000},  {10000},  {100000} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+What should the type of {\tt [10**(i-1) for i in 2..5]} be?  On one hand,
+$i-1$ is always an integer greater than zero as $i$ ranges from $2$ to
+$5$ and so $10**i$ is also always a positive integer.  On the other,
+$i-1$ is a very simple function of $i$.  Axiom does not try to analyze
+every such function over the index's range of values to determine
+whether it is always positive or nowhere negative.  For an arbitrary
+Axiom function, this analysis is not possible.
+
+So, to be consistent no such analysis is done and we get this.
+\spadcommand{[10**(i-1) for i in 2..5]}
+$$
+\left[
+{10},  {100},  {1000},  {10000} 
+\right]
+$$
+\returnType{Type: List Fraction Integer}
+
+To get a list of elements of {\tt PositiveInteger} instead, you have
+two choices.  You can use a conversion.
+
+\spadcommand{[10**((i-1) :: PI) for i in 2..5]}
+\begin{verbatim}
+Compiling function G82696 with type Integer -> Boolean 
+Compiling function G82708 with type NonNegativeInteger -> Boolean 
+\end{verbatim}
+$$
+\left[
+{10},  {100},  {1000},  {10000} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Or you can use {\tt pretend}.  \index{pretend}
+\spadcommand{[10**((i-1) pretend PI) for i in 2..5]}
+$$
+\left[
+{10},  {100},  {1000},  {10000} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The operation {\tt pretend} is used to defeat the Axiom type system.
+The expression {\tt object pretend D} means ``make a new object
+(without copying) of type {\tt D} from {\tt object}.''  If 
+{\tt object} were an integer and you told Axiom to pretend it was a list,
+you would probably see a message about a fatal error being caught and
+memory possibly being damaged.  Lists do not have the same internal
+representation as integers!
+
+You use {\tt pretend} at your peril.  \index{peril}
+
+Use $pretend$ with great care!  Axiom trusts you that the value is of
+the specified type.
+
+\spadcommand{(2/3) pretend Complex Integer}
+$$
+2+{3 \  i} 
+$$
+\returnType{Type: Complex Integer}
+
+\section{Package Calling and Target Types}
+\label{ugTypesPkgCall}
+
+Axiom works hard to figure out what you mean by an expression without
+your having to qualify it with type information.  Nevertheless, there
+are times when you need to help it along by providing hints (or even
+orders!) to get Axiom to do what you want.
+
+We saw in \ref{ugTypesDeclare} on page~\pageref{ugTypesDeclare} that
+declarations using types and modes control the type of the results
+produced.  For example, we can either produce a complex object with
+polynomial real and imaginary parts or a polynomial with complex
+integer coefficients, depending on the declaration.
+
+Package calling is how you tell Axiom to use a particular function
+from a particular part of the library.
+
+Use the \spadopFrom{/}{Fraction} from {\tt Fraction Integer} to create
+a fraction of two integers.
+\spadcommand{2/3}
+$$
+2 \over 3 
+$$
+\returnType{Type: Fraction Integer}
+
+If we wanted a floating point number, we can say ``use the
+\spadopFrom{/}{Float} in {\tt Float}.''
+\spadcommand{(2/3)\$Float}
+$$
+0.6666666666 6666666667 
+$$
+\returnType{Type: Float}
+
+Perhaps we actually wanted a fraction of complex integers.
+\spadcommand{(2/3)\$Fraction(Complex Integer)}
+$$
+2 \over 3 
+$$
+\returnType{Type: Float}
+
+In each case, AXIOM used the indicated operations, sometimes first
+needing to convert the two integers into objects of the appropriate type.
+In these examples, ``/'' is written as an infix operator.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+To use package calling with an infix operator, use the following syntax:
+$$(\ arg_1{\rm \ op\ }arg_2\ )\$type$$
+} 
+
+We used, for example, $(2/3)\${\rm Float}$. The expression $2+3+4$
+is equivalent to $(2+3)+4$. Therefore in the expression 
+$(2+3+4)\${\rm Float}$ the second ``+'' comes from the {\rm Float}
+domain. The first ``+'' comes from {\rm Float} because the package
+call causes AXIOM to convert $(2+3)$ and $4$ to type
+{\rm Float}. Before the sum is converted, it is given a target type
+of {\rm Float} by AXIOM and then evaluated. The target type causes the
+``+'' from {\tt Float} to be used.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+For an operator written before its arguments, you must use parentheses
+around the arguments (even if there is only one), and follow the closing
+parenthesis by a ``\$'' and then the type.
+$$ fun\ (\ arg_1, arg_2, \ldots, arg_N\ )\$type$$
+}
+
+For example, to call the ``minimum'' function from {\rm SmallFloat} on two
+integers, you could write {\bf min}(4,89){\tt SmallFloat}. Another use of
+package calling is to tell AXIOM to use a library function rather than a
+function you defined. We discuss this in 
+Section \ref{ugUserUse} on page~\pageref{ugUserUse}.
+
+Sometimes rather than specifying where an operation comes from, you
+just want to say what type the result should be. We say that you provide a
+{\sl target type} for the expression. Instead of using a ``\$'', use a ``@''
+to specify the requested target type. Otherwise, the syntax is the same.
+Note that giving a target type is not the same as explicitly doing a
+conversion. The first says ``try to pick operations so that the result has
+such-and-such a type.'' The second says ``compute the result and then convert
+to an object of such-and-such a type.''
+
+Sometimes it makes sense, as in this expression, to say ``choose the 
+operations in this expression so that the final result is {\rm Float}.
+\spadcommand{(2/3)@Float}
+$$
+0.6666666666 6666666667 
+$$
+\returnType{Type: Float}
+
+Here we used ``{\tt @}'' to say that the target type of the left-hand side
+was {\tt Float}.  In this simple case, there was no real difference
+between using ``{\tt \$}'' and ``{\tt @}''.  
+You can see the difference if you try the following.
+
+This says to try to choose ``{\tt +}'' so that the result is a string.
+Axiom cannot do this.
+\spadcommand{(2 + 3)@String}
+\begin{verbatim} 
+An expression involving @ String actually evaluated to one of 
+   type PositiveInteger . Perhaps you should use :: String .
+\end{verbatim}
+
+This says to get the {\tt +} from {\tt String} and apply it to the two
+integers.  Axiom also cannot do this because there is no {\tt +}
+exported by {\tt String}.
+\spadcommand{(2 + 3)\$String}
+\begin{verbatim}
+   The function + is not implemented in String .
+\end{verbatim}
+
+(By the way, the operation \spadfunFrom{concat}{String} or juxtaposition
+is used to concatenate two strings.)
+\index{String}
+
+When we have more than one operation in an expression, the difference
+is even more evident.  The following two expressions show that Axiom
+uses the target type to create different objects.  
+The ``{\tt +}'', ``{\tt *}'' and ``{\tt **}'' operations are all 
+chosen so that an object of the correct final type is created.
+
+This says that the operations should be chosen so that the result is a
+{\tt Complex} object.
+\spadcommand{((x + y * \%i)**2)@(Complex Polynomial Integer)}
+$$
+-{y \sp 2}+{x \sp 2}+{2 \  x \  y \  i} 
+$$
+\returnType{Type: Complex Polynomial Integer}
+
+This says that the operations should be chosen so that the result is a
+{\tt Polynomial} object.
+\spadcommand{((x + y * \%i)**2)@(Polynomial Complex Integer)}
+$$
+-{y \sp 2}+{2 \  i \  x \  y}+{x \sp 2} 
+$$
+\returnType{Type: Polynomial Complex Integer}
+
+What do you think might happen if we left off all target type and
+package call information in this last example?
+\spadcommand{(x + y * \%i)**2}
+$$
+-{y \sp 2}+{2 \  i \  x \  y}+{x \sp 2} 
+$$
+\returnType{Type: Polynomial Complex Integer}
+
+We can convert it to {\tt Complex} as an afterthought.  But this is
+more work than just saying making what we want in the first place.
+\spadcommand{\% :: Complex ?}
+$$
+-{y \sp 2}+{x \sp 2}+{2 \  x \  y \  i} 
+$$
+\returnType{Type: Complex Polynomial Integer}
+
+Finally, another use of package calling is to qualify fully an
+operation that is passed as an argument to a function.
+
+Start with a small matrix of integers.
+\spadcommand{h := matrix [ [8,6],[-4,9] ]}
+$$
+\left[
+\begin{array}{cc}
+8 & 6 \\ 
+-4 & 9 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+We want to produce a new matrix that has for entries the
+multiplicative inverses of the entries of $h$.  One way to do this is
+by calling \spadfunFrom{map}{MatrixCategoryFunctions2} with the
+\spadfunFrom{inv}{Fraction} function from {\tt Fraction (Integer)}.
+
+\spadcommand{map(inv\$Fraction(Integer),h)}
+$$
+\left[
+\begin{array}{cc}
+{1 \over 8} & {1 \over 6} \\ 
+-{1 \over 4} & {1 \over 9} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Fraction Integer}
+
+We could have been a bit less verbose and used abbreviations.
+\spadcommand{map(inv\$FRAC(INT),h)}
+$$
+\left[
+\begin{array}{cc}
+{1 \over 8} & {1 \over 6} \\ 
+-{1 \over 4} & {1 \over 9} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Fraction Integer}
+
+As it turns out, Axiom is smart enough to know what we mean anyway.
+We can just say this.
+\spadcommand{map(inv,h)}
+$$
+\left[
+\begin{array}{cc}
+{1 \over 8} & {1 \over 6} \\ 
+-{1 \over 4} & {1 \over 9} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Fraction Integer}
+
+\section{Resolving Types}
+\label{ugTypesResolve}
+
+In this section we briefly describe an internal process by which
+\index{resolve} Axiom determines a type to which two objects of
+possibly different types can be converted.  We do this to give you
+further insight into how Axiom takes your input, analyzes it, and
+produces a result.
+
+What happens when you enter $x + 1$ to Axiom?  Let's look at what you
+get from the two terms of this expression.
+
+This is a symbolic object whose type indicates the name.
+\spadcommand{x}
+$$
+x 
+$$
+\returnType{Type: Variable x}
+
+This is a positive integer.
+\spadcommand{1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+There are no operations in {\tt PositiveInteger} that add positive
+integers to objects of type {\tt Variable(x)} nor are there any in
+{\tt Variable(x)}.  Before it can add the two parts, Axiom must come
+up with a common type to which both $x$ and $1$ can be converted.  We
+say that Axiom must {\it resolve} the two types into a common type.
+In this example, the common type is {\tt Polynomial(Integer)}.
+
+Once this is determined, both parts are converted into polynomials,
+and the addition operation from {\tt Polynomial(Integer)} is used to
+get the answer.
+\spadcommand{x + 1}
+$$
+x+1 
+$$
+\returnType{Type: Polynomial Integer}
+
+Axiom can always resolve two types: if nothing resembling the original
+types can be found, then {\tt Any} is be used.  \index{Any} This is
+fine and useful in some cases.
+
+\spadcommand{["string",3.14159]}
+$$
+\left[
+\mbox{\tt "string"} ,  {3.14159} 
+\right]
+$$
+\returnType{Type: List Any}
+
+In other cases objects of type {\tt Any} can't be used by the
+operations you specified.
+\spadcommand{"string" + 3.14159}
+\begin{verbatim}
+There are 11 exposed and 5 unexposed library operations named + 
+  having 2 argument(s) but none was determined to be applicable. 
+  Use HyperDoc Browse, or issue
+                            )display op +
+  to learn more about the available operations. Perhaps 
+  package-calling the operation or using coercions on the 
+  arguments will allow you to apply the operation.
+ 
+Cannot find a definition or applicable library operation named + 
+  with argument type(s) 
+                               String
+                                Float
+      
+  Perhaps you should use "@" to indicate the required return type, 
+  or "$" to specify which version of the function you need.
+\end{verbatim}
+
+Although this example was contrived, your expressions may need to be
+qualified slightly to help Axiom resolve the types involved.  You may
+need to declare a few variables, do some package calling, provide some
+target type information or do some explicit conversions.
+
+We suggest that you just enter the expression you want evaluated and
+see what Axiom does.  We think you will be impressed with its ability
+to ``do what I mean.''  If Axiom is still being obtuse, give it some
+hints.  As you work with Axiom, you will learn where it needs a little
+help to analyze quickly and perform your computations.
+
+\section{Exposing Domains and Packages}
+\label{ugTypesExpose}
+
+In this section we discuss how Axiom makes some operations available
+to you while hiding others that are meant to be used by developers or
+only in rare cases.  If you are a new user of Axiom, it is likely that
+everything you need is available by default and you may want to skip
+over this section on first reading.
+
+Every \index{constructor!exposed} domain and package in the Axiom
+library \index{constructor!hidden} is \index{exposed!constructor}
+either exposed (meaning that you can use its operations without doing
+anything special) or it is {\it hidden} (meaning you have to either
+package call (see \ref{ugTypesPkgCall} on
+page~\pageref{ugTypesPkgCall}) the operations it contains or
+explicitly expose it to use the operations).  The initial exposure
+status for a constructor is set in the file {\bf exposed.lsp} (see the
+{\it Installer's Note} \index{exposed.lsp @{\bf exposed.lsp}} for
+Axiom \index{file!exposed.lsp @{\bf exposed.lsp}} if you need to know
+the location of this file).  Constructors are collected together in
+\index{group!exposure} {\it exposure groups}.  \index{exposure!group}
+Categories are all in the exposure group ``categories'' and the bulk
+of the basic set of packages and domains that are exposed are in the
+exposure group ``basic.''  Here is an abbreviated sample of the file
+(without the Lisp parentheses):
+
+\begin{verbatim}
+basic
+        AlgebraicNumber                          AN
+        AlgebraGivenByStructuralConstants        ALGSC
+        Any                                      ANY
+        AnyFunctions1                            ANY1
+        BinaryExpansion                          BINARY
+        Boolean                                  BOOLEAN
+        CardinalNumber                           CARD
+        CartesianTensor                          CARTEN
+        Character                                CHAR
+        CharacterClass                           CCLASS
+        CliffordAlgebra                          CLIF
+        Color                                    COLOR
+        Complex                                  COMPLEX
+        ContinuedFraction                        CONTFRAC
+        DecimalExpansion                         DECIMAL
+        ...
+\end{verbatim}
+\begin{verbatim}
+categories
+        AbelianGroup                             ABELGRP
+        AbelianMonoid                            ABELMON
+        AbelianMonoidRing                        AMR
+        AbelianSemiGroup                         ABELSG
+        Aggregate                                AGG
+        Algebra                                  ALGEBRA
+        AlgebraicallyClosedField                 ACF
+        AlgebraicallyClosedFunctionSpace         ACFS
+        ArcHyperbolicFunctionCategory            AHYP
+        ...
+\end{verbatim}
+
+For each constructor in a group, the full name and the abbreviation is
+given.  There are other groups in {\bf exposed.lsp} but initially only
+the constructors in exposure groups ``basic'' ``categories''
+``naglink'' and ``anna'' are exposed.
+
+As an interactive user of Axiom, you do not need to modify this file.
+Instead, use {\tt )set expose} to expose, hide or query the exposure
+status of an individual constructor or exposure group. \index{set expose} 
+The reason for having exposure groups is to be able to expose
+or hide multiple constructors with a single command.  For example, you
+might group together into exposure group ``quantum'' a number of
+domains and packages useful for quantum mechanical computations.
+These probably should not be available to every user, but you want an
+easy way to make the whole collection visible to Axiom when it is
+looking for operations to apply.
+
+If you wanted to hide all the basic constructors available by default,
+you would issue {\tt )set expose drop group basic}.  
+\index{set expose drop group} We do not recommend that you do this.  
+If, however, you discover that you have hidden all the basic constructors, 
+you should issue {\tt )set expose add group basic} to restore your default
+environment.  \index{set expose add group}
+
+It is more likely that you would want to expose or hide individual
+constructors.  In \ref{ugUserTriangle} on
+page~\pageref{ugUserTriangle} we use several operations from 
+{\tt OutputForm}, a domain usually hidden.  To avoid package calling every
+operation from {\tt OutputForm}, we expose the domain and let Axiom
+conclude that those operations should be used.  Use {\tt )set expose
+add constructor} and {\tt )set expose drop constructor} to expose and
+hide a constructor, respectively.  \index{set expose drop constructor}
+You should use the constructor name, not the abbreviation.  The 
+{\tt )set expose} command guides you through these options.  
+\index{set expose add constructor}
+
+If you expose a previously hidden constructor, Axiom exhibits new
+behavior (that was your intention) though you might not expect the
+results that you get.  {\tt OutputForm} is, in fact, one of the worst
+offenders in this regard.  \index{OutputForm} This domain is meant to
+be used by other domains for creating a structure that Axiom knows how
+to display.  It has functions like \spadopFrom{+}{OutputForm} that
+form output representations rather than do mathematical calculations.
+Because of the order in which Axiom looks at constructors when it is
+deciding what operation to apply, {\tt OutputForm} might be used
+instead of what you expect.
+
+This is a polynomial.
+\spadcommand{x + x}
+$$
+2 \  x 
+$$
+\returnType{Type: Polynomial Integer}
+
+Expose {\tt OutputForm}.
+\spadcommand{)set expose add constructor OutputForm }
+\begin{verbatim}
+   OutputForm is now explicitly exposed in frame G82322 
+\end{verbatim}
+
+This is what we get when {\tt OutputForm} is automatically available.
+\spadcommand{x + x}
+$$
+x+x 
+$$
+\returnType{Type: OutputForm}
+
+Hide {\tt OutputForm} so we don't run into problems with any later examples!
+\spadcommand{)set expose drop constructor OutputForm }
+\begin{verbatim}
+   OutputForm is now explicitly hidden in frame G82322 
+\end{verbatim}
+
+Finally, exposure is done on a frame-by-frame basis.  A {\it frame}
+(see \ref{ugSysCmdframe} on page~\pageref{ugSysCmdframe})
+\index{frame!exposure and} is one of possibly several logical Axiom
+workspaces within a physical one, each having its own environment (for
+example, variables and function definitions).  If you have several
+Axiom workspace windows on your screen, they are all different frames,
+automatically created for you by HyperDoc.  Frames can be manually
+created, made active and destroyed by the {\tt )frame} system command.
+\index{frame} They do not share exposure information, so you need to
+use {\tt )set expose} in each one to add or drop constructors from
+view.
+
+\section{Commands for Snooping}
+\label{ugAvailSnoop}
+
+To conclude this chapter, we introduce you to some system commands
+that you can use for getting more information about domains, packages,
+categories, and operations.  The most powerful Axiom facility for
+getting information about constructors and operations is the Browse
+component of HyperDoc.  This is discussed in Chapter 
+\ref{ugBrowse} on page~\pageref{ugBrowse}.
+
+Use the {\tt )what} system command to see lists of system objects
+whose name contain a particular substring (uppercase or lowercase is
+not significant).  \index{what}
+
+Issue this to see a list of all operations with ``{\tt complex}'' in
+their names.  \index{what operation}
+\spadcommand{)what operation complex}
+\begin{verbatim}
+
+Operations whose names satisfy the above pattern(s):
+
+complex                   complex?                          
+complexEigenvalues        complexEigenvectors               
+complexElementary         complexExpand                     
+complexForm               complexIntegrate                  
+complexLimit              complexNormalize                  
+complexNumeric            complexNumericIfCan               
+complexRoots              complexSolve                      
+complexZeros              createLowComplexityNormalBasis    
+createLowComplexityTable  doubleComplex?                    
+drawComplex               drawComplexVectorField            
+fortranComplex            fortranDoubleComplex              
+pmComplexintegrate                
+   
+To get more information about an operation such as 
+complexZeros, issue the command )display op complexZeros 
+\end{verbatim}
+
+If you want to see all domains with ``{\tt matrix}'' in their names,
+issue this.  \index{what domain}
+\spadcommand{)what domain matrix}
+\begin{verbatim}
+----------------------- Domains -----------------------
+
+Domains with names matching patterns:
+     matrix 
+
+ DHMATRIX DenavitHartenbergMatrix      
+ DPMM     DirectProductMatrixModule
+ IMATRIX  IndexedMatrix                
+ LSQM     LieSquareMatrix
+ M3D      ThreeDimensionalMatrix       
+ MATCAT-  MatrixCategory&
+ MATRIX   Matrix                       
+ RMATCAT- RectangularMatrixCategory&
+ RMATRIX  RectangularMatrix            
+ SMATCAT- SquareMatrixCategory&
+ SQMATRIX SquareMatrix
+\end{verbatim}
+
+Similarly, if you wish to see all packages whose names contain ``{\tt
+gauss}'', enter this.  \index{what packages}
+\spadcommand{)what package gauss}
+\begin{verbatim}
+---------------------- Packages -----------------------
+
+Packages with names matching patterns:
+     gauss 
+
+ GAUSSFAC GaussianFactorizationPackage
+\end{verbatim}
+
+This command shows all the operations that {\tt Any} provides.
+Wherever {\tt \$} appears, it means ``{\tt Any}''.  \index{show}
+\spadcommand{)show Any}
+\begin{verbatim}
+ Any  is a domain constructor
+ Abbreviation for Any is ANY 
+ This constructor is exposed in this frame.
+ Issue )edit /usr/local/axiom/mnt/algebra/any.spad 
+  to see algebra source code for ANY 
+
+--------------------- Operations ----------------------
+ ?=? : (%,%) -> Boolean                
+ any : (SExpression,None) -> %
+ coerce : % -> OutputForm              
+ dom : % -> SExpression
+ domainOf : % -> OutputForm            
+ hash : % -> SingleInteger
+ latex : % -> String                   
+ obj : % -> None
+ objectOf : % -> OutputForm            
+ ?~=? : (%,%) -> Boolean
+ showTypeInOutput : Boolean -> String
+
+\end{verbatim}
+
+This displays all operations with the name {\tt complex}.
+\index{display operation}
+\spadcommand{)display operation complex}
+\begin{verbatim}
+There is one exposed function called complex :
+ [1] (D1,D1) -> D from D if D has COMPCAT D1 and D1 has COMRING
+\end{verbatim}
+
+Let's analyze this output.
+
+First we find out what some of the abbreviations mean.
+\spadcommand{)abbreviation query COMPCAT}
+\begin{verbatim}
+   COMPCAT abbreviates category ComplexCategory 
+\end{verbatim}
+
+\spadcommand{)abbreviation query COMRING}
+\begin{verbatim}
+   COMRING abbreviates category CommutativeRing 
+\end{verbatim}
+
+So if {\tt D1} is a commutative ring (such as the integers or floats) and
+{\tt D} belongs to {\tt ComplexCategory D1}, then there is an operation
+called {\bf complex} that takes two elements of {\tt D1} and creates an
+element of {\tt D}.  The primary example of a constructor implementing
+domains belonging to {\tt ComplexCategory} is {\tt Complex}.  See
+\ref{Complex} on page~\pageref{Complex} for more information on that and see
+\ref{ugUserDeclare} on page~\pageref{ugUserDeclare}
+for more information on function types.
+
+\setcounter{chapter}{2}
+
+\chapter{Using HyperDoc}
+\label{ugHyper}
+
+\begin{figure}[htbp]
+\begin{picture}(324,260)%(-54,0)
+\special{psfile=ps/h-root.ps}
+\end{picture}
+\caption{The HyperDoc root window page.}
+\end{figure}
+
+HyperDoc is the gateway to Axiom.  \index{HyperDoc} It's both an
+on-line tutorial and an on-line reference manual.  It also enables you
+to use Axiom simply by using the mouse and filling in templates.
+HyperDoc is available to you if you are running Axiom under the X
+Window System.
+
+Pages usually have active areas, marked in {\bf this font} (bold
+face).  As you move the mouse pointer to an active area, the pointer
+changes from a filled dot to an open circle.  The active areas are
+usually linked to other pages.  When you click on an active area, you
+move to the linked page.
+
+\section{Headings}
+\label{ugHyperHeadings}
+Most pages have a standard set of buttons at the top of the page.
+This is what they mean:
+
+\begin{description}
+
+\item[\HelpBitmap] Click on this to get help.  The button only appears
+if there is specific help for the page you are viewing.  You can get
+{\it general} help for HyperDoc by clicking the help button on the
+home page.
+
+\item[\UpBitmap] Click here to go back one page.
+By clicking on this button repeatedly, you can go back several pages and
+then take off in a new direction.
+
+\item[\ReturnBitmap] Go back to the home page, that is, the page on
+which you started.  Use HyperDoc to explore, to make forays into new
+topics.  Don't worry about how to get back.  HyperDoc remembers where
+you came from.  Just click on this button to return.
+
+\item[\ExitBitmap] From the root window (the one that is displayed
+when you start the system) this button leaves the HyperDoc program,
+and it must be restarted if you want to use it again.  From any other
+HyperDoc window, it just makes that one window go away.  You {\it must} 
+use this button to get rid of a window.  If you use the window
+manager ``Close'' button, then all of HyperDoc goes away.
+
+\end{description}
+
+The buttons are not displayed if they are not applicable to the page
+you are viewing.  For example, there is no \ReturnBitmap button on the
+top-level menu.
+
+\section{Key Definitions}
+\label{ugHyperKeys}
+
+The following keyboard definitions are in effect throughout HyperDoc.
+See \ref{ugHyperScroll} on page~\pageref{ugHyperScroll} and 
+\ref{ugHyperInput} on page~\pageref{ugHyperInput} for some contextual key
+definitions.
+
+\begin{description}
+\item[F1] Display the main help page.
+\item[F3] Same as \ExitBitmap{}, makes the window go away if you are not at the top-level window or quits the HyperDoc facility if you are at the top-level.
+\item[F5] Rereads the HyperDoc database, if necessary (for system developers).
+\item[F9] Displays this information about key definitions.
+\item[F12] Same as {\bf F3}.
+\item[Up Arrow] Scroll up one line.
+\item[Down Arrow] Scroll down one line.
+\item[Page Up] Scroll up one page.
+\item[Page Down] Scroll down one page.
+\end{description}
+
+\section{Scroll Bars}
+\label{ugHyperScroll}
+
+Whenever there is too much text to fit on a page, a 
+{\it scroll \index{scroll bar} bar} 
+automatically appears along the right side.
+
+With a scroll bar, your page becomes an aperture, that is, a window
+into a larger amount of text than can be displayed at one time.  The
+scroll bar lets you move up and down in the text to see different
+parts.  It also shows where the aperture is relative to the whole
+text.  The aperture is indicated by a strip on the scroll bar.
+
+Move the cursor with the mouse to the ``down-arrow'' at the bottom of
+the scroll bar and click.  See that the aperture moves down one line.
+Do it several times.  Each time you click, the aperture moves down one
+line.  Move the mouse to the ``up-arrow'' at the top of the scroll bar
+and click.  The aperture moves up one line each time you click.
+
+Next move the mouse to any position along the middle of the scroll bar
+and click.  HyperDoc attempts to move the top of the aperture to this
+point in the text.
+
+You cannot make the aperture go off the bottom edge.  When the
+aperture is about half the size of text, the lowest you can move the
+aperture is halfway down.
+
+To move up or down one screen at a time, use the \fbox{\bf PageUp} and 
+\fbox{\bf PageDown} keys on your keyboard.  They move the visible part of the
+region up and down one page each time you press them.
+
+If the HyperDoc page does not contain an input area (see
+\ref{ugHyperInput} on page~\pageref{ugHyperInput}), you can also use
+the \fbox{\bf Home} and \fbox{$\uparrow$} and \fbox{$\downarrow$}
+arrow keys to navigate.  When you press the \fbox{\bf Home} key, the
+screen is positioned at the very top of the page.  Use the
+\fbox{$\uparrow$} and \fbox{$\downarrow$} arrow keys to move the
+screen up and down one line at a time, respectively.
+
+\section{Input Areas}
+\label{ugHyperInput}
+
+Input areas are boxes where you can put data.
+
+To enter characters, first move your mouse cursor to somewhere within
+the HyperDoc page.  Characters that you type are inserted in front of
+the underscore.  This means that when you type characters at your
+keyboard, they go into this first input area.
+
+The input area grows to accommodate as many characters as you type.
+Use the \fbox{\bf Backspace} key to erase characters to the left.  To
+modify what you type, use the right-arrow \fbox{$\rightarrow$} and
+left-arrow keys \fbox{$\leftarrow$} and the keys \fbox{\bf Insert},
+\fbox{\bf Delete}, \fbox{\bf Home} and \fbox{\bf End}.  These keys are
+found immediately on the right of the standard IBM keyboard.
+
+If you press the \fbox{\bf Home} key, the cursor moves to the
+beginning of the line and if you press the \fbox{\bf End} key, the
+cursor moves to the end of the line.  Pressing 
+\fbox{\bf Ctrl}--\fbox{\bf End} deletes all the text from the 
+cursor to the end of the line.
+
+A page may have more than one input area.  Only one input area has an
+underscore cursor.  When you first see apage, the top-most input area
+contains the cursor.  To type information into another input area, use
+the \fbox{\bf Enter} or \fbox{\bf Tab} key to move from one input area to
+xanother.  To move in the reverse order, use \fbox{\bf Shift}--\fbox{\bf Tab}.
+
+You can also move from one input area to another using your mouse.
+Notice that each input area is active. Click on one of the areas.
+As you can see, the underscore cursor moves to that window.
+
+\section{Radio Buttons and Toggles}
+\label{ugHyperButtons}
+
+Some pages have {\it radio buttons} and {\it toggles}.
+Radio buttons are a group of buttons like those on car radios: you can
+select only one at a time.
+
+Once you have selected a button, it appears to be inverted and
+contains a checkmark.  To change the selection, move the cursor with
+the mouse to a different radio button and click.
+
+A toggle is an independent button that displays some on/off state.
+When ``on'', the button appears to be inverted and contains a
+checkmark.  When ``off'', the button is raised.
+
+Unlike radio buttons, you can set a group of them any way you like.
+To change toggle the selection, move the cursor with the mouse to the
+button and click.
+
+\section{Search Strings}
+\label{ugHyperSearch}
+
+A {\it search string} is used for searching some database.  To learn
+about search strings, we suggest that you bring up the HyperDoc
+glossary.  To do this from the top-level page of HyperDoc:
+\begin{enumerate}
+\item Click on Reference, bringing up the Axiom Reference page.
+\item Click on Glossary, bringing up the glossary.
+\end{enumerate}
+
+The glossary has an input area at its bottom.  We review the various
+kinds of search strings you can enter to search the glossary.
+
+The simplest search string is a word, for example, {\tt operation}.  A
+word only matches an entry having exactly that spelling.  Enter the
+word {\tt operation} into the input area above then click on 
+{\bf Search}.  As you can see, {\tt operation} matches only one entry,
+namely with {\tt operation} itself.
+
+Normally matching is insensitive to whether the alphabetic characters
+of your search string are in uppercase or lowercase.  Thus 
+{\tt operation} and {\tt OperAtion} both have the same effect.
+%If you prefer that matching be case-sensitive, issue the command
+%{\tt set HHyperName mixedCase} command to the interpreter.
+
+You will very often want to use the wildcard ``{\tt *}'' in your search
+string so as to match multiple entries in the list.  The search key
+``{\tt *}'' matches every entry in the list.  You can also use ``{\tt *}''
+anywhere within a search string to match an arbitrary substring.  Try
+``{\tt cat*}'' for example: enter ``{\tt cat*}'' into the input area and click
+on {\bf Search}.  This matches several entries.
+
+You use any number of wildcards in a search string as long as they are
+not adjacent.  Try search strings such as ``{\tt *dom*}''.  As you see,
+this search string matches ``{\tt domain}'', ``{\tt domain constructor}'',
+``{\tt subdomain}'', and so on.
+
+\subsection{Logical Searches}
+\label{ugLogicalSearches}
+
+For more complicated searches, you can use ``{\tt and}'', ``{\tt or}'', and
+``{\tt not}'' with basic search strings; write logical expressions using
+these three operators just as in the Axiom language.  For example,
+{\tt domain or package} matches the two entries {\tt domain} and 
+{\tt package}.  Similarly, ``{\tt dom* and *con*}'' matches 
+``{\tt domain constructor}'' and others.  Also ``{\tt not *a*}'' matches 
+every entry that does not contain the letter ``{\tt a}'' somewhere.
+
+Use parentheses for grouping.  For example, ``{\tt dom* and (not *con*)}''
+matches ``{\tt domain}'' but not ``{\tt domain constructor}''.
+
+There is no limit to how complex your logical expression can be.
+For example,
+\begin{center}
+{\tt a* or b* or c* or d* or e* and (not *a*)}
+\end{center}
+is a valid expression.
+
+\section{Example Pages}
+\label{ugHyperExample}
+
+Many pages have Axiom example commands.
+
+Each command has an active ``button'' along the left margin.  When you
+click on this button, the output for the command is ``pasted-in.''
+Click again on the button and you see that the pasted-in output
+disappears.
+
+Maybe you would like to run an example?  To do so, just click on any
+part of its text!  When you do, the example line is copied into a new
+interactive Axiom buffer for this HyperDoc page.
+
+Sometimes one example line cannot be run before you run an earlier one.
+Don't worry---HyperDoc automatically runs all the necessary
+lines in the right order!
+
+The new interactive Axiom buffer disappears when you leave HyperDoc.
+If you want to get rid of it beforehand, use the {\bf Cancel} button
+of the X Window manager or issue the Axiom system command 
+{\tt )close.}  \index{close}
+
+\section{X Window Resources for HyperDoc}
+\label{ugHyperResources}
+
+You can control the appearance of HyperDoc while running under Version
+11 \index{HyperDoc X Window System defaults} of the X Window System by
+placing the following resources \index{X Window System} in the file
+{\bf .Xdefaults} in your home directory.  \index{file!.Xdefaults} 
+In what follows, {\it font} is any valid X11 font name
+\index{font} (for example, {\tt Rom14}) and {\it color} is any valid
+X11 color \index{color} specification (for example, {\tt NavyBlue}).
+For more information about fonts and colors, refer to the X Window
+documentation for your system.
+
+\begin{description}
+\item[{\tt Axiom.hyperdoc.RmFont:} {\it font}] \ \newline
+This is the standard text font.  
+The default value is {\tt Rom14}
+\item[{\tt Axiom.hyperdoc.RmColor:} {\it color}] \ \newline
+This is the standard text color.  
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.ActiveFont:} {\it font}] \ \newline
+This is the font used for HyperDoc link buttons.  
+The default value is {\tt Bld14}
+\item[{\tt Axiom.hyperdoc.ActiveColor:} {\it color}] \ \newline
+This is the color used for HyperDoc link buttons.  
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.AxiomFont:} {\it font}] \ \newline
+This is the font used for active Axiom commands.
+The default value is {\tt Bld14}
+\item[{\tt Axiom.hyperdoc.AxiomColor:} {\it color}] \ \newline
+This is the color used for active Axiom commands.
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.BoldFont:} {\it font}] \ \newline
+This is the font used for bold face.  
+The default value is {\tt Bld14}
+\item[{\tt Axiom.hyperdoc.BoldColor:} {\it color}] \ \newline
+This is the color used for bold face.  
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.TtFont:} {\it font}] \ \newline
+This is the font used for Axiom output in HyperDoc.
+This font must be fixed-width.  
+The default value is {\tt Rom14}
+\item[{\tt Axiom.hyperdoc.TtColor:} {\it color}] \ \newline
+This is the color used for Axiom output in HyperDoc.
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.EmphasizeFont:} {\it font}] \ \newline
+This is the font used for italics.  
+The default value is {\tt Itl14}
+\item[{\tt Axiom.hyperdoc.EmphasizeColor:} {\it color}] \ \newline
+This is the color used for italics.  
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.InputBackground:} {\it color}] \ \newline
+This is the color used as the background for input areas.
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.InputForeground:} {\it color}] \ \newline
+This is the color used as the foreground for input areas.
+The default value is {\tt white}
+\item[{\tt Axiom.hyperdoc.BorderColor:} {\it color}] \ \newline
+This is the color used for drawing border lines.
+The default value is {\tt black}
+\item[{\tt Axiom.hyperdoc.Background:} {\it color}] \ \newline
+This is the color used for the background of all windows.
+The default value is {\tt white}
+\end{description}
+\vfill
+\eject
+
+\setcounter{chapter}{3}
+
+\chapter{Input Files and Output Styles}
+\label{ugInOut}
+
+In this chapter we discuss how to collect Axiom statements
+and commands into files and then read the contents into the
+workspace.
+We also show how to display the results of your computations in
+several different styles including \TeX{}, FORTRAN and
+monospace two-dimensional format.\footnote{\TeX{} is a
+trademark of the American Mathematical Society.}
+
+The printed version of this book uses the Axiom \TeX{} output formatter.
+When we demonstrate a particular output style, we will need to turn
+\TeX{} formatting off and the output style on so that the correct output
+is shown in the text.
+
+\section{Input Files}
+\label{ugInOutIn}
+
+In this section we explain what an {\it input file} is and
+\index{file!input} why you would want to know about it.  We discuss
+where Axiom looks for input files and how you can direct it to look
+elsewhere.  We also show how to read the contents of an input file
+into the {\it workspace} and how to use the {\it history} facility to
+generate an input file from the statements you have entered directly
+into the workspace.
+
+An {\it input} file contains Axiom expressions and system commands.
+Anything that you can enter directly to Axiom can be put into an input
+file.  This is how you save input functions and expressions that you
+wish to read into Axiom more than one time.
+
+To read an input file into Axiom, use the {\tt )read} system command.
+\index{read} For example, you can read a file in a particular
+directory by issuing
+\begin{verbatim}
+)read /spad/src/input/matrix.input
+\end{verbatim}
+
+The ``{\bf .input}'' is optional; this also works:
+\begin{verbatim}
+)read /spad/src/input/matrix
+\end{verbatim}
+
+What happens if you just enter {\tt )read matrix.input} or even {\tt
+)read matrix}?  Axiom looks in your current working directory for
+input files that are not qualified by a directory name.  Typically,
+this directory is the directory from which you invoked Axiom.
+
+To change the current working directory, use the {\tt )cd} system
+command.  The command {\tt {)cd}} by itself shows the current working
+\index{directory!default for searching} directory.  \index{cd} To
+change it to \index{file!input!where found} the {\tt {src/input}}
+subdirectory for user ``babar'', issue
+\begin{verbatim}
+)cd /u/babar/src/input
+\end{verbatim}
+Axiom looks first in this directory for an input file.  If it is not
+found, it looks in the system's directories, assuming you meant some
+input file that was provided with Axiom.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+If you have the Axiom history facility turned on (which it is
+by default), you can save all the lines you have entered into the
+workspace by entering
+
+)history )write
+
+\index{history )write}
+
+Axiom tells you what input file to edit to see your statements.  The
+file is in your home directory or in the directory you specified with
+\index{cd} {\tt {)cd}}.\\
+}
+
+In \ref{ugLangBlocks} on page~\pageref{ugLangBlocks} 
+we discuss using indentation in input files to
+group statements into {\it blocks.}
+
+\section{The .axiom.input File}
+\label{ugInOutSpadprof}
+
+When Axiom starts up, it tries to read the input file {\bf
+.axiom.input}\footnote{{\bf.axiom.input} used to be called 
+{\bf axiom.input} in the NAG version}
+from your home \index{start-up profile file}
+directory. \index{file!start-up profile} It
+there is no {\bf .axiom.input} in your home directory, it reads the
+copy located in its own {\bf src/input} directory.
+\index{file!.axiom.input @{\bf .axiom.input}} The file usually
+contains system commands to personalize your Axiom environment.  In
+the remainder of this section we mention a few things that users
+frequently place in their {\bf .axiom.input} files.
+
+In order to have FORTRAN output always produced from your
+computations, place the system command {\tt )set output fortran on} in
+{\bf .axiom.input}.  \index{quit} If you do not want to be prompted
+for confirmation when you issue the {\tt )quit} system command, place
+{\tt )set quit unprotected} in {\bf .axiom.input}.  
+\index{set quit unprotected} 
+If you then decide that you do want to be prompted, issue
+{\tt )set quit protected}.  \index{set quit protected} This is the
+default setting so that new users do not leave Axiom
+inadvertently.\footnote{The system command {\tt )pquit} always
+prompts you for confirmation.}
+
+To see the other system variables you can set, issue {\tt {)set}}
+or use the HyperDoc {\bf Settings} facility to view and change
+Axiom system variables.
+
+\section{Common Features of Using Output Formats}
+\label{ugInOutOut}
+
+In this section we discuss how to start and stop the display
+\index{output formats!common features} of the different output formats
+and how to send the output to the screen or to a file.
+\index{file!sending output to} To fix ideas, we use FORTRAN output
+format for most of the examples.
+
+You can use the {\tt )set output} system \index{output
+formats!starting} command to \index{output formats!stopping} toggle or
+redirect the different kinds of output.  \index{set output} The name
+of the kind of output follows ``output'' in the command.  The names are
+
+\begin{tabular}{@{}ll}
+{\bf fortran} & for FORTRAN output. \\
+{\bf algebra} & for monospace two-dimensional mathematical output. \\
+{\bf tex}     & for \TeX{} output. \\
+{\bf script}  & for IBM Script Formula Format output.
+\end{tabular}
+
+For example, issue {\tt {)set output fortran on}} to turn on FORTRAN
+format and issue {\tt {)set output fortran off}} to turn it off.  By
+default, {\tt algebra} is {\tt on} and all others are {\tt off}.
+\index{set output fortran} When output is started, it is sent to the
+screen.  To send the output to a file, give the file name without
+\index{output formats!sending to file} directory or extension.  Axiom
+appends a file extension depending on the kind of output being
+produced.
+
+Issue this to redirect FORTRAN output to, for example, the file
+{\bf linalg.sfort}.
+\spadcommand{)set output fortran linalg}
+\begin{verbatim}
+   FORTRAN output will be written to file linalg.sfort .
+\end{verbatim}
+
+You must {\it also} turn on the creation of FORTRAN output.
+The above just says where it goes if it is created.
+\spadcommand{)set output fortran on}
+
+In what directory is this output placed?  It goes into the directory
+from which you started Axiom, or if you have used the {\tt {)cd}}
+system command, the one that you specified with {\tt {)cd}}.
+\index{cd} You should use {\tt )cd} before you send the output to the file.
+
+You can always direct output back to the screen by issuing this.
+\index{output formats!sending to screen}
+\spadcommand{)set output fortran console}
+
+Let's make sure FORTRAN formatting is off so that nothing we
+do from now on produces FORTRAN output.
+\spadcommand{)set output fortran off}
+
+We also delete the demonstrated output file we created.
+\spadcommand{)system rm linalg.sfort}
+
+You can abbreviate the words ``{\tt on},'' ``{\tt off},'' and 
+``{\tt console}'' to the minimal number of characters needed to distinguish
+them.  Because of this, you cannot send output to files called 
+{\bf on.sfort, off.sfort, of.sfort, console.sfort, consol.sfort} and so on.
+
+The width of the output on the page is set by \index{output
+formats!line length} {\tt )set output length} for all formats except
+FORTRAN.  \index{set output length} Use {\tt )set fortran fortlength}
+to change the FORTRAN line length from its default value of $72$.
+
+\section{Monospace Two-Dimensional Mathematical Format}
+\label{ugInOutAlgebra}
+
+This is the default output format for Axiom.  
+It is usually on when you start the system.  
+\index{set output algebra} 
+\index{output formats!monospace 2D} 
+\index{monospace 2D output format}
+
+If it is not, issue this.
+\spadcommand{)set output algebra on}
+
+Since the printed version of this book (as opposed to the HyperDoc
+version) shows output produced by the \TeX{} output formatter, let us
+temporarily turn off \TeX{} output.
+\spadcommand{)set output tex off}
+
+Here is an example of what it looks like.
+\spadcommand{matrix [ [i*x**i + j*\%i*y**j for i in 1..2] for j in 3..4]}
+\begin{verbatim}
+
+        +     3           3     2+
+        |3%i y  + x  3%i y  + 2x |
+   (1)  |                        |
+        |     4           4     2|
+        +4%i y  + x  4%i y  + 2x +
+\end{verbatim}
+\returnType{Type: Matrix Polynomial Complex Integer}
+
+Issue this to turn off this kind of formatting.
+\spadcommand{)set output algebra off}
+
+Turn \TeX{} output on again.
+\spadcommand{)set output tex on}
+
+The characters used for the matrix brackets above are rather ugly.
+You get this character set when you issue \index{character set} 
+{\tt )set output characters plain}.  \index{set output characters} This
+character set should be used when you are running on a machine that
+does not support the IBM extended ASCII character set.  If you are
+running on an IBM workstation, for example, issue 
+{\tt )set output characters default} to get better looking output.
+
+\section{TeX Format}
+\label{ugInOutTeX}
+
+Axiom can produce \TeX{} output for your \index{output formats!TeX
+@{\TeX{}}} expressions.  \index{TeX output format @{\TeX{}} output format}
+The output is produced using macros from the \LaTeX{} document
+preparation system by Leslie Lamport\cite{1}. The printed version
+of this book was produced using this formatter.
+
+To turn on \TeX{} output formatting, issue this.
+\index{set output tex}
+\spadcommand{)set output tex on}
+
+Here is an example of its output.
+\begin{verbatim}
+matrix [ [i*x**i + j*\%i*y**j for i in 1..2] for j in 3..4]
+
+$$
+\left[
+\begin{array}{cc}
+{{3 \  i \  {y \sp 3}}+x} & 
+{{3 \  i \  {y \sp 3}}+{2 \  {x \sp 2}}} \\ 
+{{4 \  i \  {y \sp 4}}+x} & 
+{{4 \  i \  {y \sp 4}}+{2 \  {x \sp 2}}} 
+\end{array}
+\right]
+$$
+
+\end{verbatim}
+This formats as
+$$
+\left[
+\begin{array}{cc}
+{{3 \  i \  {y \sp 3}}+x} & 
+{{3 \  i \  {y \sp 3}}+{2 \  {x \sp 2}}} \\ 
+{{4 \  i \  {y \sp 4}}+x} &  
+{{4 \  i \  {y \sp 4}}+{2 \  {x \sp 2}}} 
+\end{array}
+\right]
+$$
+
+To turn \TeX{} output formatting off, issue 
+{\tt {)set output tex off}}.
+The \LaTeX macros in the output generated by Axiom
+are all standard except for the following definitions:
+\begin{verbatim}
+\def\csch{\mathop{\rm csch}\nolimits}
+
+\def\erf{\mathop{\rm erf}\nolimits}
+
+\def\zag#1#2{
+  {{\hfill \left. {#1} \right|}
+   \over
+   {\left| {#2} \right. \hfill}
+  }
+}
+\end{verbatim}
+
+\section{IBM Script Formula Format}
+\label{ugInOutScript}
+
+Axiom can \index{output formats!IBM Script Formula Format} produce IBM
+Script Formula Format output for your 
+\index{IBM Script Formula Format} expressions.
+
+To turn IBM Script Formula Format on, issue this.
+\index{set output script}
+\spadcommand{)set output script on}
+
+Here is an example of its output.
+\begin{verbatim}
+matrix [ [i*x**i + j*%i*y**j for i in 1..2] for j in 3..4]
+
+.eq set blank @
+:df.
+<left lb < < < <3 @@ %i @@ <y sup 3> >+x> here < <3 @@ %i @@
+<y sup 3> >+<2 @@ <x sup 2> > > > habove < < <4 @@ %i @@
+<y sup 4> >+x> here < <4 @@ %i @@ <y sup 4> >+<2 @@
+<x up 2> > > > > right rb>
+:edf.
+\end{verbatim}
+
+To turn IBM Script Formula Format output formatting off, issue this.
+\spadcommand{)set output script off}
+
+\section{FORTRAN Format}
+\label{ugInOutFortran}
+
+In addition to turning FORTRAN output on and off and stating where the
+\index{output formats!FORTRAN} output should be placed, there are many
+options that control the \index{FORTRAN output format} appearance of
+the generated code.  In this section we describe some of the basic
+options.  Issue {\tt )set fortran} to see a full list with their
+current settings.
+
+The output FORTRAN expression usually begins in column 7.  If the
+expression needs more than one line, the ampersand character {\tt \&}
+is used in column 6.  Since some versions of FORTRAN have restrictions
+on the number of lines per statement, Axiom breaks long expressions
+into segments with a maximum of 1320 characters (20 lines of 66
+characters) per segment.  \index{set fortran} If you want to change
+this, say, to 660 characters, issue the system command 
+\index{set fortran explength} {\tt )set fortran explength 660}.  
+\index{FORTRAN output format!breaking into multiple statements} 
+You can turn off the line breaking by issuing {\tt )set fortran segment off}.
+\index{set fortran segment} Various code optimization levels are available.
+
+FORTRAN output is produced after you issue this.
+\index{set output fortran}
+\spadcommand{)set output fortran on}
+
+For the initial examples, we set the optimization level to 0, which is the
+lowest level.
+\index{set fortran optlevel}
+\spadcommand{)set fortran optlevel 0}
+
+The output is usually in columns 7 through 72, although fewer columns
+are used in the following examples so that the output
+\index{FORTRAN output format!line length}
+fits nicely on the page.
+\spadcommand{)set fortran fortlength 60}
+
+By default, the output goes to the screen and is displayed before the
+standard Axiom two-dimensional output.  In this example, an assignment
+to the variable $R1$ was generated because this is the result of step 1.
+\spadcommand{(x+y)**3}
+\begin{verbatim}
+      R1=y**3+3*x*y*y+3*x*x*y+x**3
+\end{verbatim}
+$$
+{y \sp 3}+{3 \  x \  {y \sp 2}}+{3 \  {x \sp 2} \  y}+{x \sp 3} 
+$$
+\returnType{Type: Polynomial Integer}
+
+Here is an example that illustrates the line breaking.
+\spadcommand{(x+y+z)**3}
+\begin{verbatim}
+      R2=z**3+(3*y+3*x)*z*z+(3*y*y+6*x*y+3*x*x)*z+y**3+3*x*y
+     &*y+3*x*x*y+x**3
+\end{verbatim}
+$$
+{z \sp 3}+{{\left( {3 \  y}+{3 \  x} 
+\right)}
+\  {z \sp 2}}+{{\left( {3 \  {y \sp 2}}+{6 \  x \  y}+{3 \  {x \sp 2}} 
+\right)}
+\  z}+{y \sp 3}+{3 \  x \  {y \sp 2}}+{3 \  {x \sp 2} \  y}+{x \sp 3} 
+$$
+\returnType{Type: Polynomial Integer}
+
+Note in the above examples that integers are generally converted to
+\index{FORTRAN output format!integers vs. floats} floating point
+numbers, except in exponents.  This is the default behavior but can be
+turned off by issuing {\tt )set fortran ints2floats off}.  
+\index{set fortran ints2floats} The rules governing when the conversion 
+is done are:
+\begin{enumerate}
+\item If an integer is an exponent, convert it to a floating point
+number if it is greater than 32767 in absolute value, otherwise leave it
+as an integer.
+\item Convert all other integers in an expression to floating point numbers.
+\end{enumerate}
+These rules only govern integers in expressions.  Numbers generated by
+Axiom for $DIMENSION$ statements are also integers.
+
+To set the type of generated FORTRAN data, 
+\index{FORTRAN output format!data types}
+use one of the following:
+\begin{verbatim}
+)set fortran defaulttype REAL
+)set fortran defaulttype INTEGER
+)set fortran defaulttype COMPLEX
+)set fortran defaulttype LOGICAL
+)set fortran defaulttype CHARACTER
+\end{verbatim}
+
+When temporaries are created, they are given a default type of {\tt REAL.}  
+Also, the {\tt REAL} versions of functions are used by default.
+\spadcommand{sin(x)}
+\begin{verbatim}
+      R3=DSIN(x)
+\end{verbatim}
+$$
+\sin 
+\left(
+{x} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+At optimization level 1, Axiom removes common subexpressions.
+\index{FORTRAN output format!optimization level}
+\index{set fortran optlevel}
+\spadcommand{)set fortran optlevel 1}
+
+\spadcommand{(x+y+z)**3}
+\begin{verbatim}
+      T2=y*y
+      T3=x*x
+      R4=z**3+(3*y+3*x)*z*z+(3*T2+6*x*y+3*T3)*z+y**3+3*x*T2+
+     &3*T3*y+x**3
+\end{verbatim}
+$$
+{z \sp 3}+{{\left( {3 \  y}+{3 \  x} 
+\right)}
+\  {z \sp 2}}+{{\left( {3 \  {y \sp 2}}+{6 \  x \  y}+{3 \  {x \sp 2}} 
+\right)}
+\  z}+{y \sp 3}+{3 \  x \  {y \sp 2}}+{3 \  {x \sp 2} \  y}+{x \sp 3} 
+$$
+\returnType{Type: Polynomial Integer}
+
+This changes the precision to {\tt DOUBLE}.  \index{set fortran
+precision double} Substitute {\tt single} for {\tt double}
+\index{FORTRAN output format!precision} to return to single precision.  
+\index{set fortran precision single}
+
+\spadcommand{)set fortran precision double}
+
+Complex constants display the precision.
+\spadcommand{2.3 + 5.6*\%i }
+\begin{verbatim}
+      R5=(2.3D0,5.6D0)
+\end{verbatim}
+$$
+{2.3}+{{5.6} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+The function names that Axiom generates depend on the chosen precision.
+\spadcommand{sin \%e}
+%%NOTE: the book shows DSIN(DEXP(1.0D0))
+\begin{verbatim}
+      R6=DSIN(DEXP(1))
+\end{verbatim}
+$$
+\sin 
+\left(
+{e} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+Reset the precision to {\tt single} and look at these two examples again.
+\spadcommand{)set fortran precision single}
+
+\spadcommand{2.3 + 5.6*\%i}
+\begin{verbatim}
+      R7=(2.3,5.6)
+\end{verbatim}
+$$
+{2.3}+{{5.6} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+\spadcommand{sin \%e}
+%%NOTE: the book shows SIN(EXP(1.))
+\begin{verbatim}
+      R8=SIN(EXP(1))
+\end{verbatim}
+$$
+\sin 
+\left(
+{e} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+Expressions that look like lists, streams, sets or matrices cause
+array code to be generated.
+\spadcommand{[x+1,y+1,z+1]}
+\begin{verbatim}
+      T1(1)=x+1
+      T1(2)=y+1
+      T1(3)=z+1
+      R9=T1
+\end{verbatim}
+$$
+\left[
+{x+1}, {y+1}, {z+1} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+
+A temporary variable is generated to be the name of the array.
+\index{FORTRAN output format!arrays} This may have to be changed in
+your particular application.
+\spadcommand{set[2,3,4,3,5]}
+\begin{verbatim}
+      T1(1)=2
+      T1(2)=3
+      T1(3)=4
+      T1(4)=5
+      R10=T1
+\end{verbatim}
+$$
+\left\{
+2,  3,  4,  5 
+\right\}
+$$
+\returnType{Type: Set PositiveInteger}
+
+By default, the starting index for generated FORTRAN arrays is $0$.
+\spadcommand{matrix [ [2.3,9.7],[0.0,18.778] ]}
+\begin{verbatim}
+      T1(0,0)=2.3
+      T1(0,1)=9.7
+      T1(1,0)=0.0
+      T1(1,1)=18.778
+      T1
+\end{verbatim}
+$$
+\left[
+\begin{array}{cc}
+{2.3} & {9.7} \\ 
+{0.0} & {18.778} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Float}
+
+To change the starting index for generated FORTRAN arrays to be $1$,
+\index{set fortran startindex} issue this.  This value can only be $0$
+or $1$.
+\spadcommand{)set fortran startindex 1}
+
+Look at the code generated for the matrix again.
+\spadcommand{matrix [ [2.3,9.7],[0.0,18.778] ]}
+\begin{verbatim}
+      T1(1,1)=2.3
+      T1(1,2)=9.7
+      T1(2,1)=0.0
+      T1(2,2)=18.778
+      T1
+\end{verbatim}
+$$
+\left[
+\begin{array}{cc}
+{2.3} & {9.7} \\ 
+{0.0} & {18.778} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Float}
+
+
+\setcounter{chapter}{4}
+
+\chapter{Overview of Interactive Language}
+\label{ugLang}
+
+In this chapter we look at some of the basic components of the Axiom
+language that you can use interactively.  We show how to create a {\it
+block} of expressions, how to form loops and list iterations, how to
+modify the sequential evaluation of a block and how to use 
+{\tt if-then-else} to evaluate parts of your program conditionally.  We
+suggest you first read the boxed material in each section and then
+proceed to a more thorough reading of the chapter.
+
+\section{Immediate and Delayed Assignments}
+\label{ugLangAssign}
+
+A {\it variable} in Axiom refers to a value.  A variable has a name
+beginning with an uppercase or lowercase alphabetic character, 
+``{\tt \%}'', or ``{\tt !}''.  Successive characters (if any) can be any of
+the above, digits, or ``{\tt ?}''.  Case is distinguished.  The
+following are all examples of valid, distinct variable names:
+
+\begin{verbatim}
+a             tooBig?    a1B2c3%!?
+A             %j         numberOfPoints
+beta6         %J         numberofpoints
+\end{verbatim}
+
+The ``{\tt :=}'' operator is the immediate {\it assignment} operator.
+\index{assignment!immediate} Use it to associate a value with a
+variable.  \index{immediate assignment}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for immediate assignment for a single variable is
+\begin{center}
+{\it variable} $:=$ {\it expression}
+\end{center}
+The value returned by an immediate assignment is the value of 
+{\it expression}.\\
+}
+
+The right-hand side of the expression is evaluated, yielding $1$.
+This value is then assigned to $a$.
+\spadcommand{a := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+The right-hand side of the expression is evaluated, yielding $1$.
+This value is then assigned to $b$.  Thus $a$ and $b$ both have the
+value $1$ after the sequence of assignments.
+\spadcommand{b := a}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+What is the value of $b$ if $a$ is assigned the value $2$?
+\spadcommand{a := 2}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+As you see, the value of $b$ is left unchanged.
+\spadcommand{b}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+This is what we mean when we say this kind of assignment is {\it
+immediate}; $b$ has no dependency on $a$ after the initial assignment.
+This is the usual notion of assignment found in programming languages
+such as C, \index{C language!assignment} PASCAL
+\index{PASCAL!assignment} and FORTRAN.  \index{FORTRAN!assignment}
+
+Axiom provides delayed assignment with ``{\tt ==}''.
+\index{assignment!delayed} This implements a \index{delayed
+assignment} delayed evaluation of the right-hand side and dependency
+checking.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for delayed assignment is
+\begin{center}
+{\it variable} $==$ {\it expression}
+\end{center}
+The value returned by a delayed assignment is the unique value of {\tt Void}.\\
+}
+
+Using $a$ and $b$ as above, these are the corresponding delayed assignments.
+\spadcommand{a == 1}
+\returnType{Type: Void}
+
+\spadcommand{b == a}
+\returnType{Type: Void}
+
+The right-hand side of each delayed assignment is left unevaluated
+until the variables on the left-hand sides are evaluated.  Therefore
+this evaluation and \ldots
+\spadcommand{a}
+\begin{verbatim}
+Compiling body of rule a to compute value of type PositiveInteger 
+\end{verbatim}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+this evaluation seem the same as before.
+\spadcommand{b}
+\begin{verbatim}
+Compiling body of rule b to compute value of type PositiveInteger 
+\end{verbatim}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+If we change $a$ to $2$
+\spadcommand{a == 2}
+\begin{verbatim}
+   Compiled code for a has been cleared.
+   Compiled code for b has been cleared.
+   1 old definition(s) deleted for function or rule a 
+\end{verbatim}
+\returnType{Type: Void}
+
+then $a$ evaluates to $2$, as expected, but
+\spadcommand{a}
+\begin{verbatim}
+Compiling body of rule a to compute value of type PositiveInteger 
+
++++ |*0;a;1;G82322| redefined
+\end{verbatim}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+the value of $b$ reflects the change to $a$.
+\spadcommand{b}
+\begin{verbatim}
+Compiling body of rule b to compute value of type PositiveInteger 
+
++++ |*0;b;1;G82322| redefined
+\end{verbatim}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+It is possible to set several variables at the same time
+\index{assignment!multiple immediate} by using \index{multiple
+immediate assignment} a {\it tuple} of variables and a tuple of
+expressions. Note that a {\it tuple} is a collection of things
+separated by commas, often surrounded by parentheses.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for multiple immediate assignments is
+\begin{center}
+{\tt ( $\hbox{\it var}_{1}$, $\hbox{\it var}_{2}$, \ldots, 
+$\hbox{\it var}_{N}$ ) := ( $\hbox{\it expr}_{1}$, $\hbox{\it expr}_{2}$, 
+\ldots, $\hbox{\it expr}_{N}$ ) }
+\end{center}
+The value returned by an immediate assignment is the value of
+$\hbox{\it expr}_{N}$.\\
+}
+
+This sets $x$ to $1$ and $y$ to $2$.
+\spadcommand{(x,y) := (1,2)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+Multiple immediate assigments are parallel in the sense that the
+expressions on the right are all evaluated before any assignments on
+the left are made.  However, the order of evaluation of these
+expressions is undefined.
+
+You can use multiple immediate assignment to swap the values held by
+variables.
+\spadcommand{(x,y) := (y,x)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+$x$ has the previous value of $y$.
+\spadcommand{x}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+$y$ has the previous value of $x$.
+\spadcommand{y}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+There is no syntactic form for multiple delayed assignments.  See the
+discussion in section \ref{ugUserDelay} on page~\pageref{ugUserDelay}
+about how Axiom differentiates between delayed assignments and user
+functions of no arguments.
+
+\section{Blocks}
+\label{ugLangBlocks}
+
+A {\it block} is a sequence of expressions evaluated in the order that
+they appear, except as modified by control expressions such as
+{\tt break}, \index{break} {\tt return}, \index{return} {\tt iterate} and
+\index{iterate} {\tt if-then-else} constructions.  The value of a block is
+the value of the expression last evaluated in the block.
+
+To leave a block early, use ``{\tt =>}''.  For example, $i < 0 => x$.  The
+expression before the ``{\tt =>}'' must evaluate to {\tt true} or {\tt false}.
+The expression following the ``{\tt =>}'' is the return value for the block.
+
+A block can be constructed in two ways:
+\begin{enumerate}
+\item the expressions can be separated by semicolons
+and the resulting expression surrounded by parentheses, and
+\item the expressions can be written on succeeding lines with each line
+indented the same number of spaces (which must be greater than zero).
+\index{indentation}
+A block entered in this form is
+called a {\it pile}.
+\end{enumerate}
+Only the first form is available if you are entering expressions
+directly to Axiom.  Both forms are available in {\bf .input} files.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for a simple block of expressions entered interactively is
+\begin{center}
+{\tt ( $\hbox{\it expression}_{1}$; $\hbox{\it expression}_{2}$; \ldots; 
+$\hbox{\it expression}_{N}$ )}
+\end{center}
+The value returned by a block is the value of an {\tt =>} expression,
+or $\hbox{\it expression}_{N}$ if no {\tt =>} is encountered.\\
+}
+
+In {\bf .input} files, blocks can also be written using piles.  The
+examples throughout this book are assumed to come from {\bf .input} files.
+
+In this example, we assign a rational number to $a$ using a block
+consisting of three expressions.  This block is written as a pile.
+Each expression in the pile has the same indentation, in this case two
+spaces to the right of the first line.
+\begin{verbatim}
+a :=
+  i := gcd(234,672)
+  i := 3*i**5 - i + 1
+  1 / i
+\end{verbatim}
+$$
+1 \over {23323} 
+$$
+\returnType{Type: Fraction Integer}
+
+Here is the same block written on one line.  This is how you are
+required to enter it at the input prompt.
+\spadcommand{a := (i := gcd(234,672); i := 3*i**5 - i + 1; 1 / i)}
+$$
+1 \over {23323} 
+$$
+\returnType{Type: Fraction Integer}
+
+Blocks can be used to put several expressions on one line.  The value
+returned is that of the last expression.
+\spadcommand{(a := 1; b := 2; c := 3; [a,b,c])}
+$$
+\left[
+1,  2,  3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Axiom gives you two ways of writing a block and the preferred way in
+an {\bf .input} file is to use a pile.  \index{file!input} Roughly
+speaking, a pile is a block whose constituent expressions are indented
+the same amount.  You begin a pile by starting a new line for the
+first expression, indenting it to the right of the previous line.  You
+then enter the second expression on a new line, vertically aligning it
+with the first line. And so on.  If you need to enter an inner pile,
+further indent its lines to the right of the outer pile.  Axiom knows
+where a pile ends.  It ends when a subsequent line is indented to the
+left of the pile or the end of the file.
+
+Blocks can be used to perform several steps before an assignment
+(immediate or delayed) is made.
+\begin{verbatim}
+d :=
+   c := a**2 + b**2
+   sqrt(c * 1.3)
+\end{verbatim}
+$$
+2.5495097567 96392415 
+$$
+\returnType{Type: Float}
+
+Blocks can be used in the arguments to functions.  (Here $h$ is
+assigned $2.1 + 3.5$.)
+\begin{verbatim}
+h := 2.1 +
+   1.0
+   3.5
+\end{verbatim}
+$$
+5.6 
+$$
+\returnType{Type: Float}
+
+Here the second argument to {\bf eval} is $x = z$, where the value of
+$z$ is computed in the first line of the block starting on the second
+line.
+\begin{verbatim}
+eval(x**2 - x*y**2,
+     z := %pi/2.0 - exp(4.1)
+     x = z
+   )
+\end{verbatim}
+$$
+{{58.7694912705 67072878} \  {y \sp 2}}+{3453.8531042012 59382} 
+$$
+\returnType{Type: Polynomial Float}
+
+Blocks can be used in the clauses of {\tt if-then-else} expressions 
+(see \ref{ugLangIf} on page~\pageref{ugLangIf}).
+
+\spadcommand{if h > 3.1 then 1.0 else (z := cos(h); max(z,0.5))}
+$$
+1.0 
+$$
+\returnType{Type: Float}
+
+This is the pile version of the last block.
+\begin{verbatim}
+if h > 3.1 then
+    1.0
+  else
+    z := cos(h)
+    max(z,0.5)
+\end{verbatim}
+$$
+1.0 
+$$
+\returnType{Type: Float}
+
+Blocks can be nested.
+\spadcommand{a := (b := factorial(12); c := (d := eulerPhi(22); factorial(d));b+c)}
+$$
+482630400 
+$$
+\returnType{Type: PositiveInteger}
+
+This is the pile version of the last block.
+\begin{verbatim}
+a :=
+  b := factorial(12)
+  c :=
+    d := eulerPhi(22)
+    factorial(d)
+  b+c
+\end{verbatim}
+$$
+482630400 
+$$
+\returnType{Type: PositiveInteger}
+
+Since $c + d$ does equal $3628855$, $a$ has the value of $c$ and the
+last line is never evaluated.
+\begin{verbatim}
+a :=
+  c := factorial 10
+  d := fibonacci 10
+  c + d = 3628855 => c
+  d
+\end{verbatim}
+$$
+3628800 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{if-then-else}
+\label{ugLangIf}
+
+Like many other programming languages, Axiom uses the three keywords
+\index{if} {\tt if}, {\tt then} \index{then} and {\tt else}
+\index{else} to form \index{conditional} conditional expressions.  The
+{\tt else} part of the conditional is optional.  The expression
+between the {\tt if} and {\tt then} keywords is a {\it predicate}: an
+expression that evaluates to or is convertible to either {\tt true} or
+{\tt false}, that is, a {\tt Boolean}.  \index{Boolean}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for conditional expressions is
+\begin{center}
+{\tt if\ }{\it predicate} 
+{\tt then\ }$\hbox{\it expression}_{1}$ 
+{\tt else\ }$\hbox{\it expression}_{2}$
+\end{center}
+where the {\tt else} $\hbox{\it expression}_{2}$ part is optional.  The
+value returned from a conditional expression is 
+$\hbox{\it expression}_{1}$ if the predicate evaluates to {\tt true} and 
+$\hbox{\it expression}_{2}$ otherwise.  If no {\tt else} clause is given, 
+the value is always the unique value of {\tt Void}.\\
+}
+
+An {\tt if-then-else} expression always returns a value.  If the 
+{\tt else} clause is missing then the entire expression returns the unique
+value of {\tt Void}.  If both clauses are present, the type of the
+value returned by {\tt if} is obtained by resolving the types of the
+values of the two clauses.  See \ref{ugTypesResolve} on
+page~\pageref{ugTypesResolve} for more information.
+
+The predicate must evaluate to, or be convertible to, an object of
+type {\tt Boolean}: {\tt true} or {\tt false}.  By default, the equal
+sign \spadopFrom{=}{Equation} creates \index{equation} an equation.
+
+This is an equation.  \index{Equation} In particular, it is an object
+of type {\tt Equation Polynomial Integer}.
+
+\spadcommand{x + 1 = y}
+$$
+{x+1}=y 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+However, for predicates in {\tt if} expressions, Axiom \index{equality
+testing} places a default target type of {\tt Boolean} on the
+predicate and equality testing is performed.  \index{Boolean} Thus you
+need not qualify the ``{\tt =}'' in any way.  In other contexts you
+may need to tell Axiom that you want to test for equality rather than
+create an equation.  In those cases, use ``{\tt @}'' and a target type
+of {\tt Boolean}.  See section \ref{ugTypesPkgCall} on
+page~\pageref{ugTypesPkgCall} for more information.
+
+The compound symbol meaning ``not equal'' in Axiom is
+\index{inequality testing} ``{$\sim =$}''.  \index{\_notequal@$\sim =$} 
+This can be used directly without a package call or a target
+specification.  The expression $a$~$\sim =$~$b$ is directly translated
+into {\tt not}$(a = b)$.
+
+Many other functions have return values of type {\tt Boolean}.  These
+include ``{\tt <}'', ``{\tt <=}'', ``{\tt >}'', ``{\tt >=}'', 
+``{\tt $\sim$=}'' and ``{\bf member?}''.  By convention,
+operations with names ending in ``{\tt ?}''  return {\tt Boolean} values.
+
+The usual rules for piles are suspended for conditional expressions.
+In {\bf .input} files, the {\tt then} and {\tt else} keywords can begin in the
+same column as the corresponding {\tt if} but may also appear to the
+right.  Each of the following styles of writing {\tt if-then-else}
+expressions is acceptable:
+\begin{verbatim}
+if i>0 then output("positive") else output("nonpositive")
+
+if i > 0 then output("positive")
+  else output("nonpositive")
+
+if i > 0 then output("positive")
+else output("nonpositive")
+
+if i > 0
+then output("positive")
+else output("nonpositive")
+
+if i > 0
+  then output("positive")
+  else output("nonpositive")
+\end{verbatim}
+
+A block can follow the {\tt then} or {\tt else} keywords.  In the following
+two assignments to {\tt a}, the {\tt then} and {\tt else} clauses each are
+followed by two-line piles.  The value returned in each is the value
+of the second line.
+\begin{verbatim}
+a :=
+  if i > 0 then
+    j := sin(i * pi())
+    exp(j + 1/j)
+  else
+    j := cos(i * 0.5 * pi())
+    log(abs(j)**5 + 1)
+
+a :=
+  if i > 0
+    then
+      j := sin(i * pi())
+      exp(j + 1/j)
+    else
+      j := cos(i * 0.5 * pi())
+      log(abs(j)**5 + 1)
+\end{verbatim}
+
+These are both equivalent to the following:
+\begin{verbatim}
+a :=
+  if i > 0 then (j := sin(i * pi()); exp(j + 1/j))
+  else (j := cos(i * 0.5 * pi()); log(abs(j)**5 + 1))
+\end{verbatim}
+
+\section{Loops}
+\label{ugLangLoops}
+
+A {\it loop} is an expression that contains another expression,
+\index{loop} called the {\it loop body}, which is to be evaluated zero
+or more \index{loop!body} times.  All loops contain the {\tt repeat}
+keyword and return the unique value of {\tt Void}.  Loops can contain
+inner loops to any depth.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The most basic loop is of the form
+\begin{center}
+{\tt repeat\ }{\it loopBody}
+\end{center}
+
+Unless {\it loopBody} contains a {\tt break} or {\tt return} expression, the
+loop repeats forever.  The value returned by the loop is the unique
+value of {\tt Void}.\\
+}
+
+\subsection{Compiling vs. Interpreting Loops}
+\label{ugLangLoopsCompInt}
+
+Axiom tries to determine completely the type of every object in a loop
+and then to translate the loop body to LISP or even to machine code.
+This translation is called compilation.
+
+If Axiom decides that it cannot compile the loop, it issues a
+\index{loop!compilation} message stating the problem and then the
+following message:
+\begin{center}
+{\bf We will attempt to step through and interpret the code.}
+\end{center}
+
+It is still possible that Axiom can evaluate the loop but in {\it
+interpret-code mode}.  See section \ref{ugUserCompInt} on
+page~\pageref{ugUserCompInt} where this is discussed in terms
+\index{panic!avoiding} of compiling versus interpreting functions.
+
+\subsection{return in Loops}
+\label{ugLangLoopsReturn}
+
+A {\tt return} expression is used to exit a function with
+\index{loop!leaving via return} a particular value.  In particular, if
+a {\tt return} is in a loop within the \index{return} function, the loop
+is terminated whenever the {\tt return} is evaluated.
+%> This is a bug! The compiler should never accept allow
+%> Void to be the return type of a function when it has to use
+%> resolve to determine it.
+
+Suppose we start with this.
+\begin{verbatim}
+f() ==
+  i := 1
+  repeat
+    if factorial(i) > 1000 then return i
+    i := i + 1
+\end{verbatim}
+\returnType{Type: Void}
+
+When {\tt factorial(i)} is big enough, control passes from inside the loop
+all the way outside the function, returning the value of $i$ (or so we
+think).
+\spadcommand{f()}
+\returnType{Type: Void}
+
+What went wrong?  Isn't it obvious that this function should return an
+integer?  Well, Axiom makes no attempt to analyze the structure of a
+loop to determine if it always returns a value because, in general,
+this is impossible.  So Axiom has this simple rule: the type of the
+function is determined by the type of its body, in this case a block.
+The normal value of a block is the value of its last expression, in
+this case, a loop.  And the value of every loop is the unique value of
+{\tt Void}.!  So the return type of {\bf f} is {\tt Void}.
+
+There are two ways to fix this.  The best way is for you to tell Axiom
+what the return type of $f$ is.  You do this by giving $f$ a
+declaration {\tt f:()~->~Integer} prior to calling for its value.  This
+tells Axiom: ``trust me---an integer is returned.''  We'll explain
+more about this in the next chapter.  Another clumsy way is to add a
+dummy expression as follows.
+
+Since we want an integer, let's stick in a dummy final expression that is
+an integer and will never be evaluated.
+\begin{verbatim}
+f() ==
+  i := 1
+  repeat
+    if factorial(i) > 1000 then return i
+    i := i + 1
+  0
+\end{verbatim}
+\returnType{Type: Void}
+
+When we try {\bf f} again we get what we wanted.  See
+\ref{ugUserBlocks} on page~\pageref{ugUserBlocks} for more information.
+
+\spadcommand{f()}
+\begin{verbatim}
+   Compiling function f with type () -> NonNegativeInteger 
+\end{verbatim}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{break in Loops}
+\label{ugLangLoopsBreak}
+
+The {\tt break} keyword is often more useful \index{break} in terminating
+\index{loop!leaving via break} a loop.  A {\tt break} causes control to
+transfer to the expression immediately following the loop.  As loops
+always return the unique value of {\tt Void}., you cannot return a
+value with {\tt break}.  That is, {\tt break} takes no argument.
+
+This example is a modification of the last example in the previous
+section \ref{ugLangLoopsReturn} on page~\pageref{ugLangLoopsReturn}.
+Instead of using {\tt return}, we'll use {\tt break}.
+
+\begin{verbatim}
+f() ==
+  i := 1
+  repeat
+    if factorial(i) > 1000 then break
+    i := i + 1
+  i
+\end{verbatim}
+\begin{verbatim}
+   Compiled code for f has been cleared.
+   1 old definition(s) deleted for function or rule f 
+\end{verbatim}
+\returnType{Type: Void}
+
+The loop terminates when {\tt factorial(i)} gets big enough, the last line
+of the function evaluates to the corresponding ``good'' value of $i$,
+and the function terminates, returning that value.
+
+\spadcommand{f()}
+\begin{verbatim}
+   Compiling function f with type () -> PositiveInteger 
+
++++ |*0;f;1;G82322| redefined
+\end{verbatim}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+You can only use {\tt break} to terminate the evaluation of one loop.
+Let's consider a loop within a loop, that is, a loop with a nested
+loop.  First, we initialize two counter variables.
+
+\spadcommand{(i,j) := (1, 1)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Nested loops must have multiple {\tt break} \index{loop!nested}
+expressions at the appropriate nesting level.  How would you rewrite
+this so {\tt (i + j) > 10} is only evaluated once?
+\begin{verbatim}
+repeat
+  repeat
+    if (i + j) > 10 then break
+    j := j + 1
+  if (i + j) > 10 then break
+  i := i + 1
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{break vs. {\tt =>} in Loop Bodies}
+\label{ugLangLoopsBreakVs}
+
+Compare the following two loops:
+\begin{verbatim}
+i := 1                            i := 1
+repeat                            repeat
+  i := i + 1                        i := i + 1
+  i > 3 => i                        if i > 3 then break
+  output(i)                         output(i)
+\end{verbatim}
+
+In the example on the left, the values $2$ and $3$ for $i$ are
+displayed but then the ``{\tt =>}'' does not allow control to reach the
+call to \spadfunFrom{output}{OutputForm} again.  The loop will not
+terminate until you run out of space or interrupt the execution.  The
+variable $i$ will continue to be incremented because the ``{\tt =>}'' only
+means to leave the {\it block}, not the loop.
+
+In the example on the right, upon reaching $4$, the {\tt break} will be
+executed, and both the block and the loop will terminate.  This is one
+of the reasons why both ``{\tt =>}'' and {\tt break} are provided.  Using a
+{\tt while} clause (see below) with the ``{\tt =>}'' \index{while} lets you
+simulate the action of {\tt break}.
+
+\subsection{More Examples of break}
+\label{ugLangLoopsBreakMore}
+
+Here we give four examples of {\tt repeat} loops that terminate when a
+value exceeds a given bound.
+
+First, initialize $i$ as the loop counter.
+\spadcommand{i := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Here is the first loop.  When the square of $i$ exceeds $100$, the
+loop terminates.
+\begin{verbatim}
+repeat
+  i := i + 1
+  if i**2 > 100 then break
+\end{verbatim}
+\returnType{Type: Void}
+
+Upon completion, $i$ should have the value $11$.
+\spadcommand{i}
+$$
+11 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Do the same thing except use ``{\tt =>}'' instead an {\tt if-then} expression.
+
+\spadcommand{i := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+\begin{verbatim}
+repeat
+  i := i + 1
+  i**2 > 100 => break
+\end{verbatim}
+\returnType{Type: Void}
+
+\spadcommand{i}
+$$
+11 
+$$
+\returnType{Type: NonNegativeInteger}
+
+As a third example, we use a simple loop to compute $n!$.
+\spadcommand{(n, i, f) := (100, 1, 1)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Use $i$ as the iteration variable and $f$ to compute the factorial.
+\begin{verbatim}
+repeat
+  if i > n then break
+  f := f * i
+  i := i + 1
+\end{verbatim}
+\returnType{Type: Void}
+
+Look at the value of $f$.
+\spadcommand{f}
+\begin{verbatim}
+ 93326215443944152681699238856266700490715968264381621468_
+ 59296389521759999322991560894146397615651828625369792082_
+ 7223758251185210916864000000000000000000000000
+\end{verbatim}
+\returnType{Type: PositiveInteger}
+
+Finally, we show an example of nested loops.  First define a four by
+four matrix.
+\spadcommand{m := matrix [ [21,37,53,14], [8,-24,22,-16], [2,10,15,14], [26,33,55,-13] ]}
+$$
+\left[
+\begin{array}{cccc}
+{21} & {37} & {53} & {14} \\ 
+8 & -{24} & {22} & -{16} \\ 
+2 & {10} & {15} & {14} \\ 
+{26} & {33} & {55} & -{13} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+Next, set row counter $r$ and column counter $c$ to $1$.  Note: if we
+were writing a function, these would all be local variables rather
+than global workspace variables.
+\spadcommand{(r, c) := (1, 1)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Also, let {\tt lastrow} and {\tt lastcol} be the final row and column index.
+
+\spadcommand{(lastrow, lastcol) := (nrows(m), ncols(m))}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+Scan the rows looking for the first negative element.  We remark that
+you can reformulate this example in a better, more concise form by
+using a {\tt for} clause with {\tt repeat}.  See
+\ref{ugLangLoopsForIn} on page~\pageref{ugLangLoopsForIn} for more
+information.
+
+\begin{verbatim}
+repeat
+  if r > lastrow then break
+  c := 1
+  repeat
+    if c > lastcol then break
+    if elt(m,r,c) < 0 then
+      output [r, c, elt(m,r,c)]
+      r := lastrow
+      break     -- don't look any further
+    c := c + 1
+  r := r + 1
+ 
+   [2,2,- 24]
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{iterate in Loops}
+\label{ugLangLoopsIterate}
+
+Axiom provides an {\tt iterate} expression that \index{iterate} skips over
+the remainder of a loop body and starts the next loop iteration.
+
+We first initialize a counter.
+
+\spadcommand{i := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Display the even integers from $2$ to $5$.
+\begin{verbatim}
+repeat
+  i := i + 1
+  if i > 5 then break
+  if odd?(i) then iterate
+  output(i)
+ 
+   2
+   4
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{while Loops}
+\label{ugLangLoopsWhile}
+
+The {\tt repeat} in a loop can be modified by adding one or more {\tt while}
+clauses.  \index{while} Each clause contains a {\it predicate}
+immediately following the {\tt while} keyword.  The predicate is tested
+{\it before} the evaluation of the body of the loop.  The loop body is
+evaluated whenever the predicates in a {\tt while} clause are all {\tt true}.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for a simple loop using {\tt while} is
+\begin{center}
+{\tt while} {\it predicate} {\tt repeat} {\it loopBody}
+\end{center}
+The {\it predicate} is evaluated before {\it loopBody} is evaluated.
+A {\tt while} loop terminates immediately when {\it predicate} evaluates
+to {\tt false} or when a {\tt break} or {\tt return} expression is evaluated in
+{\it loopBody}.  The value returned by the loop is the unique value of
+{\tt Void}.\\
+}
+
+Here is a simple example of using {\tt while} in a loop.  We first
+initialize the counter.
+\spadcommand{i := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+The steps involved in computing this example are\\
+(1) set $i$ to $1$,\\
+(2) test the condition $i < 1$ and determine that it is not {\tt true}, and\\
+(3) do not evaluate the loop body and therefore do not display $"hello"$.
+\begin{verbatim}
+while i < 1 repeat
+  output "hello"
+  i := i + 1
+\end{verbatim}
+\returnType{Type: Void}
+
+If you have multiple predicates to be tested use the logical {\tt and}
+operation to separate them.  Axiom evaluates these predicates from
+left to right.
+\spadcommand{(x, y) := (1, 1)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\begin{verbatim}
+while x < 4 and y < 10 repeat
+  output [x,y]
+  x := x + 1
+  y := y + 2
+ 
+   [1,1]
+   [2,3]
+   [3,5]
+\end{verbatim}
+\returnType{Type: Void}
+
+A {\tt break} expression can be included in a loop body to terminate a
+loop even if the predicate in any {\tt while} clauses are not {\tt false}.
+\spadcommand{(x, y) := (1, 1)}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+This loop has multiple {\tt while} clauses and the loop terminates
+before any one of their conditions evaluates to {\tt false}.
+\begin{verbatim}
+while x < 4 while y < 10 repeat
+  if x + y > 7 then break
+  output [x,y]
+  x := x + 1
+  y := y + 2
+ 
+   [1,1]
+   [2,3]
+\end{verbatim}
+\returnType{Type: Void}
+
+Here's a different version of the nested loops that looked for the
+first negative element in a matrix.
+\spadcommand{m := matrix [ [21,37,53,14], [8,-24,22,-16], [2,10,15,14], [26,33,55,-13] ]}
+$$
+\left[
+\begin{array}{cccc}
+{21} & {37} & {53} & {14} \\ 
+8 & -{24} & {22} & -{16} \\ 
+2 & {10} & {15} & {14} \\ 
+{26} & {33} & {55} & -{13} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+Initialized the row index to $1$ and get the number of rows and
+columns.  If we were writing a function, these would all be local
+variables.
+\spadcommand{r := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{(lastrow, lastcol) := (nrows(m), ncols(m))}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+Scan the rows looking for the first negative element.
+\begin{verbatim}
+while r <= lastrow repeat
+  c := 1  -- index of first column
+  while c <= lastcol repeat
+    if elt(m,r,c) < 0 then
+      output [r, c, elt(m,r,c)]
+      r := lastrow
+      break     -- don't look any further
+    c := c + 1
+  r := r + 1
+ 
+   [2,2,- 24]
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{for Loops}
+\label{ugLangLoopsForIn}
+
+Axiom provides the {\tt for} \index{for} and {\tt in\ } \index{in} keywords in
+{\tt repeat} loops, allowing you to iterate across all \index{iteration}
+elements of a list, or to have a variable take on integral values from
+a lower bound to an upper bound.  We shall refer to these modifying
+clauses of {\tt repeat} loops as {\tt for} clauses.  These clauses can be
+present in addition to {\tt while} clauses.  As with all other types of
+{\tt repeat} loops, {\tt break} can \index{break} be used to prematurely
+terminate the evaluation of the loop.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The syntax for a simple loop using {\tt for} is
+\begin{center}
+{\tt for} {\it iterator} {\tt repeat} {\it loopBody}
+\end{center}
+
+The {\it iterator} has several forms.  Each form has an end test which
+is evaluated before {\it loopBody} is evaluated.  A {\tt for} loop
+terminates immediately when the end test succeeds (evaluates to 
+{\tt true}) or when a {\tt break} or {\tt return} expression is evaluated
+in {\it loopBody}.  The value returned by the loop is the unique value
+of {\tt Void}.\\ }
+
+\subsection{for i in n..m repeat}
+\label{ugLangLoopsForInNM}
+
+If {\tt for} \index{for} is followed by a variable name, the {\tt in\ }
+\index{in} keyword and then an integer segment of the form $n..m$,
+\index{segment} the end test for this loop is the predicate $i > m$.
+The body of the loop is evaluated $m-n+1$ times if this number is
+greater than 0.  If this number is less than or equal to 0, the loop
+body is not evaluated at all.
+
+The variable $i$ has the value $n, n+1, ..., m$ for successive iterations
+of the loop body.The loop variable is a {\it local variable}
+within the loop body: its value is not available outside the loop body
+and its value and type within the loop body completely mask any outer
+definition of a variable with the same name.
+
+This loop prints the values of
+${10}^3$, ${11}^3$, and $12^3$:
+\spadcommand{for i in 10..12 repeat output(i**3)}
+\begin{verbatim}
+   1000
+   1331
+   1728
+\end{verbatim}
+\returnType{Type: Void}
+
+Here is a sample list.
+\spadcommand{a := [1,2,3]}
+$$
+\left[
+1,  2,  3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Iterate across this list, using ``{\tt .}'' to access the elements of
+a list and the ``{\bf \#}'' operation to count its elements.
+
+\spadcommand{for i in 1..\#a repeat output(a.i)}
+\begin{verbatim}
+   1
+   2
+   3
+\end{verbatim}
+\returnType{Type: Void}
+
+This type of iteration is applicable to anything that uses ``{\tt .}''.
+You can also use it with functions that use indices to extract elements.
+
+Define $m$ to be a matrix.
+\spadcommand{m := matrix [ [1,2],[4,3],[9,0] ]}
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+4 & 3 \\ 
+9 & 0 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+Display the rows of $m$.
+\spadcommand{for i in 1..nrows(m) repeat output row(m,i)}
+\begin{verbatim}
+   [1,2]
+   [4,3]
+   [9,0]
+\end{verbatim}
+\returnType{Type: Void}
+
+You can use {\tt iterate} with {\tt for}-loops.\index{iterate}
+
+Display the even integers in a segment.
+\begin{verbatim}
+for i in 1..5 repeat
+  if odd?(i) then iterate
+  output(i)
+ 
+   2
+   4
+\end{verbatim}
+\returnType{Type: Void}
+
+See section \ref{SegmentXmpPage} on page~\pageref{SegmentXmpPage} for
+more information about segments.
+
+\subsection{for i in n..m by s repeat}
+\label{ugLangLoopsForInNMS}
+
+By default, the difference between values taken on by a variable in
+loops such as {\tt for i in n..m repeat ...} is $1$.  It is possible to
+supply another, possibly negative, step value by using the {\tt by}
+\index{by} keyword along with {\tt for} and {\tt in\ }.  Like the upper and
+lower bounds, the step value following the {\tt by} keyword must be an
+integer.  Note that the loop {\tt for i in 1..2 by 0 repeat output(i)}
+will not terminate by itself, as the step value does not change the
+index from its initial value of $1$.
+
+This expression displays the odd integers between two bounds.
+\spadcommand{for i in 1..5 by 2 repeat output(i)}
+\begin{verbatim}
+   1
+   3
+   5
+\end{verbatim}
+\returnType{Type: Void}
+
+Use this to display the numbers in reverse order.
+\spadcommand{for i in 5..1 by -2 repeat output(i)}
+\begin{verbatim}
+   5
+   3
+   1
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{for i in n.. repeat}
+\label{ugLangLoopsForInN}
+
+If the value after the ``{\tt ..}''  is omitted, the loop has no end test.
+A potentially infinite loop is thus created.  The variable is given
+the successive values ${n}, {n+1}, {n+2}, ...$ and the loop is terminated
+only if a {\tt break} or {\tt return} expression is evaluated in the loop
+body.  However you may also add some other modifying clause on the
+{\tt repeat} (for example, a {\tt while} clause) to stop the loop.
+
+This loop displays the integers greater than or equal to $15$
+and less than the first prime greater than $15$.
+\spadcommand{for i in 15.. while not prime?(i) repeat output(i)}
+\begin{verbatim}
+   15
+   16
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{for x in l repeat}
+\label{ugLangLoopsForInXL}
+
+Another variant of the {\tt for} loop has the form:
+\begin{center}
+{\it {\tt for} x {\tt in\ } list {\tt repeat} loopBody}
+\end{center}
+
+This form is used when you want to iterate directly over the elements
+of a list.  In this form of the {\tt for} loop, the variable {\tt x} takes on
+the value of each successive element in {\tt l}.  The end test is most
+simply stated in English: ``are there no more {\tt x} in {\tt l}?''
+
+If {\tt l} is this list,
+\spadcommand{l := [0,-5,3]}
+$$
+\left[
+0,  -5,  3 
+\right]
+$$
+\returnType{Type: List Integer}
+
+display all elements of {\tt l}, one per line.
+\spadcommand{for x in l repeat output(x)}
+\begin{verbatim}
+   0
+   - 5
+   3
+\end{verbatim}
+\returnType{Type: Void}
+
+Since the list constructing expression {\bf expand}{\tt [n..m]} creates the
+list $[n, {n+1}, ..., m]$. Note that this list is empty if $n > m$.  You
+might be tempted to think that the loops
+\begin{verbatim}
+for i in n..m repeat output(i)
+\end{verbatim}
+
+and
+\begin{verbatim}
+for x in expand [n..m] repeat output(x)
+\end{verbatim}
+
+are equivalent.  The second form first creates the list {\bf
+expand}{\tt [n..m]} (no matter how large it might be) and then does
+the iteration.  The first form potentially runs in much less space, as
+the index variable $i$ is simply incremented once per loop and the
+list is not actually created.  Using the first form is much more
+efficient.
+
+Of course, sometimes you really want to iterate across a specific list.
+This displays each of the factors of $2400000$.
+\spadcommand{for f in factors(factor(2400000)) repeat output(f)}
+\begin{verbatim}
+   [factor= 2,exponent= 8]
+   [factor= 3,exponent= 1]
+   [factor= 5,exponent= 5]
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{``Such that'' Predicates}
+\label{ugLangLoopsForInPred}
+
+A {\tt for} loop can be followed by a ``{\tt |}'' and then a predicate.  The
+predicate qualifies the use of the values from the iterator following
+the {\tt for}.  Think of the vertical bar ``{\tt |}'' as the phrase ``such
+that.''
+
+This loop expression prints out the integers $n$ in the given segment
+such that $n$ is odd.
+\spadcommand{for n in 0..4 | odd? n repeat output n}
+\begin{verbatim}
+   1
+   3
+\end{verbatim}
+\returnType{Type: Void}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+A {\tt for} loop can also be written
+$$
+{\rm for} {\it \ iterator\ } | {\it \ predicate\ } 
+{\rm repeat} {\it \ loopBody\ }
+$$
+
+which is equivalent to:
+$$
+{\rm for} {\it \ iterator\ } {\rm repeat\ if}
+{\it \ predicate\ } {\rm then} {\it \ loopBody\ } {\rm else\ }iterate
+$$
+}
+
+The predicate need not refer only to the variable in the {\tt for} clause:
+any variable in an outer scope can be part of the predicate.
+
+In this example, the predicate on the inner {\tt for} loop uses $i$ from
+the outer loop and the $j$ from the {\tt for} \index{iteration!nested}
+clause that it directly modifies.
+\begin{verbatim}
+for i in 1..50 repeat
+  for j in 1..50 | factorial(i+j) < 25 repeat
+    output [i,j]
+ 
+   [1,1]
+   [1,2]
+   [1,3]
+   [2,1]
+   [2,2]
+   [3,1]
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{Parallel Iteration}
+\label{ugLangLoopsPar}
+
+The last example of the previous section 
+\ref{ugLangLoopsForInPred} on page~\pageref{ugLangLoopsForInPred}
+gives an example of {\it nested iteration}: a loop is contained
+\index{iteration!nested} in another loop.  \index{iteration!parallel}
+Sometimes you want to iterate across two lists in parallel, or perhaps
+you want to traverse a list while incrementing a variable.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general syntax of a repeat loop is 
+$$
+iterator_1\  iterator_2\  \ldots\  iterator_N {\rm \ repeat\ } loopBody
+$$
+where each {\it iterator} is either a {\tt for} or a {\tt while} clause.  The
+loop terminates immediately when the end test of any {\it iterator}
+succeeds or when a {\tt break} or {\tt return} expression is evaluated in {\it
+loopBody}.  The value returned by the loop is the unique value of {\tt
+Void}.\\
+}
+
+Here we write a loop to iterate across two lists, computing the sum of
+the pairwise product of elements. Here is the first list.
+\spadcommand{l := [1,3,5,7]}
+$$
+\left[
+1,  3,  5,  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+And the second.
+\spadcommand{m := [100,200]}
+$$
+\left[
+{100},  {200} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The initial value of the sum counter.
+\spadcommand{sum := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+The last two elements of $l$ are not used in the calculation because
+$m$ has two fewer elements than $l$.
+\begin{verbatim}
+for x in l for y in m repeat
+    sum := sum + x*y
+\end{verbatim}
+\returnType{Type: Void}
+
+Display the ``dot product.''
+\spadcommand{sum}
+$$
+700 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Next, we write a loop to compute the sum of the products of the loop
+elements with their positions in the loop.
+\spadcommand{l := [2,3,5,7,11,13,17,19,23,29,31,37]}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+{31},  {37} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The initial sum.
+\spadcommand{sum := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Here looping stops when the list $l$ is exhausted, even though
+the $for i in 0..$ specifies no terminating condition.
+
+\spadcommand{for i in 0.. for x in l repeat sum := i * x}
+\returnType{Type: Void}
+
+Display this weighted sum.
+\spadcommand{sum}
+$$
+407 
+$$
+\returnType{Type: NonNegativeInteger}
+
+When ``{\tt |}'' is used to qualify any of the {\tt for} clauses in a parallel
+iteration, the variables in the predicates can be from an outer scope
+or from a {\tt for} clause in or to the left of a modified clause.
+
+This is correct:
+% output from following is too long to show
+\begin{verbatim}
+for i in 1..10 repeat
+  for j in 200..300 | odd? (i+j) repeat
+    output [i,j]
+\end{verbatim}
+
+This is not correct since the variable $j$ has not been defined
+outside the inner loop.
+\begin{verbatim}
+for i in 1..10 | odd? (i+j) repeat  -- wrong, j not defined
+  for j in 200..300 repeat
+    output [i,j]
+\end{verbatim}
+
+\subsection{Mixing Loop Modifiers}
+\label{ugLangLoopsMix}
+
+This example shows that it is possible to mix several of the
+\index{loop!mixing modifiers} forms of {\tt repeat} modifying clauses on a loop.
+\begin{verbatim}
+for i in 1..10
+    for j in 151..160 | odd? j
+      while i + j < 160 repeat
+        output [i,j]
+ 
+   [1,151]
+   [3,153]
+\end{verbatim}
+\returnType{Type: Void}
+
+Here are useful rules for composing loop expressions:
+\begin{enumerate}
+\item {\tt while} predicates can only refer to variables that
+are global (or in an outer scope)
+or that are defined in {\tt for} clauses to the left of the
+predicate.
+\item A ``such that'' predicate (something following ``{\tt |}'')
+must directly follow a {\tt for} clause and can only refer to
+variables that are global (or in an outer scope)
+or defined in the modified {\tt for} clause
+or any {\tt for} clause to the left.
+\end{enumerate}
+
+\section{Creating Lists and Streams with Iterators}
+\label{ugLangIts}
+
+All of what we did for loops in 
+\ref{ugLangLoops} on page~\pageref{ugLangLoops} \index{iteration}
+can be transformed into expressions that create lists
+\index{list!created by iterator} and streams.  \index{stream!created
+by iterator} The {\tt repeat}, {\tt break} or {\tt iterate} words are not used but
+all the other ideas carry over.  Before we give you the general rule,
+here are some examples which give you the idea.
+
+This creates a simple list of the integers from $1$ to $10$.
+\spadcommand{list := [i for i in 1..10]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Create a stream of the integers greater than or equal to $1$.
+\spadcommand{stream := [i for i in 1..]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10},  \ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+This is a list of the prime integers between $1$ and $10$, inclusive.
+\spadcommand{[i for i in 1..10 | prime? i]}
+$$
+\left[
+2,  3,  5,  7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+This is a stream of the prime integers greater than or equal to $1$.
+\spadcommand{[i for i in 1..   | prime? i]}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+This is a list of the integers between $1$ and $10$, inclusive, whose
+squares are less than $700$.
+\spadcommand{[i for i in 1..10 while i*i < 700]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+This is a stream of the integers greater than or equal to $1$
+whose squares are less than $700$.
+\spadcommand{[i for i in 1..   while i*i < 700]}
+$$
+\left[
+1,  2,  3,  4,  5,  6,  7,  8,  9,  {10},  \ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+Here is the general rule.
+\index{collection}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general syntax of a collection is
+\begin{center}
+{\tt [ {\it collectExpression} $\hbox{\it iterator}_{1}$  
+$\hbox{\it iterator}_{2}$ \ldots $\hbox{\it iterator}_{N}$ ]}
+\end{center}
+
+where each $\hbox{\it iterator}_{i}$ is either a {\tt for} or a {\tt while}
+clause.  The loop terminates immediately when the end test of any
+$\hbox{\it iterator}_{i}$ succeeds or when a {\tt return} expression is
+evaluated in {\it collectExpression}.  The value returned by the
+collection is either a list or a stream of elements, one for each
+iteration of the {\it collectExpression}.\\
+}
+
+Be careful when you use {\tt while} 
+\index{stream!using while @{using {\tt while}}} 
+to create a stream.  By default, Axiom tries to compute and
+display the first ten elements of a stream.  If the {\tt while} condition
+is not satisfied quickly, Axiom can spend a long (possibly infinite)
+time trying to compute \index{stream!number of elements computed} the
+elements.  Use {\tt )set streams calculate} to change the default to
+something else.  \index{set streams calculate} This also affects the
+number of terms computed and displayed for power series.  For the
+purposes of this book, we have used this system command to display
+fewer than ten terms.
+
+Use nested iterators to create lists of \index{iteration!nested} lists
+which can then be given as an argument to {\bf matrix}.
+\spadcommand{matrix [ [x**i+j for i in 1..3] for j in 10..12]}
+$$
+\left[
+\begin{array}{ccc}
+{x+{10}} & {{x \sp 2}+{10}} & {{x \sp 3}+{10}} \\ 
+{x+{11}} & {{x \sp 2}+{11}} & {{x \sp 3}+{11}} \\ 
+{x+{12}} & {{x \sp 2}+{12}} & {{x \sp 3}+{12}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Polynomial Integer}
+
+You can also create lists of streams, streams of lists and streams of
+streams.  Here is a stream of streams.
+\spadcommand{[ [i/j for i in j+1..] for j in 1..]}
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ 2,  3,  4,  5,  6,  7,  8,  9,  {10},  {11},  
+\ldots 
+\right]},
+ {\left[ {3 \over 2},  2,  {5 \over 2},  3,  {7 \over 2},  4,  
+{9 \over 2},  5,  {{11} \over 2},  6,  \ldots 
+\right]},
+\right.
+\\
+\\
+\displaystyle
+ {\left[ {4 \over 3},  {5 \over 3},  2,  {7 \over 3},  {8 \over 3}, 
+ 3,  {{10} \over 3},  {{11} \over 3},  4,  {{13} \over 3},  
+\ldots 
+\right]},
+ {\left[ {5 \over 4},  {3 \over 2},  {7 \over 4},  2,  {9 \over 4}, 
+ {5 \over 2},  {{11} \over 4},  3,  {{13} \over 4},  {7 \over 2}, 
+ \ldots 
+\right]},
+\\
+\\
+\displaystyle
+ {\left[ {6 \over 5},  {7 \over 5},  {8 \over 5},  {9 \over 5},  2, 
+ {{11} \over 5},  {{12} \over 5},  {{13} \over 5},  {{14} \over 5}, 
+ 3,  \ldots 
+\right]},
+ {\left[ {7 \over 6},  {4 \over 3},  {3 \over 2},  {5 \over 3},  
+{{11} \over 6},  2,  {{13} \over 6},  {7 \over 3},  {5 \over 2},  
+{8 \over 3},  \ldots 
+\right]},
+\\
+\\
+\displaystyle
+ {\left[ {8 \over 7},  {9 \over 7},  {{10} \over 7},  {{11} \over 7}, 
+ {{12} \over 7},  {{13} \over 7},  2,  {{15} \over 7},  {{16} \over 
+7},  {{17} \over 7},  \ldots 
+\right]},
+ {\left[ {9 \over 8},  {5 \over 4},  {{11} \over 8},  {3 \over 2},  
+{{13} \over 8},  {7 \over 4},  {{15} \over 8},  2,  {{17} \over 8}, 
+ {9 \over 4},  \ldots 
+\right]},
+\\
+\\
+\displaystyle
+ {\left[ {{10} \over 9},  {{11} \over 9},  {4 \over 3},  {{13} \over 
+9},  {{14} \over 9},  {5 \over 3},  {{16} \over 9},  {{17} \over 9}, 
+ 2,  {{19} \over 9},  \ldots 
+\right]},
+\\
+\\
+\displaystyle
+\left.
+ {\left[ {{11} \over {10}},  {6 \over 5},  {{13} \over {10}},  {7 
+\over 5},  {3 \over 2},  {8 \over 5},  {{17} \over {10}},  {9 \over 
+5},  {{19} \over {10}},  2,  \ldots 
+\right]},
+ \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream Stream Fraction Integer}
+
+You can use parallel iteration across lists and streams to create
+\index{iteration!parallel} new lists.
+\spadcommand{[i/j for i in 3.. by 10 for j in 2..]}
+$$
+\left[
+{3 \over 2},  {{13} \over 3},  {{23} \over 4},  {{33} \over 5},  
+{{43} \over 6},  {{53} \over 7},  {{63} \over 8},  {{73} \over 9},  
+{{83} \over {10}},  {{93} \over {11}},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+Iteration stops if the end of a list or stream is reached.
+\spadcommand{[i**j for i in 1..7 for j in 2.. ]}
+$$
+\left[
+1,  8,  {81},  {1024},  {15625},  {279936},  {5764801} 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+%or a while condition fails.
+%\spadcommand{[i**j for i in 1..  for j in 2.. while i + j < 5 ]}
+%tpdhere
+%   There are no library operations named swhile 
+%      Use HyperDoc Browse or issue
+%                               )what op swhile
+%      to learn if there is any operation containing " swhile " in its 
+%      name.
+% 
+%   Cannot find a definition or applicable library operation named 
+%      swhile with argument type(s) 
+%     (Record(part1: PositiveInteger,part2: PositiveInteger) -> Boolean)
+%     InfiniteTuple Record(part1: PositiveInteger,part2: PositiveInteger)
+%      
+%      Perhaps you should use "@" to indicate the required return type, 
+%      or "$" to specify which version of the function you need.
+
+As with loops, you can combine these modifiers to make very
+complicated conditions.
+\spadcommand{[ [ [i,j] for i in 10..15 | prime? i] for j in 17..22 | j = squareFreePart j]}
+$$
+\left[
+{\left[ {\left[ {11},  {17} 
+\right]},
+ {\left[ {13},  {17} 
+\right]}
+\right]},
+ {\left[ {\left[ {11},  {19} 
+\right]},
+ {\left[ {13},  {19} 
+\right]}
+\right]},
+ {\left[ {\left[ {11},  {21} 
+\right]},
+ {\left[ {13},  {21} 
+\right]}
+\right]},
+ {\left[ {\left[ {11},  {22} 
+\right]},
+ {\left[ {13},  {22} 
+\right]}
+\right]}
+\right]
+$$
+\returnType{Type: List List List PositiveInteger}
+
+See List 
+(section \ref{ListXmpPage} on page~\pageref{ListXmpPage}) and Stream 
+(section \ref{StreamXmpPage} on page~\pageref{StreamXmpPage})
+for more information on creating and
+manipulating lists and streams, respectively.
+
+\section{An Example: Streams of Primes}
+\label{ugLangStreamsPrimes}
+
+We conclude this chapter with an example of the creation and
+manipulation of infinite streams of prime integers.  This might be
+useful for experiments with numbers or other applications where you
+are using sequences of primes over and over again.  As for all
+streams, the stream of primes is only computed as far out as you need.
+Once computed, however, all the primes up to that point are saved for
+future reference.
+
+Two useful operations provided by the Axiom library are
+\spadfunFrom{prime?}{IntegerPrimesPackage} and
+\spadfunFrom{nextPrime}{IntegerPrimesPackage}.  A straight-forward way
+to create a stream of prime numbers is to start with the stream of
+positive integers $[2,..]$ and filter out those that are prime.
+
+Create a stream of primes.
+\spadcommand{primes : Stream Integer := [i for i in 2.. | prime? i]}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+A more elegant way, however, is to use the
+\spadfunFrom{generate}{Stream} operation from {\tt Stream}.  Given an
+initial value $a$ and a function $f$, \spadfunFrom{generate}{Stream}
+constructs the stream $[a, f(a), f(f(a)), ...]$.  This function gives
+you the quickest method of getting the stream of primes.
+
+This is how you use \spadfunFrom{generate}{Stream} to generate an
+infinite stream of primes.
+\spadcommand{primes := generate(nextPrime,2)}
+$$
+\left[
+2,  3,  5,  7,  {11},  {13},  {17},  {19},  {23},  {29},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Once the stream is generated, you might only be interested in primes
+starting at a particular value.
+\spadcommand{smallPrimes := [p for p in primes | p > 1000]}
+$$
+\left[
+{1009},  {1013},  {1019},  {1021},  {1031},  {1033},  {1039},  
+{1049},  {1051},  {1061},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Here are the first 11 primes greater than 1000.
+\spadcommand{[p for p in smallPrimes for i in 1..11]}
+$$
+\left[
+{1009},  {1013},  {1019},  {1021},  {1031},  {1033},  {1039},  
+{1049},  {1051},  {1061},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Here is a stream of primes between 1000 and 1200.
+\spadcommand{[p for p in smallPrimes while p < 1200]}
+$$
+\left[
+{1009},  {1013},  {1019},  {1021},  {1031},  {1033},  {1039},  
+{1049},  {1051},  {1061},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+To get these expanded into a finite stream, you call
+\spadfunFrom{complete}{Stream} on the stream.
+\spadcommand{complete \%}
+$$
+\left[
+{1009},  {1013},  {1019},  {1021},  {1031},  {1033},  {1039},  
+{1049},  {1051},  {1061},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Twin primes are consecutive odd number pairs which are prime.
+Here is the stream of twin primes.
+\spadcommand{twinPrimes := [ [p,p+2] for p in primes | prime?(p + 2)]}
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ 3,  5 \right]},
+{\left[ 5,  7 \right]},
+{\left[ {11},  {13} \right]},
+{\left[ {17},  {19} \right]},
+{\left[ {29},  {31} \right]},
+{\left[ {41},  {43} \right]},
+{\left[ {59},  {61} \right]},
+{\left[ {71},  {73} \right]},
+\right.
+\\
+\\
+\displaystyle
+\left.
+{\left[ {101},  {103} \right]},
+{\left[ {107},  {109} \right]},
+ \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream List Integer}
+
+Since we already have the primes computed we can avoid the call to
+\spadfunFrom{prime?}{IntegerPrimesPackage} by using a double
+iteration.  This time we'll just generate a stream of the first of the
+twin primes.
+\spadcommand{firstOfTwins:= [p for p in primes for q in rest primes | q=p+2]}
+$$
+\left[
+3,  5,  {11},  {17},  {29},  {41},  {59},  {71},  {101},  
+{107},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Let's try to compute the infinite stream of triplet primes, the set of
+primes $p$ such that $[p,p+2,p+4]$ are primes. For example, $[3,5,7]$
+is a triple prime.  We could do this by a triple {\tt for} iteration.  A
+more economical way is to use {\bf firstOfTwins}.  This time however,
+put a semicolon at the end of the line.
+
+Create the stream of firstTriplets.  Put a semicolon at the end so
+that no elements are computed.
+\spadcommand{firstTriplets := [p for p in firstOfTwins for q in rest firstOfTwins | q = p+2];}
+\returnType{Type: Stream Integer}
+
+What happened?  As you know, by default Axiom displays the first ten
+elements of a stream when you first display it.  And, therefore, it
+needs to compute them!  If you want {\it no} elements computed, just
+terminate the expression by a semicolon (``{\tt ;}'').  The semi-colon
+prevents the display of the result of evaluating the expression.
+Since no stream elements are needed for display (or anything else, so
+far), none are computed.
+
+Compute the first triplet prime.
+\spadcommand{firstTriplets.1}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+If you want to compute another, just ask for it.  But wait a second!
+Given three consecutive odd integers, one of them must be divisible by
+$3$. Thus there is only one triplet prime.  But suppose that you did not
+know this and wanted to know what was the tenth triplet prime.
+\begin{verbatim}
+firstTriples.10
+\end{verbatim}
+
+To compute the tenth triplet prime, Axiom first must compute the
+second, the third, and so on.  But since there isn't even a second
+triplet prime, Axiom will compute forever.  Nonetheless, this effort
+can produce a useful result.  After waiting a bit, hit \fbox{\bf Ctrl-c}.
+The system responds as follows.
+\begin{verbatim}
+   >> System error:
+   Console interrupt.
+   You are being returned to the top level of
+   the interpreter.
+\end{verbatim}
+
+If you want to know how many primes have been computed, type:
+\begin{verbatim}
+numberOfComputedEntries primes
+\end{verbatim}
+
+and, for this discussion, let's say that the result is $2045$.
+How big is the $2045$-th prime?
+\spadcommand{primes.2045}
+$$
+17837 
+$$
+\returnType{Type: PositiveInteger}
+
+What you have learned is that there are no triplet primes between 5
+and 17837.  Although this result is well known (some might even say
+trivial), there are many experiments you could make where the result
+is not known.  What you see here is a paradigm for testing of
+hypotheses.  Here our hypothesis could have been: ``there is more than
+one triplet prime.''  We have tested this hypothesis for 17837 cases.
+With streams, you can let your machine run, interrupt it to see how
+far it has progressed, then start it up and let it continue from where
+it left off.
+
+\setcounter{chapter}{5}
+
+\chapter{User-Defined Functions, Macros and Rules}
+\label{ugUser}
+
+In this chapter we show you how to write functions and macros,
+and we explain how Axiom looks for and applies them.
+We show some simple one-line examples of functions, together
+with larger ones that are defined piece-by-piece or through the use of
+piles.
+
+\section{Functions vs. Macros}
+\label{ugUserFunMac}
+
+A function is a program to perform some \index{function!vs. macro}
+computation.  \index{macro!vs. function} Most functions have names so
+that it is easy to refer to them.  A simple example of a function is
+one named \spadfunFrom{abs}{Integer} which computes the absolute value
+of an integer.
+
+This is a use of the ``absolute value'' library function for integers.
+\spadcommand{abs(-8)}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+This is an unnamed function that does the same thing, using the
+``maps-to'' syntax {\tt +->} that we discuss in 
+section \ref{ugUserAnon} on page~\pageref{ugUserAnon}.
+\spadcommand{(x +-> if x < 0 then -x else x)(-8)}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+Functions can be used alone or serve as the building blocks for larger
+programs.  Usually they return a value that you might want to use in
+the next stage of a computation, but not always (for example, see
+\ref{ExitXmpPage} on page~\pageref{ExitXmpPage} and \ref{VoidXmpPage}
+on page~\pageref{VoidXmpPage}).  They may also read data from your
+keyboard, move information from one place to another, or format and
+display results on your screen.
+
+In Axiom, as in mathematics, functions \index{function!parameters} are
+usually parameterized.  Each time you {\it call} (some people say {\it
+apply} or invoke) a function, you give \index{parameters to a
+function} values to the parameters (variables).  Such a value is
+called an {\it argument} of \index{function!arguments} the function.
+Axiom uses the arguments for the computation.  In this way you get
+different results depending on what you ``feed'' the function.
+
+Functions can have local variables or refer to global variables in the
+workspace.  Axiom can often compile functions so that they execute
+very efficiently.  Functions can be passed as arguments to other
+functions.
+
+Macros are textual substitutions.  They are used to clarify the
+meaning of constants or expressions and to be templates for frequently
+used expressions.  Macros can be parameterized but they are not
+objects that can be passed as arguments to functions.  In effect,
+macros are extensions to the Axiom expression parser.
+
+\section{Macros}
+\label{ugUserMacros}
+
+A {\it macro} provides general textual substitution of \index{macro}
+an Axiom expression for a name.  You can think of a macro as being a
+generalized abbreviation.  You can only have one macro in your
+workspace with a given name, no matter how many arguments it has.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The two general forms for macros are
+\begin{center}
+{\tt macro} {\it name} {\tt ==} {\it body} \\
+{\tt macro} {\it name(arg1,...)} {\tt ==} {\it body}
+\end{center}
+where the body of the macro can be any Axiom expression.\\
+}
+
+For example, suppose you decided that you like to use {\tt df} for 
+{\tt D}.  You define the macro {\tt df} like this.
+\spadcommand{macro df == D}
+\returnType{Type: Void}
+
+Whenever you type {\tt df}, the system expands it to {\tt D}.
+\spadcommand{df(x**2 + x + 1,x)}
+$$
+{2 \  x}+1 
+$$
+\returnType{Type: Polynomial Integer}
+
+Macros can be parameterized and so can be used for many different
+kinds of objects.
+\spadcommand{macro ff(x) == x**2 + 1}
+\returnType{Type: Void}
+
+Apply it to a number, a symbol, or an expression.
+\spadcommand{ff z}
+$$
+{z \sp 2}+1 
+$$
+\returnType{Type: Polynomial Integer}
+
+Macros can also be nested, but you get an error message if you
+run out of space because of an infinite nesting loop.
+\spadcommand{macro gg(x) == ff(2*x - 2/3)}
+\returnType{Type: Void}
+
+This new macro is fine as it does not produce a loop.
+\spadcommand{gg(1/w)}
+$$
+{{{13} \  {w \sp 2}} -{{24} \  w}+{36}} \over {9 \  {w \sp 2}} 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+This, however, loops since {\tt gg} is defined in terms of {\tt ff}.
+\spadcommand{macro ff(x) == gg(-x)}
+\returnType{Type: Void}
+
+The body of a macro can be a block.
+\spadcommand{macro next == (past := present; present := future; future := past + present)}
+\returnType{Type: Void}
+
+Before entering {\tt next}, we need values for {\tt present} and {\tt future}.
+\spadcommand{present : Integer := 0}
+$$
+0 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{future : Integer := 1}
+$$
+1 
+$$
+\returnType{Type: Integer}
+
+Repeatedly evaluating {\tt next} produces the next Fibonacci number.
+\spadcommand{next}
+$$
+1 
+$$
+\returnType{Type: Integer}
+
+And the next one.
+\spadcommand{next}
+$$
+2 
+$$
+\returnType{Type: Integer}
+
+Here is the infinite stream of the rest of the Fibonacci numbers.
+\spadcommand{[next for i in 1..]}
+$$
+\left[
+3,  5,  8,  {13},  {21},  {34},  {55},  {89},  {144},  
+{233},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Bundle all the above lines into a single macro.
+\begin{verbatim}
+macro fibStream ==
+  present : Integer := 1
+  future : Integer := 1
+  [next for i in 1..] where
+    macro next ==
+      past := present
+      present := future
+      future := past + present
+\end{verbatim}
+\returnType{Type: Void}
+
+Use \spadfunFrom{concat}{Stream} to start with the first two
+\index{Fibonacci numbers} Fibonacci numbers.
+\spadcommand{concat([0,1],fibStream)}
+$$
+\left[
+0, 1, 2, 3, 5, 8, {13}, {21}, {34}, {55}, 
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+The library operation {\bf fibonacci} is an easier way to compute
+these numbers.
+
+\spadcommand{[fibonacci i for i in 1..]}
+$$
+\left[
+1,  1,  2,  3,  5,  8,  {13},  {21},  {34},  {55},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+\section{Introduction to Functions}
+\label{ugUserIntro}
+
+Each name in your workspace can refer to a single object.  This may be
+any kind of object including a function.  You can use interactively
+any function from the library or any that you define in the workspace.
+In the library the same name can have very many functions, but you can
+have only one function with a given name, although it can have any
+number of arguments that you choose.
+
+If you define a function in the workspace that has the same name and
+number of arguments as one in the library, then your definition takes
+precedence.  In fact, to get the library function you must
+{\sl package-call} it 
+(see section \ref{ugTypesPkgCall} on page~\pageref{ugTypesPkgCall}).
+
+To use a function in Axiom, you apply it to its arguments.  Most
+functions are applied by entering the name of the function followed by
+its argument or arguments.
+\spadcommand{factor(12)}
+$$
+{2 \sp 2} \  3 
+$$
+\returnType{Type: Factored Integer}
+
+Some functions like ``{\tt +}'' have {\it infix} {\it operators} as names.
+\spadcommand{3 + 4}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+The function ``{\tt +}'' has two arguments.  When you give it more than
+two arguments, Axiom groups the arguments to the left.  This
+expression is equivalent to $(1 + 2) + 7$.
+\spadcommand{1 + 2 + 7}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+All operations, including infix operators, can be written in prefix
+form, that is, with the operation name followed by the arguments in
+parentheses.  For example, $2 + 3$ can alternatively be written as
+$+(2,3)$.  But $+(2,3,4)$ is an error since {\tt +} takes only two
+arguments.
+
+Prefix operations are generally applied before the infix operation.
+Thus the form ${\bf factorial\ } 3 + 1$ means ${\bf factorial}(3) + 1$
+producing $7$, and $-2 + 5$ means $(-2) + 5$ producing $3$.  An
+example of a prefix operator is prefix ``{\tt -}''.  For example, $- 2 +
+5$ converts to $(- 2) + 5$ producing the value $3$.  Any prefix
+function taking two arguments can be written in an infix manner by
+putting an ampersand ``{\tt \&}'' before the name.  Thus ${\tt D}(2*x,x)$ can
+be written as $2*x\ {\tt \&D} x$ returning $2$.
+
+Every function in Axiom is identified by a {\it name} and 
+{\it type}. (An exception is an ``anonymous function'' discussed in
+\ref{ugUserAnon} on page~\pageref{ugUserAnon}.)  
+The type of a function is always a mapping of the
+form \spadsig{Source}{Target} where {\tt Source} and {\tt Target} are types.
+To enter a type from the keyboard, enter the arrow by using a hyphen
+``{\tt -}'' followed by a greater-than sign ``{\tt >}'', e.g. 
+{\tt Integer -> Integer}.
+
+Let's go back to ``{\tt +}''.  There are many ``{\tt +}'' functions in the
+Axiom library: one for integers, one for floats, another for rational
+numbers, and so on.  These ``{\tt +}'' functions have different types and
+thus are different functions.  You've seen examples of this 
+{\it overloading} before---using the same name for different functions.
+Overloading is the rule rather than the exception.  You can add two
+integers, two polynomials, two matrices or two power series.  These
+are all done with the same function name but with different functions.
+
+\section{Declaring the Type of Functions}
+\label{ugUserDeclare}
+
+In \ref{ugTypesDeclare} on page~\pageref{ugTypesDeclare} we discussed
+how to declare a variable to restrict the kind of values that can be
+assigned to it.  In this section we show how to declare a variable
+that refers to function objects.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+A function is an object of type
+\begin{center}
+{\sf Source $\rightarrow$ Type}
+\end{center}
+
+where {\tt Source} and {\tt Target} can be any type.  A common type
+for {\tt Source} is {\tt Tuple}($\hbox{\it T}_{1}$, \ldots, 
+$\hbox{\it T}_{n}$), usually written ($\hbox{\it T}_{1}$, \ldots, 
+$\hbox{\it T}_{n}$), to indicate a function of $n$ arguments.\\
+}
+
+If $g$ takes an {\tt Integer}, a {\tt Float} and another {\tt Integer}, 
+and returns a {\tt String}, the declaration is written:
+\spadcommand{g: (Integer,Float,Integer) -> String}
+\returnType{Type: Void}
+
+The types need not be written fully; using abbreviations, the above
+declaration is:
+\spadcommand{g: (INT,FLOAT,INT) -> STRING}
+\returnType{Type: Void}
+
+It is possible for a function to take no arguments.  If $ h$ takes no
+arguments but returns a {\tt Polynomial} {\tt Integer}, any of the
+following declarations is acceptable.
+\spadcommand{h: () -> POLY INT}
+\returnType{Type: Void}
+
+\spadcommand{h: () -> Polynomial INT}
+\returnType{Type: Void}
+
+\spadcommand{h: () -> POLY Integer}
+\returnType{Type: Void}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Functions can also be declared when they are being defined.
+The syntax for combined declaration/definition is:
+\begin{center}
+\frenchspacing{\tt {\it functionName}($\hbox{\it parm}_{1}$: 
+$\hbox{\it parmType}_{1}$, \ldots, $\hbox{\it parm}_{N}$: 
+$\hbox{\it parmType}_{N}$): {\it functionReturnType}}
+\end{center}
+{\ }%force a blank line 
+}
+
+The following definition fragments show how this can be done for
+the functions $g$ and $h$ above.
+\begin{verbatim}
+g(arg1: INT, arg2: FLOAT, arg3: INT): STRING == ...
+
+h(): POLY INT == ...
+\end{verbatim}
+
+A current restriction on function declarations is that they must
+involve fully specified types (that is, cannot include modes involving
+explicit or implicit ``{\tt ?}'').  For more information on declaring
+things in general, see \ref{ugTypesDeclare} on page~\pageref{ugTypesDeclare}.
+
+\section{One-Line Functions}
+\label{ugUserOne}
+
+As you use Axiom, you will find that you will write many short
+functions \index{function!one-line definition} to codify sequences of
+operations that you often perform.  In this section we write some
+simple one-line functions.
+
+This is a simple recursive factorial function for positive integers.
+\spadcommand{fac n == if n < 3 then n else n * fac(n-1)}
+\returnType{Type: Void}
+
+\spadcommand{fac 10}
+$$
+3628800 
+$$
+\returnType{Type: PositiveInteger}
+
+This function computes $1 + 1/2 + 1/3 + ... + 1/n$.
+\spadcommand{s n == reduce(+,[1/i for i in 1..n])}
+\returnType{Type: Void}
+
+\spadcommand{s 50}
+$$
+{13943237577224054960759} \over {3099044504245996706400} 
+$$
+\returnType{Type: Fraction Integer}
+
+This function computes a Mersenne number, several of which are prime.
+\index{Mersenne number}
+\spadcommand{mersenne i == 2**i - 1}
+\returnType{Type: Void}
+
+If you type {\tt mersenne}, Axiom shows you the function definition.
+\spadcommand{mersenne}
+$$
+mersenne \  i \  == \  {{2 \sp i} -1} 
+$$
+\returnType{Type: FunctionCalled mersenne}
+
+Generate a stream of Mersenne numbers.
+\spadcommand{[mersenne i for i in 1..]}
+$$
+\left[
+1,  3,  7,  {15},  {31},  {63},  {127},  {255},  {511},  
+{1023},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Create a stream of those values of $i$ such that {\tt mersenne(i)} is prime.
+\spadcommand{mersenneIndex := [n for n in 1.. | prime?(mersenne(n))]}
+\begin{verbatim}
+   Compiling function mersenne with type PositiveInteger -> Integer 
+\end{verbatim}
+$$
+\left[
+2,  3,  5,  7,  {13},  {17},  {19},  {31},  {61},  {89},  
+\ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+Finally, write a function that returns the $n$-th Mersenne prime.
+\spadcommand{mersennePrime n == mersenne mersenneIndex(n)}
+\returnType{Type: Void}
+
+\spadcommand{mersennePrime 5}
+$$
+8191 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{Declared vs. Undeclared Functions}
+\label{ugUserDecUndec}
+
+If you declare the type of a function, you can apply it to any data
+that can be converted to the source type of the function.
+
+Define {\bf f} with type {\sf Integer $\rightarrow$ Integer}.
+\spadcommand{f(x: Integer): Integer == x + 1}
+\begin{verbatim}
+   Function declaration f : Integer -> Integer has been added to 
+      workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+The function {\bf f} can be applied to integers, \ldots
+\spadcommand{f 9}
+\begin{verbatim}
+   Compiling function f with type Integer -> Integer 
+\end{verbatim}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+and to values that convert to integers, \ldots
+\spadcommand{f(-2.0)}
+$$
+-1 
+$$
+\returnType{Type: Integer}
+
+but not to values that cannot be converted to integers.
+\spadcommand{f(2/3)}
+\begin{verbatim}
+   Conversion failed in the compiled user function f .
+ 
+   Cannot convert from type Fraction Integer to Integer for value
+   2
+   -
+   3
+\end{verbatim}
+
+To make the function over a wide range of types, do not declare its type.
+Give the same definition with no declaration.
+\spadcommand{g x == x + 1}
+\returnType{Type: Void}
+
+If $x + 1$ makes sense, you can apply {\bf g} to $x$.
+\spadcommand{g 9}
+\begin{verbatim}
+   Compiling function g with type PositiveInteger -> PositiveInteger 
+\end{verbatim}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+A version of {\bf g} with different argument types get compiled for
+each new kind of argument used.
+\spadcommand{g(2/3)}
+\begin{verbatim}
+   Compiling function g with type Fraction Integer -> Fraction Integer 
+\end{verbatim}
+$$
+5 \over 3 
+$$
+\returnType{Type: Fraction Integer}
+
+Here $x+1$ for $x = "axiom"$ makes no sense.
+\spadcommand{g("axiom")}
+\begin{verbatim}
+   There are 11 exposed and 5 unexposed library operations named + 
+      having 2 argument(s) but none was determined to be applicable. 
+      Use HyperDoc Browse, or issue
+                                )display op +
+      to learn more about the available operations. Perhaps 
+      package-calling the operation or using coercions on the arguments
+      will allow you to apply the operation.
+   Cannot find a definition or applicable library operation named + 
+      with argument type(s) 
+                                   String
+                               PositiveInteger
+      
+      Perhaps you should use "@" to indicate the required return type, 
+      or "$" to specify which version of the function you need.
+   AXIOM will attempt to step through and interpret the code.
+   There are 11 exposed and 5 unexposed library operations named + 
+      having 2 argument(s) but none was determined to be applicable. 
+      Use HyperDoc Browse, or issue
+                                )display op +
+      to learn more about the available operations. Perhaps 
+      package-calling the operation or using coercions on the arguments
+      will allow you to apply the operation.
+ 
+   Cannot find a definition or applicable library operation named + 
+      with argument type(s) 
+                                   String
+                               PositiveInteger
+      
+      Perhaps you should use "@" to indicate the required return type, 
+      or "$" to specify which version of the function you need.
+\end{verbatim}
+
+As you will see in Chapter \ref{ugCategories} on
+page~\pageref{ugCategories}, Axiom has a formal idea of categories for
+what ``makes sense.''
+
+\section{Functions vs. Operations}
+\label{ugUserDecOpers}
+
+A function is an object that you can create, manipulate, pass to, and
+return from functions (for some interesting examples of library
+functions that manipulate functions, see \ref{MappingPackage1XmpPage}
+on page~\pageref{MappingPackage1XmpPage}).  Yet, we often seem to use
+the term {\it operation} and {\it function} interchangeably in Axiom.  What
+is the distinction?
+
+First consider values and types associated with some variable $n$ in
+your workspace.  You can make the declaration {\tt n : Integer}, then
+assign $n$ an integer value.  You then speak of the integer $n$.
+However, note that the integer is not the name $n$ itself, but the
+value that you assign to $n$.
+
+Similarly, you can declare a variable $f$ in your workspace to have
+type {\sf Integer $\rightarrow$ Integer}, then assign $f$, through a
+definition or an assignment of an anonymous function.  You then speak
+of the function $f$.  However, the function is not $f$, but the value
+that you assign to $f$.
+
+A function is a value, in fact, some machine code for doing something.
+Doing what?  Well, performing some {\it operation}.  Formally, an
+operation consists of the constituent parts of $f$ in your workspace,
+excluding the value; thus an operation has a name and a type.  An
+operation is what domains and packages export.  Thus {\tt Ring}
+exports one operation ``{\tt +}''.  Every ring also exports this
+operation.  Also, the author of every ring in the system is obliged
+under contract (see \ref{ugPackagesAbstract} on
+page~\pageref{ugPackagesAbstract}) to provide an implementation for
+this operation.
+
+This chapter is all about functions---how you create them
+interactively and how you apply them to meet your needs.  In Chapter
+\ref{ugPackages} on page~\pageref{ugPackages} you will learn how to
+create them for the Axiom library.  Then in Chapter \ref{ugCategories}
+on page~\pageref{ugCategories}, you will learn about categories and
+exported operations.
+
+\section{Delayed Assignments vs. Functions with No Arguments}
+\label{ugUserDelay}
+
+In \ref{ugLangAssign} on page~\pageref{ugLangAssign} we discussed the
+difference between immediate and \index{function!with no arguments}
+delayed assignments.  In this section we show the difference between
+delayed assignments and functions of no arguments.
+
+A function of no arguments is sometimes called a {\it nullary function.}
+\spadcommand{sin24() == sin(24.0)}
+\returnType{Type: Void}
+
+You must use the parentheses ``{\tt ()}'' to evaluate it.  Like a
+delayed assignment, the right-hand-side of a function evaluation is
+not evaluated until the left-hand-side is used.
+\spadcommand{sin24()}
+\begin{verbatim}
+   Compiling function sin24 with type () -> Float 
+\end{verbatim}
+$$
+-{0.9055783620\ 0662384514} 
+$$
+\returnType{Type: Float}
+
+If you omit the parentheses, you just get the function definition.
+\spadcommand{sin24}
+$$
+sin24 \  {\left( 
+\right)}
+\  == \  {\sin 
+\left(
+{{24.0}} 
+\right)}
+$$
+\returnType{Type: FunctionCalled sin24}
+
+You do not use the parentheses ``{\tt ()}'' in a delayed assignment\ldots
+
+\spadcommand{cos24 == cos(24.0)}
+\returnType{Type: Void}
+
+nor in the evaluation.
+
+\spadcommand{cos24}
+\begin{verbatim}
+   Compiling body of rule cos24 to compute value of type Float 
+\end{verbatim}
+$$
+0.4241790073\ 3699697594 
+$$
+\returnType{Type: Float}
+
+The only syntactic difference between delayed assignments
+and nullary functions is that you use ``{\tt ()}'' in the latter case.
+
+\section{How Axiom Determines What Function to Use}
+\label{ugUserUse}
+
+What happens if you define a function that has the same name as a
+library function?  Well, if your function has the same name and number
+of arguments (we sometimes say {\it arity}) as another function in the
+library, then your function covers up the library function.  If you
+want then to call the library function, you will have to {\sl package-call}
+it.  Axiom can use both the functions you write and those that come
+from the library.  Let's do a simple example to illustrate this.
+
+Suppose you (wrongly!) define {\bf sin} in this way.
+\spadcommand{sin x == 1.0}
+\returnType{Type: Void}
+
+The value $1.0$ is returned for any argument.
+\spadcommand{sin 4.3}
+\begin{verbatim}
+   Compiling function sin with type Float -> Float 
+\end{verbatim}
+$$
+1.0 
+$$
+\returnType{Type: Float}
+
+If you want the library operation, we have to package-call it
+(see \ref{ugTypesPkgCall} on page~\pageref{ugTypesPkgCall}
+for more information).
+\spadcommand{sin(4.3)\$Float}
+$$
+-{0.9161659367 4945498404} 
+$$
+\returnType{Type: Float}
+
+\spadcommand{sin(34.6)\$Float}
+$$
+-{0.0424680347 1695010154 3} 
+$$
+\returnType{Type: Float}
+
+Even worse, say we accidentally used the same name as a library
+function in the function.
+\spadcommand{sin x == sin x}
+\begin{verbatim}
+   Compiled code for sin has been cleared.
+   1 old definition(s) deleted for function or rule sin 
+\end{verbatim}
+\returnType{Type: Void}
+
+Then Axiom definitely does not understand us.
+\spadcommand{sin 4.3}
+\begin{verbatim}
+AXIOM cannot determine the type of sin because it cannot analyze 
+   the non-recursive part, if that exists. This may be remedied 
+   by declaring the function.
+\end{verbatim}
+
+Again, we could package-call the inside function.
+\spadcommand{sin x == sin(x)\$Float}
+\begin{verbatim}
+   1 old definition(s) deleted for function or rule sin 
+\end{verbatim}
+\returnType{Type: Void}
+
+\spadcommand{sin 4.3}
+\begin{verbatim}
+   Compiling function sin with type Float -> Float 
+
++++ |*1;sin;1;G82322| redefined
+\end{verbatim}
+$$
+-{0.9161659367 4945498404} 
+$$
+\returnType{Type: Float}
+
+Of course, you are unlikely to make such obvious errors.  It is more
+probable that you would write a function and in the body use a
+function that you think is a library function.  If you had also
+written a function by that same name, the library function would be
+invisible.
+
+How does Axiom determine what library function to call?  It very much
+depends on the particular example, but the simple case of creating the
+polynomial $x + 2/3$ will give you an idea.
+\begin{enumerate}
+\item The $x$ is analyzed and its default type is
+{\tt Variable(x)}.
+\item The $2$ is analyzed and its default type is
+{\tt PositiveInteger}.
+\item The $3$ is analyzed and its default type is
+{\tt PositiveInteger}.
+\item Because the arguments to ``{\tt /}'' are integers, Axiom
+gives the expression $2/3$ a default target type of
+{\tt Fraction(Integer)}.
+\item Axiom looks in {\tt PositiveInteger} for ``{\tt /}''.
+It is not found.
+\item Axiom looks in {\tt Fraction(Integer)} for ``{\tt /}''.
+It is found for arguments of type {\tt Integer}.
+\item The $2$ and $3$ are converted to objects of type
+{\tt Integer} (this is trivial) and ``{\tt /}'' is applied,
+creating an object of type {\tt Fraction(Integer)}.
+\item No ``{\tt +}'' for arguments of types {\tt Variable(x)} and
+{\tt Fraction(Integer)} are found in either domain.
+\item Axiom resolves
+\index{resolve}
+(see \ref{ugTypesResolve} on page~\pageref{ugTypesResolve})
+the types and gets {\tt Polynomial (Fraction (Integer))}.
+\item The $x$ and the $2/3$ are converted to objects of this
+type and {\tt +} is applied, yielding the answer, an object of type
+{\tt Polynomial (Fraction (Integer))}.
+\end{enumerate}
+
+\section{Compiling vs. Interpreting}
+\label{ugUserCompInt}
+
+When possible, Axiom completely determines the type of every object in
+a function, then translates the function definition to Common Lisp or
+to machine code (see the next section).  This translation,
+\index{function!compiler} called compilation, happens the first time
+you call the function and results in a computational delay.
+Subsequent function calls with the same argument types use the
+compiled version of the code without delay.
+
+If Axiom cannot determine the type of everything, the function may
+still be executed \index{function!interpretation} but
+\index{interpret-code mode} in interpret-code mode: each statement in
+the function is analyzed and executed as the control flow indicates.
+This process is slower than executing a compiled function, but it
+allows the execution of code that may involve objects whose types
+change.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+If Axiom decides that it cannot compile the code, it issues a message
+stating the problem and then the following message:
+\begin{center}
+{\bf We will attempt to step through and interpret the code.}
+\end{center}
+
+This is not a time to panic.  \index{panic!avoiding} Rather, it just
+means that what you gave to Axiom is somehow ambiguous: either it is
+not specific enough to be analyzed completely, or it is beyond Axiom's
+present interactive compilation abilities.\\
+}
+
+This function runs in interpret-code mode, but it does not compile.
+\begin{verbatim}
+varPolys(vars) ==
+  for var in vars repeat
+    output(1 :: UnivariatePolynomial(var,Integer))
+\end{verbatim}
+\returnType{Type: Void}
+
+For $vars$ equal to $['x, 'y, 'z]$, this function displays $1$ three times.
+\spadcommand{varPolys ['x,'y,'z]}
+\begin{verbatim}
+Cannot compile conversion for types involving local variables. 
+   In particular, could not compile the expression involving :: 
+   UnivariatePolynomial(var,Integer) 
+ AXIOM will attempt to step through and interpret the code.
+ 1
+ 1
+ 1
+\end{verbatim}
+\returnType{Type: Void}
+
+The type of the argument to {\bf output} changes in each iteration, so
+Axiom cannot compile the function.  In this case, even the inner loop
+by itself would have a problem:
+\begin{verbatim}
+for var in ['x,'y,'z] repeat
+  output(1 :: UnivariatePolynomial(var,Integer))
+\end{verbatim}
+\begin{verbatim}
+Cannot compile conversion for types involving local variables. 
+   In particular, could not compile the expression involving :: 
+   UnivariatePolynomial(var,Integer) 
+ AXIOM will attempt to step through and interpret the code.
+ 1
+ 1
+ 1
+\end{verbatim}
+\returnType{Type: Void}
+
+Sometimes you can help a function to compile by using an extra
+conversion or by using $pretend$.  \index{pretend} See
+\ref{ugTypesSubdomains} on page~\pageref{ugTypesSubdomains} for details.
+
+When a function is compilable, you have the choice of whether it is
+compiled to Common Lisp and then interpreted by the Common Lisp
+interpreter or then further compiled from Common Lisp to machine code.
+\index{machine code} The option is controlled via 
+{\tt )set functions compile}.  
+\index{set function compile} Issue {\tt )set functions compile on} 
+to compile all the way to machine code.  With the default
+setting {\tt )set functions compile off}, Axiom has its Common Lisp
+code interpreted because the overhead of further compilation is larger
+than the run-time of most of the functions our users have defined.
+You may find that selectively turning this option on and off will
+\index{performance} give you the best performance in your particular
+application.  For example, if you are writing functions for graphics
+applications where hundreds of points are being computed, it is almost
+certainly true that you will get the best performance by issuing 
+{\tt )set functions compile on}.
+
+\section{Piece-Wise Function Definitions}
+\label{ugUserPiece}
+
+To move beyond functions defined in one line, we introduce in this
+section functions that are defined piece-by-piece.  That is, we say
+``use this definition when the argument is such-and-such and use this
+other definition when the argument is that-and-that.''
+
+\subsection{A Basic Example}
+\label{ugUserPieceBasic}
+
+There are many other ways to define a factorial function for
+nonnegative integers.  You might 
+\index{function!piece-wise definition} 
+say \index{piece-wise function definition} factorial of
+$0$ is $1$, otherwise factorial of $n$ is $n$ times factorial of
+$n-1$.  Here is one way to do this in Axiom.
+
+Here is the value for $n = 0$.
+\spadcommand{fact(0) == 1}
+\returnType{Type: Void}
+
+Here is the value for $n > 0$.  The vertical bar ``{\tt |}'' means ``such
+that''. \index{such that}
+\spadcommand{fact(n | n > 0) == n * fact(n - 1)}
+\returnType{Type: Void}
+
+What is the value for $n = 3$?
+\spadcommand{fact(3)}
+\begin{verbatim}
+   Compiling function fact with type Integer -> Integer 
+   Compiling function fact as a recurrence relation.
+\end{verbatim}
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+What is the value for $n = -3$?
+\spadcommand{fact(-3)}
+\begin{verbatim}
+   You did not define fact for argument -3 .
+\end{verbatim}
+
+Now for a second definition.  Here is the value for $n = 0$.
+\spadcommand{facto(0) == 1}
+\returnType{Type: Void}
+
+Give an error message if $n < 0$.
+\spadcommand{facto(n | n < 0) == error "arguments to facto must be non-negative"}
+\returnType{Type: Void}
+
+Here is the value otherwise.
+\spadcommand{facto(n) == n * facto(n - 1)}
+\returnType{Type: Void}
+
+What is the value for $n = 7$?
+\spadcommand{facto(3)}
+\begin{verbatim}
+   Compiling function facto with type Integer -> Integer 
+\end{verbatim}
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+What is the value for $n = -7$?
+\spadcommand{facto(-7)}
+\begin{verbatim}
+   Error signalled from user code in function facto: 
+      arguments to facto must be non-negative
+\end{verbatim}
+\returnType{Type: PositiveInteger}
+
+To see the current piece-wise definition of a function, use 
+{\tt )display value}.
+\spadcommand{)display value facto}
+\begin{verbatim}
+   Definition:
+     facto 0 == 1
+     facto (n | n < 0) == 
+       error(arguments to facto must be non-negative)
+     facto n == n facto(n - 1)
+\end{verbatim}
+
+In general a {\it piece-wise definition} of a function consists of two
+or more parts.  Each part gives a ``piece'' of the entire definition.
+Axiom collects the pieces of a function as you enter them.  When you
+ask for a value of the function, it then ``glues'' the pieces together
+to form a function.
+
+The two piece-wise definitions for the factorial function are examples
+of recursive functions, that is, functions that are defined in terms
+of themselves.  Here is an interesting doubly-recursive function.
+This function returns the value $11$ for all positive integer
+arguments.
+
+Here is the first of two pieces.
+\spadcommand{eleven(n | n < 1) == n + 11}
+\returnType{Type: Void}
+
+And the general case.
+\spadcommand{eleven(m) == eleven(eleven(m - 12))}
+\returnType{Type: Void}
+
+Compute $elevens$, the infinite stream of values of $eleven$.
+\spadcommand{elevens := [eleven(i) for i in 0..]}
+$$
+\left[
+{11},  {11},  {11},  {11},  {11},  {11},  {11},  {11},  {11}, 
+ {11},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+What is the value at $n = 200$?
+\spadcommand{elevens 200}
+$$
+11 
+$$
+\returnType{Type: PositiveInteger}
+
+What is the Axiom's definition of $eleven$?
+\spadcommand{)display value eleven}
+\begin{verbatim}
+   Definition:
+     eleven (m | m < 1) == m + 11
+     eleven m == eleven(eleven(m - 12))
+\end{verbatim}
+
+\subsection{Picking Up the Pieces}
+\label{ugUserPiecePicking}
+
+Here are the details about how Axiom creates a function from its
+pieces.  Axiom converts the $i$-th piece of a function definition
+into a conditional expression of the form: 
+{\tt if} $\hbox{\it pred}_{i}$ {\tt then} $\hbox{\it expression}_{i}$.  
+If any new piece has a $\hbox{\it pred}_{i}$ that is 
+identical (after all variables are uniformly named) to 
+an earlier $\hbox{\it pred}_{j}$, the earlier piece is removed.  
+Otherwise, the new piece is always added at the end.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+If there are $n$ pieces to a function definition for $f$, the function
+defined $f$ is: \newline
+\hspace*{3pc}
+{\tt if} $\hbox{\it pred}_{1}$ {\tt then} $\hbox{\it expression}_{1}$ {\tt else}\newline
+\hspace*{6pc}. . . \newline
+\hspace*{3pc}
+{\tt if} $\hbox{\it pred}_{n}$ {\tt then} $\hbox{\it expression}_{n}$ {\tt else}\newline
+\hspace*{3pc}
+{\tt  error "You did not define f for argument <arg>."}\\
+}
+
+You can give definitions of any number of mutually recursive function
+definitions, piece-wise or otherwise.  No computation is done until
+you ask for a value.  When you do ask for a value, all the relevant
+definitions are gathered, analyzed, and translated into separate
+functions and compiled.
+
+Let's recall the definition of {\bf eleven} from
+the previous section. 
+\spadcommand{eleven(n | n < 1) == n + 11}
+\returnType{Type: Void}
+
+\spadcommand{eleven(m) == eleven(eleven(m - 12))}
+\returnType{Type: Void}
+
+A similar doubly-recursive function below produces $-11$ for all
+negative positive integers.  If you haven't worked out why or how 
+{\bf eleven} works, the structure of this definition gives a clue.
+
+This definition we write as a block.
+\begin{verbatim}
+minusEleven(n) ==
+  n >= 0 => n - 11
+  minusEleven (5 + minusEleven(n + 7))
+\end{verbatim}
+\returnType{Type: Void}
+
+Define $s(n)$ to be the sum of plus and minus ``eleven'' functions
+divided by $n$.  Since $11 - 11 = 0$, we define $s(0)$ to be $1$.
+\spadcommand{s(0) == 1}
+\returnType{Type: Void}
+
+And the general term.
+\spadcommand{s(n) == (eleven(n) + minusEleven(n))/n}
+\returnType{Type: Void}
+
+What are the first ten values of $s$?
+\spadcommand{[s(n) for n in 0..]}
+$$
+\left[
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+%% interpreter puts the rule at the end - should fix
+
+% Oops! Evidently $s(0)$ should be $1$.
+% Let's check the current definition of {\bf s} using {\tt )display}.
+
+% \spadcommand{)display value s}
+
+% Change the value at $n = 0$.
+
+% \spadcommand{s(0) == 1}
+
+% Now, what is the definition of {\bf s}?
+% Note: {\it you can only replace a given piece if you give exactly the same
+% predicate!}
+
+% \spadcommand{)display value s}
+
+Axiom can create infinite streams in the positive direction (for
+example, for index values $0,1, \ldots$) or negative direction (for
+example, for $0,-1,-2, \ldots$).  Here we would like a
+stream of values of $s(n)$ that is infinite in both directions.  The
+function $t(n)$ below returns the $n$-th term of the infinite stream 
+$$[s(0), s(1), s(-1), s(2), s(-2), \ldots]$$ 
+Its definition has three pieces.
+
+Define the initial term.
+\spadcommand{t(1) == s(0)}
+\returnType{Type: Void}
+
+The even numbered terms are the $s(i)$ for positive $i$.  We use
+``{\tt quo}'' rather than ``{\tt /}'' since we want the result to be
+an integer.
+
+\spadcommand{t(n | even?(n)) == s(n quo 2)}
+\returnType{Type: Void}
+
+Finally, the odd numbered terms are the $s(i)$ for negative $i$.  In
+piece-wise definitions, you can use different variables to define
+different pieces. Axiom will not get confused.
+\spadcommand{t(p) == s(- p quo 2)}
+\returnType{Type: Void}
+
+Look at the definition of $t$.  In the first piece, the variable $n$
+was used; in the second piece, $p$.  Axiom always uses your last
+variable to display your definitions back to you.
+\spadcommand{)display value t}
+\begin{verbatim}
+   Definition:
+     t 1 == s(0)
+     t (p | even?(p)) == s(p quo 2)
+     t p == s(- p quo 2)
+\end{verbatim}
+
+Create a series of values of $s$ applied to
+alternating positive and negative arguments.
+\spadcommand{[t(i) for i in 1..]}
+\begin{verbatim}
+   Compiling function s with type Integer -> Fraction Integer 
+   Compiling function t with type PositiveInteger -> Fraction Integer 
+\end{verbatim}
+$$
+\left[
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+Evidently $t(n) = 1$ for all $i$. Check it at $n= 100$. 
+
+\spadcommand{t(100)}
+$$
+1 
+$$
+\returnType{Type: Fraction Integer}
+
+\subsection{Predicates}
+\label{ugUserPiecePred}
+
+We have already seen some examples of \index{function!predicate}
+predicates \index{predicate!in function definition}
+(\ref{ugUserPieceBasic} on page~\pageref{ugUserPieceBasic}).
+Predicates are {\tt Boolean}-valued expressions and Axiom uses them
+for filtering collections (see \ref{ugLangIts} on
+page~\pageref{ugLangIts}) and for placing constraints on function
+arguments.  In this section we discuss their latter usage.
+
+The simplest use of a predicate is one you don't see at all.
+\spadcommand{opposite 'right == 'left}
+\returnType{Type: Void}
+
+Here is a longer way to give the ``opposite definition.''
+\spadcommand{opposite (x | x = 'left) == 'right}
+\returnType{Type: Void}
+
+Try it out.
+\spadcommand{for x in ['right,'left,'inbetween] repeat output opposite x}
+\begin{verbatim}
+Compiling function opposite with type 
+   OrderedVariableList [right, left,inbetween] -> Symbol    
+ left
+ right
+ 
+The function opposite is not defined for the given argument(s).
+\end{verbatim}
+
+Explicit predicates tell Axiom that the given function definition
+piece is to be applied if the predicate evaluates to {\tt true} for
+the arguments to the function.  You can use such ``constant''
+arguments for integers, \index{function!constant argument} strings,
+and quoted symbols.  \index{constant function argument} The {\tt
+Boolean} values {\tt true} and {\tt false} can also be used if qualified with
+``$@$'' or ``$\$$'' and {\tt Boolean}.  The following are all valid
+function definition fragments using constant arguments.
+\begin{verbatim}
+a(1) == ...
+b("unramified") == ...
+c('untested) == ...
+d(true@Boolean) == ...
+\end{verbatim}
+
+If a function has more than one argument, each argument can have its
+own predicate.  However, if a predicate involves two or more
+arguments, it must be given {\it after} all the arguments mentioned in
+the predicate have been given.  You are always safe to give a single
+predicate at the end of the argument list.
+
+A function involving predicates on two arguments.
+\spadcommand{inFirstHalfQuadrant(x | x > 0,y | y < x) == true}
+\returnType{Type: Void}
+
+This is incorrect as it gives a predicate on $y$ before the argument
+$y$ is given.
+\spadcommand{inFirstHalfQuadrant(x | x > 0 and y < x,y) == true}
+\begin{verbatim}
+   1 old definition(s) deleted for function or rule inFirstHalfQuadrant
+\end{verbatim}
+\returnType{Type: Void}
+
+It is always correct to write the predicate at the end.
+\spadcommand{inFirstHalfQuadrant(x,y | x > 0 and y < x) == true}
+\begin{verbatim}
+   1 old definition(s) deleted for function or rule inFirstHalfQuadrant
+\end{verbatim}
+\returnType{Type: Void}
+
+Here is the rest of the definition.
+\spadcommand{inFirstHalfQuadrant(x,y) == false}
+\returnType{Type: Void}
+
+Try it out.
+\spadcommand{[inFirstHalfQuadrant(i,3) for i in 1..5]}
+\begin{verbatim}
+   Compiling function inFirstHalfQuadrant with type (PositiveInteger,
+      PositiveInteger) -> Boolean 
+\end{verbatim}
+$$
+\left[
+{\tt false},  {\tt false},  {\tt false},  {\tt true},  {\tt true} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\section{Caching Previously Computed Results}
+\label{ugUserCache}
+
+By default, Axiom does not save the values of any function.
+\index{function!caching values} You can cause it to save values and
+not to recompute unnecessarily \index{remembering function values} by
+using {\tt )set functions cache}.  \index{set functions cache} This
+should be used before the functions are defined or, at least, before
+they are executed.  The word following ``cache'' should be $0$ to turn
+off caching, a positive integer $n$ to save the last $n$ computed
+values or ``all'' to save all computed values.  If you then give a
+list of names of functions, the caching only affects those functions.
+Use no list of names or ``all'' when you want to define the default
+behavior for functions not specifically mentioned in other 
+{\tt )set functions cache} statements.  If you give no list of names, all
+functions will have the caching behavior.  If you explicitly turn on
+caching for one or more names, you must explicitly turn off caching
+for those names when you want to stop saving their values.
+
+This causes the functions {\bf f} and {\bf g} to have the last three
+computed values saved.
+\spadcommand{)set functions cache 3 f g}
+\begin{verbatim}
+   function f will cache the last 3 values.
+   function g will cache the last 3 values.
+\end{verbatim}
+
+This is a sample definition for {\bf f}.
+\spadcommand{f x == factorial(2**x)}
+\returnType{Type: Void}
+
+A message is displayed stating what {\bf f} will cache.
+\spadcommand{f(4)}
+\begin{verbatim}
+   Compiling function f with type PositiveInteger -> Integer 
+   f will cache 3 most recently computed value(s).
+
++++ |*1;f;1;G82322| redefined
+\end{verbatim}
+$$
+20922789888000 
+$$
+\returnType{Type: PositiveInteger}
+
+This causes all other functions to have all computed values saved by default.
+\spadcommand{)set functions cache all}
+\begin{verbatim}
+   In general, interpreter functions will cache all values.
+\end{verbatim}
+
+This causes all functions that have not been specifically cached in some way
+to have no computed values saved.
+\spadcommand{)set functions cache 0}
+\begin{verbatim}
+ In general, functions will cache no returned values.
+\end{verbatim}
+
+We also make {\bf f} and {\bf g} uncached.
+\spadcommand{)set functions cache 0 f g}
+\begin{verbatim}
+   Caching for function f is turned off
+   Caching for function g is turned off
+\end{verbatim}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Be careful about caching functions that have side effects.  Such a
+function might destructively modify the elements of an array or issue
+a {\bf draw} command, for example.  A function that you expect to
+execute every time it is called should not be cached.  Also, it is
+highly unlikely that a function with no arguments should be cached.\\
+}
+
+You should also be careful about caching functions that depend on free
+variables.  See \ref{ugUserFreeLocal} on
+page~\pageref{ugUserFreeLocal} for an example.
+
+\section{Recurrence Relations}
+\label{ugUserRecur}
+
+One of the most useful classes of function are those defined via a
+``recurrence relation.''  A {\it recurrence relation} makes each
+successive \index{recurrence relation} value depend on some or all of
+the previous values.  A simple example is the ordinary ``factorial'' function:
+\begin{verbatim}
+fact(0) == 1
+fact(n | n > 0) == n * fact(n-1)
+\end{verbatim}
+
+The value of $fact(10)$ depends on the value of $fact(9)$, $fact(9)$
+on $fact(8)$, and so on.  Because it depends on only one previous
+value, it is usually called a {\it first order recurrence relation.}
+You can easily imagine a function based on two, three or more previous
+values.  The Fibonacci numbers are probably the most famous function
+defined by a \index{Fibonacci numbers} second order recurrence relation.
+
+The library function {\bf fibonacci} computes Fibonacci numbers.
+It is obviously optimized for speed.
+\spadcommand{[fibonacci(i) for i in 0..]}
+$$
+\left[
+0,  1,  1,  2,  3,  5,  8,  {13},  {21},  {34},  \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Define the Fibonacci numbers ourselves using a piece-wise definition.
+\spadcommand{fib(1) == 1}
+\returnType{Type: Void}
+
+\spadcommand{fib(2) == 1}
+\returnType{Type: Void}
+
+\spadcommand{fib(n) == fib(n-1) + fib(n-2)}
+\returnType{Type: Void}
+
+As defined, this recurrence relation is obviously doubly-recursive.
+To compute $fib(10)$, we need to compute $fib(9)$ and $fib(8)$.  And
+to $fib(9)$, we need to compute $fib(8)$ and $fib(7)$.  And so on.  It
+seems that to compute $fib(10)$ we need to compute $fib(9)$ once,
+$fib(8)$ twice, $fib(7)$ three times.  Look familiar?  The number of
+function calls needed to compute {\it any} second order recurrence
+relation in the obvious way is exactly $fib(n)$.  These numbers grow!
+For example, if Axiom actually did this, then $fib(500)$ requires more
+than $10^{104}$ function calls.  And, given all
+this, our definition of {\bf fib} obviously could not be used to
+calculate the five-hundredth Fibonacci number.
+
+Let's try it anyway.
+\spadcommand{fib(500)}
+\begin{verbatim}
+   Compiling function fib with type Integer -> PositiveInteger 
+   Compiling function fib as a recurrence relation.
+
+13942322456169788013972438287040728395007025658769730726410_
+8962948325571622863290691557658876222521294125
+\end{verbatim}
+
+\returnType{Type: PositiveInteger}
+
+Since this takes a short time to compute, it obviously didn't do as
+many as $10^{104}$ operations!  By default, Axiom transforms any
+recurrence relation it recognizes into an iteration.  Iterations are
+efficient.  To compute the value of the $n$-th term of a recurrence
+relation using an iteration requires only $n$ function calls. Note
+that if you compare the speed of our {\bf fib} function to the library
+function, our version is still slower.  This is because the library
+\spadfunFrom{fibonacci}{IntegerNumberTheoryFunctions} uses a
+``powering algorithm'' with a computing time proportional to
+$\log^3(n)$ to compute {\tt fibonacci(n)}.
+
+To turn off this special recurrence relation compilation, issue
+\index{set function recurrence}
+\begin{verbatim}
+)set functions recurrence off
+\end{verbatim}
+To turn it back on, substitute ``{\tt on}'' for ``{\tt off}''.
+
+The transformations that Axiom uses for {\bf fib} caches the last two
+values. For a more general $k$-th order recurrence relation, Axiom
+caches the last $k$ values.  If, after computing a value for {\bf
+fib}, you ask for some larger value, Axiom picks up the cached values
+and continues computing from there.  See \ref{ugUserFreeLocal} on
+page~\pageref{ugUserFreeLocal} for an example of a function definition
+that has this same behavior.  Also see \ref{ugUserCache} on
+page~\pageref{ugUserCache} for a more general discussion of how you
+can cache function values.
+
+Recurrence relations can be used for defining recurrence relations
+involving polynomials, rational functions, or anything you like.
+Here we compute the infinite stream of Legendre polynomials.
+
+The Legendre polynomial of degree $0.$
+\spadcommand{p(0) == 1}
+\returnType{Type: Void}
+
+The Legendre polynomial of degree $1.$
+\spadcommand{p(1) == x}
+\returnType{Type: Void}
+
+The Legendre polynomial of degree $n$.
+\spadcommand{p(n) == ((2*n-1)*x*p(n-1) - (n-1)*p(n-2))/n}
+\returnType{Type: Void}
+
+Compute the Legendre polynomial of degree $6.$
+\spadcommand{p(6)}
+\begin{verbatim}
+   Compiling function p with type Integer -> Polynomial Fraction 
+      Integer 
+   Compiling function p as a recurrence relation.
+\end{verbatim}
+$$
+{{{231} \over {16}} \  {x \sp 6}} -{{{315} \over {16}} \  {x \sp 4}}+{{{105} 
+\over {16}} \  {x \sp 2}} -{5 \over {16}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+\section{Making Functions from Objects}
+\label{ugUserMake}
+
+There are many times when you compute a complicated expression and
+then wish to use that expression as the body of a function.  Axiom
+provides an operation called {\bf function} to do \index{function!from
+an object} this. \index{function!made by function @{made by 
+{\bf function}}} It creates a function object and places it into the
+workspace.  There are several versions, depending on how many
+arguments the function has.  The first argument to {\bf function} is
+always the expression to be converted into the function body, and the
+second is always the name to be used for the function.  For more
+information, see section \ref{MakeFunctionXmpPage} on
+page~\pageref{MakeFunctionXmpPage}.
+
+Start with a simple example of a polynomial in three variables.
+\spadcommand{p := -x + y**2 - z**3}
+$$
+-{z \sp 3}+{y \sp 2} -x 
+$$
+\returnType{Type: Polynomial Integer}
+
+To make this into a function of no arguments that simply returns the
+polynomial, use the two argument form of {\bf function}.
+\spadcommand{function(p,'f0)}
+$$
+f0 
+$$
+\returnType{Type: Symbol}
+
+To avoid possible conflicts (see below), it is a good idea to
+quote always this second argument.
+\spadcommand{f0}
+$$
+f0 \  {\left( 
+\right)}
+\  == \  {-{z \sp 3}+{y \sp 2} -x} 
+$$
+\returnType{Type: FunctionCalled f0}
+
+This is what you get when you evaluate the function.
+\spadcommand{f0()}
+$$
+-{z \sp 3}+{y \sp 2} -x 
+$$
+\returnType{Type: Polynomial Integer}
+
+To make a function in $x$, use a version of {\bf function} that takes
+three arguments.  The last argument is the name of the variable to use
+as the parameter.  Typically, this variable occurs in the expression
+and, like the function name, you should quote it to avoid possible confusion.
+\spadcommand{function(p,'f1,'x)}
+$$
+f1 
+$$
+\returnType{Type: Symbol}
+
+This is what the new function looks like.
+\spadcommand{f1}
+$$
+f1 \  x \  == \  {-{z \sp 3}+{y \sp 2} -x} 
+$$
+\returnType{Type: FunctionCalled f1}
+
+This is the value of {\bf f1} at $x = 3$.  Notice that the return type
+of the function is {\tt Polynomial (Integer)}, the same as $p$.
+\spadcommand{f1(3)}
+\begin{verbatim}
+   Compiling function f1 with type PositiveInteger -> Polynomial 
+      Integer 
+\end{verbatim}
+$$
+-{z \sp 3}+{y \sp 2} -3 
+$$
+\returnType{Type: Polynomial Integer}
+
+To use $x$ and $y$ as parameters, use the four argument form of {\bf function}.
+\spadcommand{function(p,'f2,'x,'y)}
+$$
+f2 
+$$
+\returnType{Type: Symbol}
+
+\spadcommand{f2}
+$$
+f2 \  {\left( x,  y 
+\right)}
+\  == \  {-{z \sp 3}+{y \sp 2} -x} 
+$$
+\returnType{Type: FunctionCalled f2}
+
+Evaluate $f2$ at $x = 3$ and $y = 0$.  The return type of {\bf f2} is
+still {\tt Polynomial(Integer)} because the variable $z$ is still
+present and not one of the parameters.
+\spadcommand{f2(3,0)}
+$$
+-{z \sp 3} -3 
+$$
+\returnType{Type: Polynomial Integer}
+
+Finally, use all three variables as parameters.  There is no five
+argument form of {\bf function}, so use the one with three arguments,
+the third argument being a list of the parameters.
+\spadcommand{function(p,'f3,['x,'y,'z])}
+$$
+f3 
+$$
+\returnType{Type: Symbol}
+
+Evaluate this using the same values for $x$ and $y$ as above, but let
+$z$ be $-6$.  The result type of {\bf f3} is {\tt Integer}.
+\spadcommand{f3}
+$$
+f3 \  {\left( x,  y,  z 
+\right)}
+\  == \  {-{z \sp 3}+{y \sp 2} -x} 
+$$
+\returnType{Type: FunctionCalled f3}
+
+\spadcommand{f3(3,0,-6)}
+\begin{verbatim}
+   Compiling function f3 with type (PositiveInteger,NonNegativeInteger,
+      Integer) -> Integer 
+\end{verbatim}
+$$
+213 
+$$
+\returnType{Type: PositiveInteger}
+
+The four functions we have defined via $p$ have been undeclared.  To
+declare a function whose body is to be generated by 
+\index{function!declaring} {\bf function}, issue the declaration 
+{\it before} the function is created.
+\spadcommand{g: (Integer, Integer) -> Float}
+\returnType{Type: Void}
+
+\spadcommand{D(sin(x-y)/cos(x+y),x)}
+$$
+{-{{\sin 
+\left(
+{{y -x}} 
+\right)}
+\  {\sin 
+\left(
+{{y+x}} 
+\right)}}+{{\cos
+\left(
+{{y -x}} 
+\right)}
+\  {\cos 
+\left(
+{{y+x}} 
+\right)}}}
+\over {{\cos 
+\left(
+{{y+x}} 
+\right)}
+\sp 2} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{function(\%,'g,'x,'y)}
+$$
+g 
+$$
+\returnType{Type: Symbol}
+
+\spadcommand{g}
+$$
+g \  {\left( x,  y 
+\right)}
+\  == \  {{-{{\sin 
+\left(
+{{y -x}} 
+\right)}
+\  {\sin 
+\left(
+{{y+x}} 
+\right)}}+{{\cos
+\left(
+{{y -x}} 
+\right)}
+\  {\cos 
+\left(
+{{y+x}} 
+\right)}}}
+\over {{\cos 
+\left(
+{{y+x}} 
+\right)}
+\sp 2}} 
+$$
+\returnType{Type: FunctionCalled g}
+
+It is an error to use $g$ without the quote in the penultimate
+expression since $g$ had been declared but did not have a value.
+Similarly, since it is common to overuse variable names like $x$, $y$,
+and so on, you avoid problems if you always quote the variable names
+for {\bf function}.  In general, if $x$ has a value and you use $x$
+without a quote in a call to {\bf function}, then Axiom does not know
+what you are trying to do.
+
+What kind of object is allowable as the first argument to 
+{\bf function}?  Let's use the Browse facility of HyperDoc to find out.
+\index{Browse@Browse} At the main Browse menu, enter the string 
+{\tt function} and then click on {\bf Operations.}  The exposed operations
+called {\bf function} all take an object whose type belongs to
+category {\tt ConvertibleTo InputForm}.  What domains are those?  Go
+back to the main Browse menu, erase {\tt function}, enter 
+{\tt ConvertibleTo} in the input area, and click on {\bf categories} on the
+{\tt Constructors} line.  At the bottom of the page, enter 
+{\tt InputForm} in the input area following {\bf S =}.  Click on 
+{\tt Cross Reference} and then on {\tt Domains}.  
+The list you see contains over forty domains that belong to the 
+category {\tt ConvertibleTo InputForm}.  Thus you can use {\bf function} 
+for {\tt Integer}, {\tt Float}, {\tt String}, {\tt Complex}, 
+{\tt Expression}, and so on.
+
+\section{Functions Defined with Blocks}
+\label{ugUserBlocks}
+
+You need not restrict yourself to functions that only fit on one line
+or are written in a piece-wise manner.  The body of the function can
+be a block, as discussed in \ref{ugLangBlocks} on page~\pageref{ugLangBlocks}.
+
+Here is a short function that swaps two elements of a list, array or vector.
+\begin{verbatim}
+swap(m,i,j) ==
+  temp := m.i
+  m.i := m.j
+  m.j := temp
+\end{verbatim}
+\returnType{Type: Void}
+
+The significance of {\bf swap} is that it has a destructive
+effect on its first argument.
+\spadcommand{k := [1,2,3,4,5]}
+$$
+\left[
+1,  2,  3,  4,  5 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{swap(k,2,4)}
+\begin{verbatim}
+   Compiling function swap with type (List PositiveInteger,
+      PositiveInteger,PositiveInteger) -> PositiveInteger 
+\end{verbatim}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+You see that the second and fourth elements are interchanged.
+\spadcommand{k}
+$$
+\left[
+1, 4, 3, 2, 5 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Using this, we write a couple of different sort functions.  First, a
+simple bubble sort.  \index{sort!bubble} The operation
+\spadopFrom{\#}{List} returns the number of elements in an aggregate.
+\begin{verbatim}
+bubbleSort(m) ==
+  n := #m
+  for i in 1..(n-1) repeat
+    for j in n..(i+1) by -1 repeat
+      if m.j < m.(j-1) then swap(m,j,j-1)
+  m
+\end{verbatim}
+\returnType{Type: Void}
+
+Let this be the list we want to sort.
+\spadcommand{m := [8,4,-3,9]}
+$$
+\left[
+8,  4,  -3,  9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+This is the result of sorting.
+\spadcommand{bubbleSort(m)}
+\begin{verbatim}
+   Compiling function swap with type (List Integer,Integer,Integer) -> 
+      Integer 
+
++++ |*3;swap;1;G82322| redefined
+   Compiling function bubbleSort with type List Integer -> List Integer
+\end{verbatim}
+$$
+\left[
+-3, 4, 8, 9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Moreover, $m$ is destructively changed to be the sorted version.
+\spadcommand{m}
+$$
+\left[
+-3, 4, 8, 9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+This function implements an insertion sort.  \index{sort!insertion}
+The basic idea is to traverse the list and insert the $i$-th element
+in its correct position among the $i-1$ previous elements.  Since we
+start at the beginning of the list, the list elements before the
+$i$-th element have already been placed in ascending order.
+\begin{verbatim}
+insertionSort(m) ==
+  for i in 2..#m repeat
+    j := i
+    while j > 1 and m.j < m.(j-1) repeat
+      swap(m,j,j-1)
+      j := j - 1
+  m
+\end{verbatim}
+\returnType{Type: Void}
+
+As with our bubble sort, this is a destructive function.
+\spadcommand{m := [8,4,-3,9]}
+$$
+\left[
+8,  4,  -3,  9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{insertionSort(m)}
+\begin{verbatim}
+   Compiling function insertionSort with type List Integer -> List 
+      Integer 
+\end{verbatim}
+$$
+\left[
+-3, 4, 8, 9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{m}
+$$
+\left[
+-3, 4, 8, 9 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Neither of the above functions is efficient for sorting large lists
+since they reference elements by asking for the $j$-th element of the
+structure $m$.
+
+Here is a more efficient bubble sort for lists.
+\begin{verbatim}
+bubbleSort2(m: List Integer): List Integer ==
+  null m => m
+  l := m
+  while not null (r := l.rest) repeat
+     r := bubbleSort2 r
+     x := l.first
+     if x < r.first then
+       l.first := r.first
+       r.first := x
+     l.rest := r
+     l := l.rest
+  m
+
+   Function declaration bubbleSort2 : List Integer -> List Integer has 
+      been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Try it out.
+\spadcommand{bubbleSort2 [3,7,2]}
+$$
+\left[
+7, 3, 2 
+\right]
+$$
+\returnType{Type: List Integer}
+
+This definition is both recursive and iterative, and is tricky!
+Unless you are {\it really} curious about this definition, we suggest
+you skip immediately to the next section.
+
+Here are the key points in the definition.  First notice that if you
+are sorting a list with less than two elements, there is nothing to
+do: just return the list.  This definition returns immediately if
+there are zero elements, and skips the entire {\tt while} loop if there is
+just one element.
+
+The second point to realize is that on each outer iteration, the
+bubble sort ensures that the minimum element is propagated leftmost.
+Each iteration of the {\tt while} loop calls {\bf bubbleSort2} recursively
+to sort all but the first element.  When finished, the minimum element
+is either in the first or second position.  The conditional expression
+ensures that it comes first.  If it is in the second, then a swap
+occurs.  In any case, the {\bf rest} of the original list must be
+updated to hold the result of the recursive call.
+
+\section{Free and Local Variables}
+\label{ugUserFreeLocal}
+
+When you want to refer to a variable that is not local to your
+function, use a ``{\tt free}'' declaration.  \index{free} Variables
+declared to be {\tt free} \index{free variable} are assumed to be defined
+globally \index{variable!free} in the \index{variable!global}
+workspace.  \index{global variable}
+
+This is a global workspace variable.
+\spadcommand{counter := 0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+This function refers to the global $counter$.
+\begin{verbatim}
+f() ==
+  free counter
+  counter := counter + 1
+\end{verbatim}
+\returnType{Type: Void}
+
+The global $counter$ is incremented by $1$.
+\spadcommand{f()}
+\begin{verbatim}
+   Compiling function f with type () -> NonNegativeInteger 
+
++++ |*0;f;1;G82322| redefined
+\end{verbatim}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{counter}
+$$
+1 
+$$
+\returnType{Type: NonNegativeInteger}
+
+
+Usually Axiom can tell that you mean to refer to a global variable and
+so {\tt free} isn't always necessary.  However, for clarity and the sake
+of self-documentation, we encourage you to use it.
+
+Declare a variable to be ``{\tt local}'' when you do not want to refer to
+\index{variable!local} a global variable by the same name.
+\index{local variable}
+
+This function uses $counter$ as a local variable.
+\begin{verbatim}
+g() ==
+  local counter
+  counter := 7
+\end{verbatim}
+\returnType{Type: Void}
+
+Apply the function.
+\spadcommand{g()}
+$$
+7 
+$$
+\returnType{Type: PositiveInteger}
+
+Check that the global value of $counter$ is unchanged.
+\spadcommand{counter}
+$$
+1 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Parameters to a function are local variables in the function.  Even if
+you issue a {\tt free} declaration for a parameter, it is still local.
+
+What happens if you do not declare that a variable $x$ in the body of
+your function is {\tt local} or {\tt free}?  Well, Axiom decides on this basis:
+\begin{enumerate}
+\item Axiom scans your function line-by-line, from top-to-bottom.
+The right-hand side of an assignment is looked at before the left-hand
+side.
+\item If $x$ is referenced before it is assigned a value, it is a
+{\tt free} (global) variable.
+\item If $x$ is assigned a value before it is referenced, it is a
+{\tt local} variable.
+\end{enumerate}
+
+Set two global variables to 1.
+\spadcommand{a := b := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Refer to $a$ before it is assigned a value, but assign a value to $b$
+before it is referenced.
+\begin{verbatim}
+h() ==
+  b := a + 1
+  a := b + a
+\end{verbatim}
+\returnType{Type: Void}
+
+Can you predict this result?
+\spadcommand{h()}
+\begin{verbatim}
+   Compiling function h with type () -> PositiveInteger 
+
++++ |*0;h;1;G82322| redefined
+\end{verbatim}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+How about this one?
+\spadcommand{[a, b]}
+$$
+\left[
+3, 1 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+What happened?  In the first line of the function body for $h$, $a$ is
+referenced on the right-hand side of the assignment.  Thus $a$ is a
+free variable.  The variable $b$ is not referenced in that line, but
+it is assigned a value.  Thus $b$ is a local variable and is given the
+value $a + 1 = 2$.  In the second line, the free variable $a$ is
+assigned the value $b + a$ which equals $2 + 1 = 3.$ This is the value
+returned by the function.  Since $a$ was free in {\bf h}, the global
+variable $a$ has value $3.$ Since $b$ was local in {\bf h}, the global
+variable $b$ is unchanged---it still has the value $1$.
+
+It is good programming practice always to declare global variables.
+However, by far the most common situation is to have local variables
+in your functions.  No declaration is needed for this situation, but
+be sure to initialize their values.
+
+Be careful if you use free variables and you cache the value of your
+function (see \ref{ugUserCache} on page~\pageref{ugUserCache}).
+Caching {\it only} checks if the values of the function arguments are
+the same as in a function call previously seen.  It does not check if
+any of the free variables on which the function depends have changed
+between function calls.
+
+Turn on caching for {\bf p}.
+\spadcommand{)set fun cache all p}
+\begin{verbatim}
+   function p will cache all values.
+\end{verbatim}
+
+Define {\bf p} to depend on the free variable $N$.
+\spadcommand{p(i,x) == ( free N; reduce( + , [ (x-i)**n for n in 1..N ] ) )}
+\returnType{Type: Void}
+
+Set the value of $N$.
+\spadcommand{N := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Evaluate {\bf p} the first time.
+\spadcommand{p(0, x)}
+$$
+x 
+$$
+\returnType{Type: Polynomial Integer}
+
+Change the value of $N$.
+\spadcommand{N := 2}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+Evaluate {\bf p} the second time.
+\spadcommand{p(0, x)}
+$$
+x 
+$$
+\returnType{Type: Polynomial Integer}
+
+If caching had been turned off, the second evaluation would have
+reflected the changed value of $N$.
+
+Turn off caching for {\bf p}.
+\spadcommand{)set fun cache 0 p}
+\begin{verbatim}
+   Caching for function p is turned off
+\end{verbatim}
+
+Axiom does not allow {\it fluid variables}, that is, variables
+\index{variable!fluid} bound by a function $f$ that can be referenced
+by functions called by $f$.  \index{fluid variable}
+
+Values are passed to functions by {\it reference}: a pointer to the
+value is passed rather than a copy of the value or a pointer to a
+copy.
+
+This is a global variable that is bound to a record object.
+\spadcommand{r : Record(i : Integer) := [1]}
+$$
+\left[
+{i=1} 
+\right]
+$$
+\returnType{Type: Record(i: Integer)}
+
+This function first modifies the one component of its record argument
+and then rebinds the parameter to another record.
+\begin{verbatim}
+resetRecord rr ==
+  rr.i := 2
+  rr := [10]
+\end{verbatim}
+\returnType{Type: Void}
+
+Pass $r$ as an argument to {\bf resetRecord}. 
+\spadcommand{resetRecord r}
+$$
+\left[
+{i={10}} 
+\right]
+$$
+\returnType{Type: Record(i: Integer)}
+
+The value of $r$ was changed by the expression $rr.i := 2$ but not by
+$rr := [10]$.
+\spadcommand{r}
+$$
+\left[
+{i=2} 
+\right]
+$$
+\returnType{Type: Record(i: Integer)}
+
+To conclude this section, we give an iterative definition of
+\index{Fibonacci numbers} a function that computes Fibonacci numbers.
+This definition approximates the definition into which Axiom
+transforms the recurrence relation definition of {\bf fib} in
+\ref{ugUserRecur} on page~\pageref{ugUserRecur}.
+
+Global variables {\tt past} and {\tt present} are used to hold the last
+computed Fibonacci numbers.
+\spadcommand{past := present := 1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Global variable $index$ gives the current index of $present$.
+\spadcommand{index := 2}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+Here is a recurrence relation defined in terms of these three global
+variables.
+\begin{verbatim}
+fib(n) ==
+  free past, present, index
+  n < 3 => 1
+  n = index - 1 => past
+  if n < index-1 then
+    (past,present) := (1,1)
+    index := 2
+  while (index < n) repeat
+    (past,present) := (present, past+present)
+    index := index + 1
+  present
+\end{verbatim}
+\returnType{Type: Void}
+
+Compute the infinite stream of Fibonacci numbers.
+\spadcommand{fibs := [fib(n) for n in 1..]}
+$$
+\left[
+1, 1, 2, 3, 5, 8, {13}, {21}, {34}, {55},
+\ldots 
+\right]
+$$
+\returnType{Type: Stream PositiveInteger}
+
+What is the 1000th Fibonacci number?
+\spadcommand{fibs 1000}
+\begin{verbatim}
+  434665576869374564356885276750406258025646605173717804024_
+    8172908953655541794905189040387984007925516929592259308_
+    0322634775209689623239873322471161642996440906533187938_
+    298969649928516003704476137795166849228875
+\end{verbatim}
+\returnType{Type: PositiveInteger}
+
+As an exercise, we suggest you write a function in an iterative style
+that computes the value of the recurrence relation 
+$p(n) = p(n-1) - 2 \, p(n-2) + 4 \, p(n-3)$ 
+having the initial values 
+$p(1) = 1,\, p(2) = 3 \hbox{ and } p(3) = 9.$ 
+How would you write the function using an element {\tt OneDimensionalArray} 
+or {\tt Vector} to hold the previously computed values?
+
+\section{Anonymous Functions}
+\label{ugUserAnon}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+An {\it anonymous function} is a function that is
+\index{function!anonymous} defined \index{anonymous function} by
+giving a list of parameters, the ``maps-to'' compound 
+\index{+-> @{\tt +->}} symbol ``{\tt +->}'' 
+(from the mathematical symbol $\mapsto$), and
+by an expression involving the parameters, the evaluation of which
+determines the return value of the function.
+
+\begin{center}
+{\tt ( $\hbox{\it parm}_{1}$, $\hbox{\it parm}_{2}$, \ldots, 
+$\hbox{\it parm}_{N}$ ) {\tt +->} {\it expression}}
+\end{center}
+{\ }%force a blank line 
+}
+
+You can apply an anonymous function in several ways.
+\begin{enumerate}
+\item Place the anonymous function definition in parentheses
+directly followed by a list of arguments.
+\item Assign the anonymous function to a variable and then
+use the variable name when you would normally use a function name.
+\item Use ``{\tt ==}'' to use the anonymous function definition as
+the arguments and body of a regular function definition.
+\item Have a named function contain a declared anonymous function and
+use the result returned by the named function.
+\end{enumerate}
+
+\subsection{Some Examples}
+\label{ugUserAnonExamp}
+
+Anonymous functions are particularly useful for defining functions
+``on the fly.'' That is, they are handy for simple functions that are
+used only in one place.  In the following examples, we show how to
+write some simple anonymous functions.
+
+This is a simple absolute value function.
+\spadcommand{x +-> if x < 0 then -x else x}
+$$
+x \mapsto {if \  {x<0} \  {\begin{array}{l} {then \  -x} \\ 
+{else \  x} 
+\end{array}
+}} 
+$$
+\returnType{Type: AnonymousFunction}
+
+\spadcommand{abs1 := \%}
+$$
+x \mapsto {if \  {x<0} \  {\begin{array}{l} {then \  -x} \\ 
+{else \  x} 
+\end{array}
+}} 
+$$
+\returnType{Type: AnonymousFunction}
+
+This function returns {\tt true} if the absolute value of
+the first argument is greater than the absolute value of the
+second, {\tt false} otherwise.
+
+\spadcommand{(x,y) +-> abs1(x) > abs1(y)}
+$$
+{\left( x,  y 
+\right)}
+\mapsto {{abs1 
+\left(
+{y} 
+\right)}<{abs1
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: AnonymousFunction}
+
+We use the above function to ``sort'' a list of integers.
+\spadcommand{sort(\%,[3,9,-4,10,-3,-1,-9,5])}
+$$
+\left[
+{10},  -9,  9,  5,  -4,  -3,  3,  -1 
+\right]
+$$
+\returnType{Type: List Integer}
+
+This function returns $1$ if $i + j$ is even, $-1$ otherwise.
+\spadcommand{ev := ( (i,j) +-> if even?(i+j) then 1 else -1)}
+$$
+{\left( i,  j 
+\right)}
+\mapsto {if \  {even? 
+\left(
+{{i+j}} 
+\right)}
+\  {\begin{array}{l} {then \  1} \\ 
+{else \  -1} 
+\end{array}
+}} 
+$$
+\returnType{Type: AnonymousFunction}
+
+We create a four-by-four matrix containing $1$ or $-1$ depending on
+whether the row plus the column index is even or not.
+\spadcommand{matrix([ [ev(row,col) for row in 1..4] for col in 1..4])}
+$$
+\left[
+\begin{array}{cccc}
+1 & -1 & 1 & -1 \\ 
+-1 & 1 & -1 & 1 \\ 
+1 & -1 & 1 & -1 \\ 
+-1 & 1 & -1 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+This function returns {\tt true} if a polynomial in $x$ has multiple
+roots, {\tt false} otherwise.  It is defined and applied in the same
+expression.
+\spadcommand{( p +-> not one?(gcd(p,D(p,x))) )(x**2+4*x+4)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+This and the next expression are equivalent.
+\spadcommand{g(x,y,z) == cos(x + sin(y + tan(z)))}
+\returnType{Type: Void}
+
+The one you use is a matter of taste.
+\spadcommand{g == (x,y,z) +-> cos(x + sin(y + tan(z)))}
+\begin{verbatim}
+   1 old definition(s) deleted for function or rule g 
+\end{verbatim}
+\returnType{Type: Void}
+
+\subsection{Declaring Anonymous Functions}
+\label{ugUserAnonDeclare}
+
+If you declare any of the arguments you must declare all of them. Thus,
+\begin{verbatim}
+(x: INT,y): FRAC INT +-> (x + 2*y)/(y - 1)
+\end{verbatim}
+is not legal.
+
+This is an example of a fully declared anonymous function.
+\index{function!declaring} \index{function!anonymous!declaring} The
+output shown just indicates that the object you created is a
+particular kind of map, that is, function.
+\spadcommand{(x: INT,y: INT): FRAC INT +-> (x + 2*y)/(y - 1)}
+$$
+\mbox{theMap(...)} 
+$$
+\returnType{Type: ((Integer,Integer) {\tt ->} Fraction Integer)}
+
+Axiom allows you to declare the arguments and not declare
+the return type.
+\spadcommand{(x: INT,y: INT) +-> (x + 2*y)/(y - 1)}
+$$
+\mbox{theMap(...)} 
+$$
+\returnType{Type: ((Integer,Integer) {\tt ->} Fraction Integer)}
+
+The return type is computed from the types of the arguments and the
+body of the function.  You cannot declare the return type if you do
+not declare the arguments.  Therefore,
+\begin{verbatim}
+(x,y): FRAC INT +-> (x + 2*y)/(y - 1)
+\end{verbatim}
+
+is not legal. This and the next expression are equivalent.
+\spadcommand{h(x: INT,y: INT): FRAC INT == (x + 2*y)/(y - 1)}
+\begin{verbatim}
+   Function declaration h : (Integer,Integer) -> Fraction Integer
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+The one you use is a matter of taste.
+\spadcommand{h == (x: INT,y: INT): FRAC INT +-> (x + 2*y)/(y - 1)}
+\begin{verbatim}
+   Function declaration h : (Integer,Integer) -> Fraction Integer
+      has been added to workspace.
+   1 old definition(s) deleted for function or rule h 
+\end{verbatim}
+\returnType{Type: Void}
+
+When should you declare an anonymous function?  
+\begin{enumerate}
+\item If you use an anonymous function and Axiom can't figure out what
+you are trying to do, declare the function.  
+\item If the function has nontrivial argument types or a nontrivial 
+return type that Axiom may be able to determine eventually, but you 
+are not willing to wait that long, declare the function.  
+\item If the function will only be used for arguments of specific types 
+and it is not too much trouble to declare the function, do so.  
+\item If you are using the anonymous function as an argument to another 
+function (such as {\bf map} or {\bf sort}), consider declaring the function.  
+\item If you define an anonymous function inside a named function, 
+you {\it must} declare the anonymous function.  
+\end{enumerate}
+
+This is an example of a named function for integers that returns a
+function.
+\spadcommand{addx x == ((y: Integer): Integer +-> x + y)}
+\returnType{Type: Void}
+
+We define {\bf g} to be a function that adds $10$ to its
+argument.
+\spadcommand{g := addx 10}
+\begin{verbatim}
+   Compiling function addx with type 
+     PositiveInteger -> (Integer -> Integer) 
+\end{verbatim}
+$$
+\mbox{theMap(...)} 
+$$
+\returnType{Type: (Integer {\tt ->} Integer)}
+
+Try it out.
+\spadcommand{g 3}
+$$
+13 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{g(-4)}
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+\index{function!anonymous!restrictions}
+An anonymous function cannot be recursive: since it does not have a
+name, you cannot even call it within itself!  If you place an
+anonymous function inside a named function, the anonymous function
+must be declared.
+
+\section{Example: A Database}
+\label{ugUserDatabase}
+
+This example shows how you can use Axiom to organize a database of
+lineage data and then query the database for relationships.
+
+The database is entered as ``assertions'' that are really pieces of a
+function definition.
+\spadcommand{children("albert") == ["albertJr","richard","diane"]}
+\returnType{Type: Void}
+
+Each piece $children(x) == y$ means ``the children of $x$ are $y$''.
+\spadcommand{children("richard") == ["douglas","daniel","susan"]}
+\returnType{Type: Void}
+
+This family tree thus spans four generations.
+\spadcommand{children("douglas") == ["dougie","valerie"]}
+\returnType{Type: Void}
+
+Say ``no one else has children.''
+\spadcommand{children(x) == []}
+\returnType{Type: Void}
+
+We need some functions for computing lineage.  Start with {\tt childOf}.
+\spadcommand{childOf(x,y) == member?(x,children(y))}
+\returnType{Type: Void}
+
+To find the {\tt parentOf} someone, you have to scan the database of
+people applying {\tt children}.
+\begin{verbatim}
+parentOf(x) ==
+  for y in people repeat
+    (if childOf(x,y) then return y)
+  "unknown"
+\end{verbatim}
+\returnType{Type: Void}
+
+And a grandparent of $x$ is just a parent of a parent of $x$.
+\spadcommand{grandParentOf(x) == parentOf parentOf x}
+\returnType{Type: Void}
+
+The grandchildren of $x$ are the people $y$ such that $x$ is a
+grandparent of $y$.
+\spadcommand{grandchildren(x) == [y for y in people | grandParentOf(y) = x]}
+\returnType{Type: Void}
+
+Suppose you want to make a list of all great-grandparents.  Well, a
+great-grandparent is a grandparent of a person who has children.
+
+\begin{verbatim}
+greatGrandParents == [x for x in people |
+  reduce(_or,
+    [not empty? children(y) for y in grandchildren(x)],false)]
+\end{verbatim}
+\returnType{Type: Void}
+
+Define {\tt descendants} to include the parent as well.
+\begin{verbatim}
+descendants(x) ==
+  kids := children(x)
+  null kids => [x]
+  concat(x,reduce(concat,[descendants(y)
+    for y in kids],[]))
+\end{verbatim}
+\returnType{Type: Void}
+
+Finally, we need a list of people.  Since all people are descendants
+of ``albert'', let's say so.
+\spadcommand{people == descendants "albert"}
+\returnType{Type: Void}
+
+We have used ``{\tt ==}'' to define the database and some functions to
+query the database.  But no computation is done until we ask for some
+information.  Then, once and for all, the functions are analyzed and
+compiled to machine code for run-time efficiency.  Notice that no
+types are given anywhere in this example.  They are not needed.
+
+Who are the grandchildren of ``richard''?
+\spadcommand{grandchildren "richard"}
+\begin{verbatim}
+Compiling function children with type String -> List String 
+Compiling function descendants with type String -> List String 
+Compiling body of rule people to compute value of type List String 
+Compiling function childOf with type (String,String) -> Boolean 
+Compiling function parentOf with type String -> String 
+Compiling function grandParentOf with type String -> String 
+Compiling function grandchildren with type String -> List String 
+\end{verbatim}
+$$
+\left[
+\mbox{\tt "dougie"} , \mbox{\tt "valerie"} 
+\right]
+$$
+\returnType{Type: List String}
+
+Who are the great-grandparents?
+\spadcommand{greatGrandParents}
+\begin{verbatim}
+Compiling body of rule greatGrandParents to compute value of 
+   type List String 
+\end{verbatim}
+$$
+\left[
+\mbox{\tt "albert"} 
+\right]
+$$
+\returnType{Type: List String}
+
+\section{Example: A Famous Triangle}
+\label{ugUserTriangle}
+
+In this example we write some functions that display Pascal's
+triangle.  \index{Pascal's triangle} It demonstrates the use of
+piece-wise definitions and some output operations you probably haven't
+seen before.
+
+To make these output operations available, we have to {\it expose} the
+domain {\tt OutputForm}.  \index{OutputForm} See 
+\ref{ugTypesExpose} on page~\pageref{ugTypesExpose}
+for more information about exposing domains and packages.
+\spadcommand{)set expose add constructor OutputForm}
+\begin{verbatim}
+   OutputForm is now explicitly exposed in frame G82322 
+\end{verbatim}
+
+Define the values along the first row and any column $i$.
+\spadcommand{pascal(1,i) == 1}
+\returnType{Type: Void}
+
+Define the values for when the row and column index $i$ are equal.
+Repeating the argument name indicates that the two index values are equal.
+\spadcommand{pascal(n,n) == 1}
+\returnType{Type: Void}
+
+\begin{verbatim}
+pascal(i,j | 1 < i and i < j) ==
+   pascal(i-1,j-1)+pascal(i,j-1)
+\end{verbatim}
+\returnType{Type: Void}
+
+Now that we have defined the coefficients in Pascal's triangle, let's
+write a couple of one-liners to display it. 
+
+First, define a function that gives the $n$-th row.
+\spadcommand{pascalRow(n) == [pascal(i,n) for i in 1..n]}
+\returnType{Type: Void}
+
+Next, we write the function {\bf displayRow} to display the row,
+separating entries by blanks and centering.
+\spadcommand{displayRow(n) == output center blankSeparate pascalRow(n)}
+\returnType{Type: Void}
+
+Here we have used three output operations.  Operation
+\spadfunFrom{output}{OutputForm} displays the printable form of
+objects on the screen, \spadfunFrom{center}{OutputForm} centers a
+printable form in the width of the screen, and
+\spadfunFrom{blankSeparate}{OutputForm} takes a list of nprintable
+forms and inserts a blank between successive elements.
+
+Look at the result.
+\spadcommand{for i in 1..7 repeat displayRow i}
+\begin{verbatim}
+   Compiling function pascal with type (Integer,Integer) -> 
+      PositiveInteger 
+   Compiling function pascalRow with type PositiveInteger -> List 
+      PositiveInteger 
+   Compiling function displayRow with type PositiveInteger -> Void 
+
+
+                                   1
+                                  1 1
+                                 1 2 1
+                                1 3 3 1
+                               1 4 6 4 1
+                             1 5 10 10 5 1
+                            1 6 15 20 15 6 1
+\end{verbatim}
+\returnType{Type: Void}
+
+Being purists, we find this less than satisfactory.  Traditionally,
+elements of Pascal's triangle are centered between the left and right
+elements on the line above.
+
+To fix this misalignment, we go back and redefine {\bf pascalRow} to
+right adjust the entries within the triangle within a width of four
+characters.
+
+\spadcommand{pascalRow(n) == [right(pascal(i,n),4) for i in 1..n]}
+\begin{verbatim}
+   Compiled code for pascalRow has been cleared.
+   Compiled code for displayRow has been cleared.
+   1 old definition(s) deleted for function or rule pascalRow 
+\end{verbatim}
+\returnType{Type: Void}
+
+Finally let's look at our purely reformatted triangle.
+\spadcommand{for i in 1..7 repeat displayRow i}
+\begin{verbatim}
+   Compiling function pascalRow with type PositiveInteger -> List 
+      OutputForm 
+
++++ |*1;pascalRow;1;G82322| redefined
+   Compiling function displayRow with type PositiveInteger -> Void 
+
++++ |*1;displayRow;1;G82322| redefined
+                                     1
+                                  1    1
+                                1    2    1
+                             1    3    3    1
+                           1    4    6    4    1
+                        1    5   10   10    5    1
+                      1    6   15   20   15    6    1
+\end{verbatim}
+\returnType{Type: Void}
+
+Unexpose {\tt OutputForm} so we don't get unexpected results later.
+\spadcommand{)set expose drop constructor OutputForm}
+\begin{verbatim}
+   OutputForm is now explicitly hidden in frame G82322 
+\end{verbatim}
+
+\section{Example: Testing for Palindromes}
+\label{ugUserPal}
+
+In this section we define a function {\bf pal?} that tests whether its
+\index{palindrome} argument is a {\it palindrome}, that is, something
+that reads the same backwards and forwards.  For example, the string
+``Madam I'm Adam'' is a palindrome (excluding blanks and punctuation)
+and so is the number $123454321$.  The definition works for any
+datatype that has $n$ components that are accessed by the indices
+$1\ldots n$.
+
+Here is the definition for {\bf pal?}.  It is simply a call to an
+auxiliary function called {\bf palAux?}.  We are following the
+convention of ending a function's name with {\tt ?} if the function
+returns a {\tt Boolean} value.
+\spadcommand{pal? s ==  palAux?(s,1,\#s)}
+\returnType{Type: Void}
+
+Here is {\bf palAux?}.  It works by comparing elements that are
+equidistant from the start and end of the object.
+\begin{verbatim}
+palAux?(s,i,j) ==
+  j > i =>
+    (s.i = s.j) and palAux?(s,i+1,i-1)
+  true
+\end{verbatim}
+\returnType{Type: Void}
+
+Try {\bf pal?} on some examples.  First, a string.
+\spadcommand{pal? "Oxford"}
+\begin{verbatim}
+   Compiling function palAux? with type (String,Integer,Integer) -> 
+      Boolean 
+   Compiling function pal? with type String -> Boolean 
+\end{verbatim}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+A list of polynomials.
+\spadcommand{pal? [4,a,x-1,0,x-1,a,4]}
+\begin{verbatim}
+   Compiling function palAux? with type (List Polynomial Integer,
+      Integer,Integer) -> Boolean 
+   Compiling function pal? with type List Polynomial Integer -> Boolean
+\end{verbatim}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+A list of integers from the example in the last section. 
+\spadcommand{pal? [1,6,15,20,15,6,1]}
+\begin{verbatim}
+   Compiling function palAux? with type (List PositiveInteger,Integer,
+      Integer) -> Boolean 
+   Compiling function pal? with type List PositiveInteger -> Boolean 
+\end{verbatim}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+To use {\bf pal?} on an integer, first convert it to a string.
+\spadcommand{pal?(1441::String)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+Compute an infinite stream of decimal numbers, each of which is an
+obvious palindrome.
+\spadcommand{ones := [reduce(+,[10**j for j in 0..i]) for i in 1..]}
+$$
+\begin{array}{@{}l}
+\left[
+{11}, {111}, {1111}, {11111}, {111111}, {1111111}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{11111111}, {111111111}, {1111111111}, {11111111111}, \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream PositiveInteger}
+
+\spadcommand{)set streams calculate 9}
+
+How about their squares?
+\spadcommand{squares := [x**2 for x in ones]}
+$$
+\begin{array}{@{}l}
+\left[
+{121}, {12321}, {1234321}, {123454321}, {12345654321}, {1234567654321}, 
+\right.
+\\
+\\
+\displaystyle
+{123456787654321}, {12345678987654321}, {1234567900987654321}, 
+\\
+\\
+\displaystyle
+\left.
+{123456790120987654321},  \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream PositiveInteger}
+
+Well, let's test them all.
+\spadcommand{[pal?(x::String) for x in squares]}
+$$
+\left[
+{\tt true}, {\tt true}, {\tt true}, {\tt true}, {\tt true}, 
+{\tt true}, {\tt true}, {\tt true}, {\tt true}, {\tt true}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Boolean}
+
+\spadcommand{)set streams calculate 7}
+
+\section{Rules and Pattern Matching}
+\label{ugUserRules}
+
+A common mathematical formula is 
+$$ \log(x) + \log(y) = \log(x y) \quad\forall \, x \hbox{\ and\ } y$$ 
+The presence of ``$\forall$'' indicates that $x$ and $y$ can stand for
+arbitrary mathematical expressions in the above formula.  You can use
+such mathematical formulas in Axiom to specify ``rewrite rules''.
+Rewrite rules are objects in Axiom that can be assigned to variables
+for later use, often for the purpose of simplification.  Rewrite rules
+look like ordinary function definitions except that they are preceded
+by the reserved word $rule$.  \index{rule} For example, a rewrite rule
+for the above formula is:
+\begin{verbatim}
+rule log(x) + log(y) == log(x * y)
+\end{verbatim}
+
+Like function definitions, no action is taken when a rewrite rule is
+issued.  Think of rewrite rules as functions that take one argument.
+When a rewrite rule $A = B$ is applied to an argument $f$, its meaning
+is: ``rewrite every subexpression of $f$ that {\it matches} $A$ by
+$B.$'' The left-hand side of a rewrite rule is called a {\it pattern};
+its right-side side is called its {\it substitution}.
+
+Create a rewrite rule named {\bf logrule}.  The generated symbol
+beginning with a ``{\tt \%}'' is a place-holder for any other terms that
+might occur in the sum.
+\spadcommand{logrule := rule log(x) + log(y) == log(x * y)}
+$$
+{{\log 
+\left(
+{y} 
+\right)}+{\log
+\left(
+{x} 
+\right)}+
+ \%C} \mbox{\rm == } {{\log 
+\left(
+{{x \  y}} 
+\right)}+
+ \%C} 
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Create an expression with logarithms.
+\spadcommand{f := log sin x + log x}
+$$
+{\log 
+\left(
+{{\sin 
+\left(
+{x} 
+\right)}}
+\right)}+{\log
+\left(
+{x} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+Apply {\bf logrule} to $f$.
+\spadcommand{logrule f}
+$$
+\log 
+\left(
+{{x \  {\sin 
+\left(
+{x} 
+\right)}}}
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+The meaning of our example rewrite rule is: ``for all expressions $x$
+and $y$, rewrite $log(x) + log(y)$ by $log(x * y)$.''  Patterns
+generally have both operation names (here, {\bf log} and ``{\tt +}'') and
+variables (here, $x$ and $y$).  By default, every operation name
+stands for itself.  Thus {\bf log} matches only ``$log$'' and not any
+other operation such as {\bf sin}.  On the other hand, variables do
+not stand for themselves.  Rather, a variable denotes a {\it pattern
+variable} that is free to match any expression whatsoever.
+\index{pattern!variables}
+
+When a rewrite rule is applied, a process called 
+{\it pattern matching} goes to work by systematically scanning
+\index{pattern!matching} the subexpressions of the argument.  When a
+subexpression is found that ``matches'' the pattern, the subexpression
+is replaced by the right-hand side of the rule.  The details of what
+happens will be covered later.
+
+The customary Axiom notation for patterns is actually a shorthand for
+a longer, more general notation.  Pattern variables can be made
+explicit by using a percent ``{\tt \%}'' as the first character of the
+variable name.  To say that a name stands for itself, you can prefix
+that name with a quote operator ``{\tt '}''.  Although the current Axiom
+parser does not let you quote an operation name, this more general
+notation gives you an alternate way of giving the same rewrite rule:
+\begin{verbatim}
+rule log(%x) + log(%y) == log(x * y)
+\end{verbatim}
+
+This longer notation gives you patterns that the standard notation
+won't handle.  For example, the rule
+\begin{verbatim}
+rule %f(c * 'x) ==  c*%f(x)
+\end{verbatim}
+means ``for all $f$ and $c$, replace $f(y)$ by $c * f(x)$ when $y$ is
+the product of $c$ and the explicit variable $x$.''
+
+Thus the pattern can have several adornments on the names that appear there.
+Normally, all these adornments are dropped in the substitution on the
+right-hand side.
+
+To summarize:
+
+\boxed{4.6in}{
+\vskip 0.1cm
+To enter a single rule in Axiom, use the following syntax: \index{rule}
+\begin{center}
+{\tt rule {\it leftHandSide} == {\it rightHandSide}}
+\end{center}
+
+The {\it leftHandSide} is a pattern to be matched and the {\it
+rightHandSide} is its substitution.  The rule is an object of type
+{\tt RewriteRule} that can be assigned to a variable and applied to
+expressions to transform them.\\
+}
+
+Rewrite rules can be collected
+into rulesets so that a set of rules can be applied at once.
+Here is another simplification rule for logarithms.
+$$y \log(x) = \log(x^y) \quad\forall \, x \hbox{\ and\ } y$$
+If instead of giving a single rule following the reserved word $rule$
+you give a ``pile'' of rules, you create what is called a {\it
+ruleset.}  \index{ruleset} Like rules, rulesets are objects in Axiom
+and can be assigned to variables.  You will find it useful to group
+commonly used rules into input files, and read them in as needed.
+
+Create a ruleset named $logrules$.
+\begin{verbatim}
+logrules := rule
+  log(x) + log(y) == log(x * y)
+  y * log x       == log(x ** y)
+\end{verbatim}
+$$
+\left\{
+{{{\log 
+\left(
+{y} 
+\right)}+{\log
+\left(
+{x} 
+\right)}+
+ \%B} \mbox{\rm == } {{\log 
+\left(
+{{x \  y}} 
+\right)}+
+ \%B}}, {{y \  {\log 
+\left(
+{x} 
+\right)}}
+\mbox{\rm == } {\log 
+\left(
+{{x \sp y}} 
+\right)}}
+\right\}
+$$
+\returnType{Type: Ruleset(Integer,Integer,Expression Integer)}
+
+Again, create an expression $f$ containing logarithms.
+\spadcommand{f := a * log(sin x) - 2 * log x}
+$$
+{a \  {\log 
+\left(
+{{\sin 
+\left(
+{x} 
+\right)}}
+\right)}}
+-{2 \  {\log 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: Expression Integer}
+
+Apply the ruleset {\bf logrules} to $f$.
+\spadcommand{logrules f}
+$$
+\log 
+\left(
+{{{{\sin 
+\left(
+{x} 
+\right)}
+\sp a} \over {x \sp 2}}} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+
+We have allowed pattern variables to match arbitrary expressions in
+the above examples.  Often you want a variable only to match
+expressions satisfying some predicate.  For example, we may want to
+apply the transformation 
+$$y \log(x) = \log(x^y)$$ 
+only when $y$ is an integer.
+
+The way to restrict a pattern variable $y$ by a predicate $f(y)$
+\index{pattern!variable!predicate} is by using a vertical bar ``{\tt |}'',
+which means ``such that,'' in \index{such that} much the same way it
+is used in function definitions.  \index{predicate!on a pattern
+variable} You do this only once, but at the earliest (meaning deepest
+and leftmost) part of the pattern.
+
+This restricts the logarithmic rule to create integer exponents only.
+\begin{verbatim}
+logrules2 := rule
+  log(x) + log(y)          == log(x * y)
+  (y | integer? y) * log x == log(x ** y)
+\end{verbatim}
+$$
+\left\{
+{{{\log 
+\left(
+{y} 
+\right)}+{\log
+\left(
+{x} 
+\right)}+
+ \%D} \mbox{\rm == } {{\log 
+\left(
+{{x \  y}} 
+\right)}+
+ \%D}}, {{y \  {\log 
+\left(
+{x} 
+\right)}}
+\mbox{\rm == } {\log 
+\left(
+{{x \sp y}} 
+\right)}}
+\right\}
+$$
+\returnType{Type: Ruleset(Integer,Integer,Expression Integer)}
+
+Compare this with the result of applying the previous set of rules.
+\spadcommand{f}
+$$
+{a \  {\log 
+\left(
+{{\sin 
+\left(
+{x} 
+\right)}}
+\right)}}
+-{2 \  {\log 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{logrules2 f}
+$$
+{a \  {\log 
+\left(
+{{\sin 
+\left(
+{x} 
+\right)}}
+\right)}}+{\log
+\left(
+{{1 \over {x \sp 2}}} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+You should be aware that you might need to apply a function like 
+{\tt integer} within your predicate expression to actually apply the test
+function.
+
+Here we use {\tt integer} because $n$ has type {\tt Expression
+Integer} but {\bf even?} is an operation defined on integers.
+\spadcommand{evenRule := rule cos(x)**(n | integer? n and even? integer n)==(1-sin(x)**2)**(n/2)}
+$$
+{{\cos 
+\left(
+{x} 
+\right)}
+\sp n} \mbox{\rm == } {{\left( -{{\sin 
+\left(
+{x} 
+\right)}
+\sp 2}+1 
+\right)}
+\sp {n \over 2}} 
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Here is the application of the rule.
+\spadcommand{evenRule( cos(x)**2 )}
+$$
+-{{\sin 
+\left(
+{x} 
+\right)}
+\sp 2}+1 
+$$
+\returnType{Type: Expression Integer}
+
+This is an example of some of the usual identities involving products of
+sines and cosines.
+\begin{verbatim}
+sinCosProducts == rule
+  sin(x) * sin(y) == (cos(x-y) - cos(x + y))/2
+  cos(x) * cos(y) == (cos(x-y) + cos(x+y))/2
+  sin(x) * cos(y) == (sin(x-y) + sin(x + y))/2
+\end{verbatim}
+\returnType{Type: Void}
+
+\spadcommand{g := sin(a)*sin(b) + cos(b)*cos(a) + sin(2*a)*cos(2*a)}
+$$
+{{\sin 
+\left(
+{a} 
+\right)}
+\  {\sin 
+\left(
+{b} 
+\right)}}+{{\cos
+\left(
+{{2 \  a}} 
+\right)}
+\  {\sin 
+\left(
+{{2 \  a}} 
+\right)}}+{{\cos
+\left(
+{a} 
+\right)}
+\  {\cos 
+\left(
+{b} 
+\right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{sinCosProducts g}
+\begin{verbatim}
+   Compiling body of rule sinCosProducts to compute value of type 
+      Ruleset(Integer,Integer,Expression Integer) 
+\end{verbatim}
+$$
+{{\sin 
+\left(
+{{4 \  a}} 
+\right)}+{2
+\  {\cos 
+\left(
+{{b -a}} 
+\right)}}}
+\over 2 
+$$
+\returnType{Type: Expression Integer}
+
+Another qualification you will often want to use is to allow a pattern to
+match an identity element.
+Using the pattern $x + y$, for example, neither $x$ nor $y$
+matches the expression $0$.
+Similarly, if a pattern contains a product $x*y$ or an exponentiation
+$x**y$, then neither $x$ or $y$ matches $1$.
+
+If identical elements were matched, pattern matching would generally loop.
+Here is an expansion rule for exponentials.
+\spadcommand{exprule := rule exp(a + b) == exp(a) * exp(b)}
+$$
+{e \sp {\left( b+a 
+\right)}}
+\mbox{\rm == } {{e \sp a} \  {e \sp b}} 
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+This rule would cause infinite rewriting on this if either $a$ or
+$b$ were allowed to match $0$.
+\spadcommand{exprule exp x}
+$$
+e \sp x 
+$$
+\returnType{Type: Expression Integer}
+
+There are occasions when you do want a pattern variable in a sum or
+product to match $0$ or $1$. If so, prefix its name
+with a ``{\tt ?}'' whenever it appears in a left-hand side of a rule.
+For example, consider the following rule for the exponential integral:
+$$\int \left(\frac{y+e^x}{x}\right) dx = 
+\int \frac{y}{x} dx + \hbox{\rm Ei}(x) \quad\forall \, x \hbox{\ and\ } y$$
+This rule is valid for $y = 0$.  One solution is to create a {\tt
+Ruleset} with two rules, one with and one without $y$.  A better
+solution is to use an ``optional'' pattern variable.
+
+Define rule {\tt eirule} with
+a pattern variable $?y$ to indicate
+that an expression may or may not occur.
+\spadcommand{eirule := rule integral((?y + exp x)/x,x) == integral(y/x,x) + Ei x}
+$$
+{\int \sp{\displaystyle x} {{{{e \sp \%M}+y} \over \%M} \  {d \%M}}} 
+\mbox{\rm == } {{{{\tt '}integral} 
+\left(
+{{y \over x}, x} 
+\right)}+{{{\tt
+'}Ei} 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Apply rule {\tt eirule} to an integral without this term.
+\spadcommand{eirule integral(exp u/u, u)}
+$$
+Ei 
+\left(
+{u} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+Apply rule {\tt eirule} to an integral with this term.
+\spadcommand{eirule integral(sin u + exp u/u, u)}
+$$
+{\int \sp{\displaystyle u} {{\sin 
+\left(
+{ \%M} 
+\right)}
+\  {d \%M}}}+{Ei 
+\left(
+{u} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+Here is one final adornment you will find useful.  When matching a
+pattern of the form $x + y$ to an expression containing a long sum of
+the form $a +\ldots+ b$, there is no way to predict in advance which
+subset of the sum matches $x$ and which matches $y$.  Aside from
+efficiency, this is generally unimportant since the rule holds for any
+possible combination of matches for $x$ and $y$.  In some situations,
+however, you may want to say which pattern variable is a sum (or
+product) of several terms, and which should match only a single term.
+To do this, put a prefix colon ``{\tt :}'' before the pattern variable
+that you want to match multiple terms.
+\index{pattern!variable!matching several terms}
+
+The remaining rules involve operators $u$ and $v$. \index{operator}
+\spadcommand{u := operator 'u}
+$$
+u 
+$$
+\returnType{Type: BasicOperator}
+
+These definitions tell Axiom that $u$ and $v$ are formal operators to
+be used in expressions.
+\spadcommand{v := operator 'v}
+$$
+v 
+$$
+\returnType{Type: BasicOperator}
+
+First define {\tt myRule} with no restrictions on the pattern variables
+$x$ and $y$.
+\spadcommand{myRule := rule u(x + y) == u x + v y}
+$$
+{u 
+\left(
+{{y+x}} 
+\right)}
+\mbox{\rm == } {{{{\tt '}v} 
+\left(
+{y} 
+\right)}+{{{\tt
+'}u} 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Apply {\tt myRule} to an expression.
+\spadcommand{myRule u(a + b + c + d)}
+$$
+{v 
+\left(
+{{d+c+b}} 
+\right)}+{u
+\left(
+{a} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+Define {\tt myOtherRule} to match several terms so that the rule gets
+applied recursively.
+\spadcommand{myOtherRule := rule u(:x + y) == u x + v y}
+$$
+{u 
+\left(
+{{y+x}} 
+\right)}
+\mbox{\rm == } {{{{\tt '}v} 
+\left(
+{y} 
+\right)}+{{{\tt
+'}u} 
+\left(
+{x} 
+\right)}}
+$$
+\returnType{Type: RewriteRule(Integer,Integer,Expression Integer)}
+
+Apply {\tt myOtherRule} to the same expression.
+\spadcommand{myOtherRule u(a + b + c + d)}
+$$
+{v 
+\left(
+{c} 
+\right)}+{v
+\left(
+{b} 
+\right)}+{v
+\left(
+{a} 
+\right)}+{u
+\left(
+{d} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Summary of pattern variable adornments:
+\vskip .5\baselineskip
+\begin{tabular}{@{}ll}
+{\tt (x | predicate?(x))} &
+  means that the substutution $s$ for $x$\\ &
+  must satisfy {\tt predicate(s) = true.} \\
+{\tt ?x} &
+  means that $x$ can match an identity \\ & element (0 or 1). \\
+{\tt :x} &
+  means that $x$ can match several terms \\ & in a sum.
+\end{tabular}\\
+}
+
+Here are some final remarks on pattern matching.  Pattern matching
+provides a very useful paradigm for solving certain classes of
+problems, namely, those that involve transformations of one form to
+another and back.  However, it is important to recognize its
+limitations.  \index{pattern!matching!caveats}
+
+First, pattern matching slows down as the number of rules you have to
+apply increases.  Thus it is good practice to organize the sets of
+rules you use optimally so that irrelevant rules are never included.
+
+Second, careless use of pattern matching can lead to wrong answers.
+You should avoid using pattern matching to handle hidden algebraic
+relationships that can go undetected by other programs.  As a simple
+example, a symbol such as ``J'' can easily be used to represent the
+square root of $-1$ or some other important algebraic quantity.  Many
+algorithms branch on whether an expression is zero or not, then divide
+by that expression if it is not.  If you fail to simplify an
+expression involving powers of $J$ to $-1,$ algorithms may incorrectly
+assume an expression is non-zero, take a wrong branch, and produce a
+meaningless result.
+
+Pattern matching should also not be used as a substitute for a domain.
+In Axiom, objects of one domain are transformed to objects of other
+domains using well-defined {\bf coerce} operations.  Pattern matching
+should be used on objects that are all the same type.  Thus if your
+application can be handled by type {\tt Expression} in Axiom and you
+think you need pattern matching, consider this choice carefully.
+\index{Expression} You may well be better served by extending an
+existing domain or by building a new domain of objects for your
+application.
+
+\setcounter{chapter}{6}
+
+\chapter{Graphics}
+\label{ugGraph}
+
+\begin{figure}[htbp]
+\includegraphics{ps/torusknot.ps}
+\caption{Torus knot of type (15,17).}
+\end{figure}
+
+This chapter shows how to use the Axiom graphics facilities
+\index{graphics} under the X Window System.  Axiom has
+two-di\-men\-sion\-al and three-di\-men\-sion\-al drawing and
+rendering packages that allow the drawing, coloring, transforming,
+mapping, clipping, and combining of graphic output from Axiom
+computations.  This facility is particularly useful for investigating
+problems in areas such as topology.  The graphics package is capable
+of plotting functions of one or more variables or plotting parametric
+surfaces and curves.  Various coordinate systems are also available,
+such as polar and spherical.
+
+A graph is displayed in a viewport window and it has a
+\index{viewport} control-panel that uses interactive mouse commands.
+PostScript and other output forms are available so that Axiom
+\index{PostScript} images can be printed or used by other programs.
+
+\section{Two-Dimensional Graphics}
+\label{ugGraphTwoD}
+
+The Axiom two-di\-men\-sion\-al graphics package provides the ability
+to \index{graphics!two-dimensional} display
+\begin{itemize}
+\item curves defined by functions of a single real variable
+\item curves defined by parametric equations
+\item implicit non-singular curves defined by polynomial equations
+\item planar graphs generated from lists of point components.
+\end{itemize}
+
+These graphs can be modified by specifying various options, such as
+calculating points in the polar coordinate system or changing the size
+of the graph viewport window.
+
+\subsection{Plotting Two-Dimensional Functions of One Variable}
+\label{ugGraphTwoDPlot}
+
+\index{curve!one variable function} The first kind of
+two-di\-men\-sion\-al graph is that of a curve defined by a function
+$y = f(x)$ over a finite interval of the $x$ axis.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a function defined by a formula $f(x)$ is:
+\begin{center}
+{\tt draw(f(x), x = a..b, {\it options})}
+\end{center}
+
+where $a..b$ defines the range of $x$, and where {\it options}
+prescribes zero or more options as described in
+\ref{ugGraphTwoDOptions} on page~\pageref{ugGraphTwoDOptions}.  An
+example of an option is $curveColor == bright red().$ An alternative
+format involving functions $f$ and $g$ is also available.\\
+}
+
+A simple way to plot a function is to use a formula.  The first
+argument is the formula.  For the second argument, write the name of
+the independent variable (here, $x$), followed by an ``{\tt =}'', and the
+range of values.
+
+Display this formula over the range $0 \leq x \leq 6$.
+Axiom converts your formula to a compiled function so that the
+results can be computed quickly and efficiently. 
+
+\spadgraph{draw(sin(tan(x)) - tan(sin(x)),x = 0..6)}
+%\begin{figure}[htbp]
+%{\rm draw(sin(tan(x)) - tan(sin(x)),x = 0..6)\\}
+%\vskip 0.2cm
+%\includegraphics{ps/2d1vara.ps}
+%\caption{$sin(tan(x)) - tan(sin(x))\ \ \ x = 0 \ldots6$}
+%\end{figure}
+%{\rm
+%\par
+%Notice that Axiom compiled the function before the graph was put
+%on the screen.
+%
+%Here is the same graph on a different interval.\\
+%
+%draw(sin(tan(x)) - tan(sin(x)),x = 10..16)\\
+%}
+%\vskip 0.2cm
+%\spadgraph{draw(sin(tan(x)) - tan(sin(x)),x = 10..16)}
+%\begin{figure}[htbp]
+%\includegraphics{ps/2d1varb.ps}
+%\caption{$sin(tan(x)) - tan(sin(x))\ \ \ x = 10 \ldots16$}
+%\end{figure}
+
+Once again the formula is converted to a compiled function before any
+points were computed.  If you want to graph the same function on
+several intervals, it is a good idea to define the function first so
+that the function has to be compiled only once.
+
+This time we first define the function.
+\spadcommand{f(x) == (x-1)*(x-2)*(x-3) }
+%\begin{figure}
+%\tpd{0 0 300 300 ps/2d1vard.ps}
+%\end{figure}
+\returnType{Type: Void}
+%\epsffile[14 14 188 199]{ps/2d1vard.ps}
+%\hspace*{\baseLeftSkip}\special{psfile=ps/2dctrl.ps}
+
+To draw the function, the first argument is its name and the second is
+just the range with no independent variable.
+\spadgraph{draw(f, 0..4) }
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2d1vard.ps}
+
+\subsection{Plotting Two-Dimensional Parametric Plane Curves}
+\label{ugGraphTwoDPar}
+
+The second kind of two-di\-men\-sion\-al graph is that of
+\index{parametric plane curve} curves produced by parametric
+equations.  \index{curve!parametric plane} Let $x = f(t)$ and 
+$y = g(t)$ be formulas or two functions $f$ and $g$ as the parameter $t$
+ranges over an interval $[a,b]$.  The function {\bf curve} takes the
+two functions $f$ and $g$ as its parameters.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a two-di\-men\-sion\-al plane curve defined by
+parametric formulas $x = f(t)$ and $y = g(t)$ is:
+\begin{center}
+{\tt draw(curve(f(t), g(t)), t = a..b, {\it options})}
+\end{center}
+
+where $a..b$ defines the range of the independent variable $t$, and
+where {\it options} prescribes zero or more options as described in
+\ref{ugGraphThreeDOptions} on page~\pageref{ugGraphThreeDOptions}.  An
+example of an option is $curveColor == bright red().$\\ }
+
+Here's an example:
+
+Define a parametric curve using a range involving $\%pi$, Axiom's way
+of saying $\pi$.  For parametric curves, Axiom
+compiles two functions, one for each of the functions $f$ and $g$.
+\spadgraph{draw(curve(sin(t)*sin(2*t)*sin(3*t), sin(4*t)*sin(5*t)*sin(6*t)), t = 0..2*\%pi)}
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2dppca.ps}
+
+The title may be an arbitrary string and is an optional argument to
+the {\bf draw} command.
+\spadgraph{draw(curve(cos(t), sin(t)), t = 0..2*\%pi)}
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2dppcb.ps}
+
+If you plan on plotting $x = f(t)$, $y = g(t)$ as $t$ ranges over
+several intervals, you may want to define functions $f$ and $g$ first,
+so that they need not be recompiled every time you create a new graph.
+Here's an example:
+
+As before, you can first define the functions you wish to draw.
+\spadcommand{f(t:DFLOAT):DFLOAT == sin(3*t/4) }
+\begin{verbatim}
+   Function declaration f : DoubleFloat -> DoubleFloat has been 
+      added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Axiom compiles them to map {\tt DoubleFloat} values to {\tt DoubleFloat} 
+values.
+\spadcommand{g(t:DFLOAT):DFLOAT == sin(t) }
+\begin{verbatim}
+   Function declaration f : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Give to {\tt curve} the names of the functions, then write the range
+without the name of the independent variable.
+\spadgraph{draw(curve(f,g),0..\%pi) }
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2dppcc.ps}
+
+Here is another look at the same curve but over a different
+range. Notice that $f$ and $g$ are not recompiled.  Also note that
+Axiom provides a default title based on the first function specified
+in {\bf curve}.
+\spadgraph{draw(curve(f,g),-4*\%pi..4*\%pi) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2dppce.ps}
+
+\subsection{Plotting Plane Algebraic Curves}
+\label{ugGraphTwoDPlane}
+
+A third kind of two-di\-men\-sion\-al graph is a non-singular
+``solution curve'' \index{curve!plane algebraic} in a rectangular
+region of the plane.  A solution curve is a curve defined by a
+polynomial equation $p(x,y) = 0$.  \index{plane algebraic curve}
+Non-singular means that the curve is ``smooth'' in that it does not
+cross itself or come to a point (cusp).  Algebraically, this means
+that for any point $(x,y)$ on the curve, that is, a point such that
+$p(x,y) = 0$, the partial derivatives 
+${{\partial p}\over{\partial x}}(x,y)$ and 
+${{\partial p}\over{\partial y}}(x,y)$ are not both zero.
+\index{curve!smooth} \index{curve!non-singular} \index{smooth curve}
+\index{non-singular curve}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a non-singular solution curve given by
+a polynomial of the form $p(x,y) = 0$ is:
+\begin{center}
+{\tt draw(p(x,y) = 0, x, y, range == [a..b, c..d], {\it options})}
+\end{center}
+
+where the second and third arguments name the first and second
+independent variables of $p$.  A {\tt range} option is always given to
+designate a bounding rectangular region of the plane
+$a \leq x \leq b, c \leq y \leq d$.
+Zero or more additional options as described in
+\ref{ugGraphTwoDOptions} on page~\pageref{ugGraphTwoDOptions} may be given.\\
+}
+
+We require that the polynomial has rational or integral coefficients.
+Here is an algebraic curve example (``Cartesian ovals''):
+\index{Cartesian!ovals}
+\spadcommand{p := ((x**2 + y**2 + 1) - 8*x)**2 - (8*(x**2 + y**2 + 1)-4*x-1) }
+$$
+{y \sp 4}+{{\left( {2 \  {x \sp 2}} -{{16} \  x} -6 
+\right)}
+\  {y \sp 2}}+{x \sp 4} -{{16} \  {x \sp 3}}+{{58} \  {x \sp 2}} -{{12} \  x} 
+-6 
+$$
+\returnType{Type: Polynomial Integer}
+
+The first argument is always expressed as an equation of the form $p = 0$
+where $p$ is a polynomial.
+\spadgraph{draw(p = 0, x, y, range == [-1..11, -7..7]) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2dpaca.ps}
+
+\subsection{Two-Dimensional Options}
+\label{ugGraphTwoDOptions}
+
+The {\bf draw} commands take an optional list of options, such as {\tt
+title} shown above.  Each option is given by the syntax: 
+{\it name} {\tt ==} {\it value}.  
+Here is a list of the available options in the
+order that they are described below.
+
+\begin{tabular}{llll}
+adaptive&clip&unit\\
+clip&curveColor&range\\
+toScale&pointColor&coordinates\\
+\end{tabular}
+
+The $adaptive$ option turns adaptive plotting on or off.
+\index{adaptive plotting} Adaptive plotting uses an algorithm that
+traverses a graph and computes more points for those parts of the
+graph with high curvature.  The higher the curvature of a region is,
+the more points the algorithm computes.  
+\index{graphics!2D options!adaptive}
+
+The {\tt adaptive} option is normally on.  Here we turn it off.
+\spadgraph{draw(sin(1/x),x=-2*\%pi..2*\%pi, adaptive == false)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptad.ps}
+
+The {\tt clip} option turns clipping on or off.  
+\index{graphics!2D options!clipping} 
+If on, large values are cut off according to
+\spadfunFrom{clipPointsDefault}{GraphicsDefaults}.
+
+\spadgraph{draw(tan(x),x=-2*\%pi..2*\%pi, clip == true)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptcp.ps}
+
+Option {\tt toScale} does plotting to scale if {\tt true} or uses the
+entire viewport if {\tt false}.  The default can be determined using
+\spadfunFrom{drawToScale}{GraphicsDefaults}.  
+\index{graphics!2D options!to scale}
+
+\spadgraph{draw(sin(x),x=-\%pi..\%pi, toScale == true, unit == [1.0,1.0])}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptsc.ps}
+
+Option {\tt clip} with a range sets point clipping of a graph within
+the \index{graphics!2D options!clip in a range} ranges specified in
+the list $[x range,y range]$.  \index{clipping} If only one range is
+specified, clipping applies to the y-axis.
+\spadgraph{draw(sec(x),x=-2*\%pi..2*\%pi, clip == [-2*\%pi..2*\%pi,-\%pi..\%pi], unit == [1.0,1.0])}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptcpr.ps}
+
+Option {\tt curveColor} sets the color of the graph curves or lines to
+be the \index{graphics!2D options!curve color} indicated palette color
+\index{curve!color} (see \ref{ugGraphColor} on page~\pageref{ugGraphColor} and
+\ref{ugGraphColorPalette} on page~\pageref{ugGraphColorPalette}).  
+\index{color!curve}
+
+\spadgraph{draw(sin(x),x=-\%pi..\%pi, curveColor == bright red())}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptcvc.ps}
+
+Option {\tt pointColor} sets the color of the graph points to the
+indicated \index{graphics!2D options!point color} palette color (see
+\ref{ugGraphColor} on page~\pageref{ugGraphColor} and 
+\ref{ugGraphColorPalette} on page~\pageref{ugGraphColorPalette}).
+\index{color!point}
+\spadgraph{draw(sin(x),x=-\%pi..\%pi, pointColor == pastel yellow())}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptptc.ps}
+
+Option {\tt unit} sets the intervals at which the axis units are
+plotted \index{graphics!2D options!set units} according to the
+indicated steps [$x$ interval, $y$ interval].
+\spadgraph{draw(curve(9*sin(3*t/4),8*sin(t)), t = -4*\%pi..4*\%pi, unit == [2.0,1.0])}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptut.ps}
+
+Option {\tt range} sets the range of variables in a graph to be within
+the ranges \index{graphics!2D options!range} for solving plane
+algebraic curve plots.
+\spadgraph{draw(y**2 + y - (x**3 - x) = 0, x, y, range == [-2..2,-2..1], unit==[1.0,1.0])}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptrga.ps}
+
+A second example of a solution plot.
+\spadgraph{draw(x**2 + y**2 = 1, x, y, range == [-3/2..3/2,-3/2..3/2], unit==[0.5,0.5])}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptrgb.ps}
+
+Option $coordinates$ indicates the coordinate system in which the
+graph \index{graphics!2D options!coordinates} is plotted.  The default
+is to use the Cartesian coordinate system.
+\index{Cartesian!coordinate system} For more details, see
+\ref{ugGraphCoord} on page~\pageref{ugGraphCoord} 
+{or {\tt CoordinateSystems}.}
+\index{coordinate system!Cartesian}
+
+\spadgraph{draw(curve(sin(5*t),t),t=0..2*\%pi, coordinates == polar)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/2doptplr.ps}
+
+\subsection{Color}
+\label{ugGraphColor}
+
+The domain {\tt Color} \index{Color} provides operations for
+manipulating \index{graphics!color} colors in two-di\-men\-sion\-al
+graphs.  \index{color} Colors are objects of {\tt Color}.  Each color
+has a {\it hue} and a {\it weight}.  \index{hue} Hues are represented
+by integers that range from $1$ to the
+\spadfunFrom{numberOfHues()}{Color}, normally
+\index{graphics!color!number of hues} $27$.  \index{weight} Weights
+are floats and have the value $1.0$ by default.
+
+\begin{description}
+
+\item[{\bf color}]\funArgs{integer}
+creates a color of hue {\it integer} and weight $1.0$.
+
+\item[{\bf hue}]\funArgs{color}
+returns the hue of {\it color} as an integer.
+\index{graphics!color!hue function}
+
+\item[{\bf red}]\funArgs{}
+\funSyntax{blue}{},
+\funSyntax{green}{}, and \funSyntax{yellow}{}
+\index{graphics!color!primary color functions}
+create colors of that hue with weight $1.0$.
+
+\item[$\hbox{\it color}_{1}$ {\tt +} $\hbox{\it color}_{2}$] returns the
+color that results from additively combining the indicated
+$\hbox{\it color}_{1}$ and $\hbox{\it color}_{2}$.
+Color addition is not commutative: changing the order of the arguments
+produces different results.
+
+\item[{\it integer} {\tt *} {\it color}]
+changes the weight of {\it color} by {\it integer}
+without affecting its hue.
+\index{graphics!color!multiply function}
+For example,
+$red() + 3*yellow()$ produces a color closer to yellow than to red.
+Color multiplication is not associative: changing the order of grouping
+\index{color!multiplication}
+produces different results.
+\end{description}
+
+These functions can be used to change the point and curve colors
+for two- and three-di\-men\-sion\-al graphs.
+Use the {\tt pointColor} option for points.
+
+\spadgraph{draw(x**2,x=-1..1,pointColor == green())}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/23dcola.ps}
+
+
+Use the {\tt curveColor} option for curves.
+
+\spadgraph{draw(x**2,x=-1..1,curveColor == color(13) + 2*blue())}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/23dcolb.ps}
+
+\subsection{Palette}
+\label{ugGraphColorPalette}
+\index{graphics!palette}
+
+Domain {\tt Palette} is the domain of shades of colors:
+{\bf dark}, {\bf dim}, {\bf bright}, {\bf pastel}, and {\bf light},
+designated by the integers $1$ through $5$, respectively.
+\index{Palette}
+
+Colors are normally ``bright.''
+
+\spadcommand{shade red()}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+To change the shade of a color, apply the name of a shade to it.
+\index{color!shade}
+\index{shade}
+
+\spadcommand{myFavoriteColor := dark blue() }
+$$
+[{ \mbox{\rm Hue: } {22} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Dark \mbox{\rm palette} 
+$$
+\returnType{Type: Palette}
+
+The expression $shade(color)$
+returns the value of a shade of $color$.
+
+\spadcommand{shade myFavoriteColor }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+The expression $hue(color)$ returns its hue.
+
+\spadcommand{hue myFavoriteColor }
+$$
+\mbox{\rm Hue: } {22} \mbox{\rm Weight: } {1.0} 
+$$
+\returnType{Type: Color}
+
+Palettes can be used in specifying colors in two-di\-men\-sion\-al graphs.
+
+\spadgraph{draw(x**2,x=-1..1,curveColor == dark blue())}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/23dpal.ps}
+
+
+\subsection{Two-Dimensional Control-Panel}
+\label{ugGraphTwoDControl}
+
+\index{graphics!2D control-panel}
+Once you have created a viewport, move your mouse to the viewport and click
+with your left mouse button to display a control-panel.
+The panel is displayed on the side of the viewport closest to
+where you clicked.  Each of the buttons which toggle on and off show the
+current state of the graph.
+
+%\begin{texonly}
+%\typeout{2D control-panel.}
+\begin{figure}[htbp]
+%{\epsfverbosetrue\epsfxsize=2in%
+%\def\epsfsize#1#2{\epsfxsize}\hspace*{\baseLeftSkip}%
+%%\epsffile[0 0 144 289]{ps/2dctrl.ps}}
+%\begin{picture}(147,252)%(-143,0)
+%\hspace*{\baseLeftSkip}\special{psfile=ps/2dctrl.ps}
+%\end{picture}
+\caption{Two-dimensional control-panel.}
+\end{figure}
+%\end{texonly}
+
+\subsubsection{Transformations}
+\index{graphics!2D control-panel!transformations}
+
+Object transformations are executed from the control-panel by mouse-activated
+potentiometer windows.
+%
+\begin{description}
+%
+\item[Scale:] To scale a graph, click on a mouse button
+\index{graphics!2D control-panel!scale}
+within the {\bf Scale} window in the upper left corner of the control-panel.
+The axes along which the scaling is to occur are indicated by setting the
+toggles above the arrow.
+With {\tt X On} and {\tt Y On} appearing, both axes are selected and scaling
+is uniform.
+If either is not selected, for example, if {\tt X Off} appears, scaling is
+non-uniform.
+%
+\item[Translate:] To translate a graph, click the mouse in the
+\index{graphics!2D control-panel!translate}
+{\bf Translate} window in the direction you wish the graph to move.
+This window is located in the upper right corner of the control-panel.
+Along the top of the {\bf Translate} window are two buttons for selecting
+the direction of translation.
+Translation along both coordinate axes results when {\tt X On} and {\tt Y
+On} appear or along one axis when one is on, for example, {\tt X On} and
+{\tt Y Off} appear.
+\end{description}
+
+\subsubsection{Messages}
+\index{graphics!2D control-panel!messages}
+
+The window directly below the transformation potentiometer windows is
+used to display system messages relating to the viewport and the control-panel.
+The following format is displayed: \newline
+%
+\begin{center}
+[scaleX, scaleY] $>$graph$<$ [translateX, translateY] \newline
+\end{center}
+The two values to the left show the scale factor along the {\tt X} and
+{\tt Y} coordinate axes.  The two values to the right show the distance of
+translation from the center in the {\tt X} and {\tt Y} directions.  The number
+in the center shows which graph in the viewport this data pertains to.
+When multiple graphs exist in the same viewport,
+the graph must be selected (see ``Multiple Graphs,'' below) in
+order for its transformation data to be shown, otherwise the number
+is 1.
+
+\subsubsection{Multiple Graphs}
+
+\index{graphics!2D control-panel!multiple graphs}
+The {\bf Graphs} window contains buttons that allow the placement
+of two-di\-men\-sion\-al graphs into one of nine available slots in any other
+two-di\-men\-sion\-al viewport.
+In the center of the window are numeral buttons from one to nine
+that show whether a graph is displayed in the viewport.
+Below each number button is a button showing whether a graph
+that is present is selected for application of some
+transformation.
+When the caret symbol is displayed, then the graph in that slot
+will be manipulated.
+Initially, the graph for which the viewport is created occupies
+the first slot, is displayed, and is selected.
+%
+%
+\begin{description}
+%
+\item[Clear:]  The {\bf Clear} button deselects every viewport graph slot.
+\index{graphics!2D control-panel!clear}
+A graph slot is reselected by selecting the button below its number.
+%
+\item[Query:]  The {\bf Query} button is used to display the scale and
+\index{graphics!2D control-panel!query}
+translate data for the indicated graph.  When this button is selected the
+message ``Click on the graph to query'' appears.  Select a slot
+number button from the {\bf Graphs} window. The scaling factor and translation
+offset of the graph are then displayed in the message window.
+%
+\item[Pick:]  The {\bf Pick} button is used to select a graph
+\index{graphics!2D control-panel!pick}
+to be placed or dropped into the indicated viewport.  When this button is
+selected, the message ``Click on the graph to pick'' appears.
+Click on the slot with the graph number of the desired
+graph.  The graph information is held waiting for
+you to execute a {\bf Drop} in some other graph.
+%
+\item[Drop:]  Once a graph has been picked up using the {\bf Pick} button,
+\index{graphics!2D control-panel!drop}
+the {\bf Drop} button places it into a new viewport slot.
+The message ``Click on the graph to drop'' appears in the message
+window when the {\bf Drop} button is selected.
+By selecting one of the slot number buttons in the {\bf Graphs}
+window, the graph currently being held is dropped into this slot
+and displayed.
+\end{description}
+
+\subsubsection{Buttons}
+\index{graphics!2D control-panel!buttons}
+
+%
+\begin{description}
+%
+\item[Axes] turns the coordinate axes on or off.
+\index{graphics!2D control-panel!axes}
+%
+\item[Units] turns the units along the {\tt x}
+and {\tt y} axis on or off.
+\index{graphics!2D control-panel!units}
+%
+\item[Box] encloses the area of the viewport graph
+in a bounding box, or removes the box if already enclosed.
+\index{graphics!2D control-panel!box}
+%
+\item[Pts] turns on or off the display of points.
+\index{graphics!2D control-panel!points}
+%
+\item[Lines] turns on or off the display
+of lines connecting points.
+\index{graphics!2D control-panel!lines}
+%
+\item[PS] writes the current viewport contents to
+\index{graphics!2D control-panel!ps}
+a file {\bf axiom2d.ps} or to a name specified in the user's {\bf
+\index{graphics!.Xdefaults!PostScript file name}
+.Xdefaults} file.
+\index{file!.Xdefaults @{\bf .Xdefaults}}
+The file is placed in the directory from which Axiom or the {\bf
+viewalone} program was invoked.
+\index{PostScript}
+%
+\item[Reset] resets the object transformation
+characteristics and attributes back to their initial states.
+\index{graphics!2D control-panel!reset}
+%
+\item[Hide] makes the control-panel disappear.
+\index{graphics!2D control-panel!hide}
+%
+\item[Quit] queries whether the current viewport
+\index{graphics!2D control-panel!quit}
+session should be terminated.
+\end{description}
+
+\subsection{Operations for Two-Dimensional Graphics}
+\label{ugGraphTwoDops}
+
+Here is a summary of useful Axiom operations for two-di\-men\-sion\-al
+graphics.
+Each operation name is followed by a list of arguments.
+Each argument is written as a variable informally named according
+to the type of the argument (for example, {\it integer}).
+If appropriate, a default value for an argument is given in
+parentheses immediately following the name.
+
+%
+\begin{description}
+%
+\item[{\bf adaptive}]\funArgs{\optArg{boolean\argDef{true}}}
+\index{adaptive plotting}
+sets or indicates whether graphs are plotted
+\index{graphics!set 2D defaults!adaptive}
+according to the adaptive refinement algorithm.
+%
+\item[{\bf axesColorDefault}]\funArgs{\optArg{color\argDef{dark blue()}}}
+sets or indicates the default color of the
+\index{graphics!set 2D defaults!axes color}
+axes in a two-di\-men\-sion\-al graph viewport.
+%
+\item[{\bf clipPointsDefault}]\funArgs{\optArg{boolean\argDef{false}}}
+sets or
+indicates whether point clipping is
+\index{graphics!set 2D defaults!clip points}
+to be applied as the default for graph plots.
+%
+\item[{\bf drawToScale}]\funArgs{\optArg{boolean\argDef{false}}}
+sets or
+indicates whether the plot of a graph
+\index{graphics!set 2D defaults!to scale}
+is ``to scale'' or uses the entire viewport space as the default.
+%
+\item[{\bf lineColorDefault}]\funArgs{\optArg{color\argDef{pastel yellow()}}}
+sets or indicates the default color of the
+\index{graphics!set 2D defaults!line color}
+lines or curves in a two-di\-men\-sion\-al graph viewport.
+%
+\item[{\bf maxPoints}]\funArgs{\optArg{integer\argDef{500}}}
+sets or indicates
+the default maximum number of
+\index{graphics!set 2D defaults!max points}
+possible points to be used when constructing a two-di\-men\-sion\-al graph.
+%
+\item[{\bf minPoints}]\funArgs{\optArg{integer\argDef{21}}}
+sets or indicates the default minimum number of
+\index{graphics!set 2D defaults!min points}
+possible points to be used when constructing a two-di\-men\-sion\-al graph.
+%
+\item[{\bf pointColorDefault}]\funArgs{\optArg{color\argDef{bright red()}}}
+sets or indicates the default color of the
+\index{graphics!set 2D defaults!point color}
+points in a two-di\-men\-sion\-al graph viewport.
+%
+\item[{\bf pointSizeDefault}]\funArgs{\optArg{integer\argDef{5}}}
+sets or indicates the default size of the
+\index{graphics!set 2D defaults!point size}
+dot used to plot points in a two-di\-men\-sion\-al graph.
+%
+\item[{\bf screenResolution}]\funArgs{\optArg{integer\argDef{600}}}
+sets or indicates the default screen
+\index{graphics!set 2D defaults!screen resolution}
+resolution constant used in setting the computation limit of adaptively
+\index{adaptive plotting}
+generated curve plots.
+%
+\item[{\bf unitsColorDefault}]\funArgs{\optArg{color\argDef{dim green()}}}
+sets or indicates the default color of the
+\index{graphics!set 2D defaults!units color}
+unit labels in a two-di\-men\-sion\-al graph viewport.
+%
+\item[{\bf viewDefaults}]\funArgs{}
+resets the default settings for the following
+\index{graphics!set 2D defaults!reset viewport}
+attributes:  point color, line color, axes color, units color, point size,
+viewport upper left-hand corner position, and the viewport size.
+%
+\item[{\bf viewPosDefault}]\funArgs{\optArg{list\argDef{[100,100]}}}
+sets or indicates the default position of the
+\index{graphics!set 2D defaults!viewport position}
+upper left-hand corner of a two-di\-men\-sion\-al viewport, relative to the
+display root window.
+The upper left-hand corner of the display is considered to be at the
+(0, 0) position.
+%
+\item[{\bf viewSizeDefault}]\funArgs{\optArg{list\argDef{[200,200]}}}
+sets or
+indicates the default size in which two
+\index{graphics!set 2D defaults!viewport size}
+dimensional viewport windows are shown.
+It is defined by a width and then a height.
+%
+\item[{\bf viewWriteAvailable}]
+\funArgs{\optArg{list\argDef{["pixmap","bitmap", "postscript", "image"]}}}
+indicates the possible file types
+\index{graphics!2D defaults!available viewport writes}
+that can be created with the \spadfunFrom{write}{TwoDimensionalViewport} function.
+%
+\item[{\bf viewWriteDefault}]\funArgs{\optArg{list\argDef{[]}}}
+sets or indicates the default types of files, in
+\index{graphics!set 2D defaults!write viewport}
+addition to the {\bf data} file, that are created when a
+{\bf write} function is executed on a viewport.
+%
+\item[{\bf units}]\funArgs{viewport, integer\argDef{1}, string\argDef{"off"}}
+turns the units on or off for the graph with index {\it integer}.
+%
+\item[{\bf axes}]\funArgs{viewport, integer\argDef{1}, string\argDef{"on"}}
+turns the axes on
+\index{graphics!2D commands!axes}
+or off for the graph with index {\it integer}.
+%
+\item[{\bf close}]\funArgs{viewport}
+closes {\it viewport}.
+\index{graphics!2D commands!close}
+%
+\item[{\bf connect}]\funArgs{viewport, integer\argDef{1}, string\argDef{"on"}}
+declares whether lines
+\index{graphics!2D commands!connect}
+connecting the points are displayed or not.
+%
+\item[{\bf controlPanel}]\funArgs{viewport, string\argDef{"off"}}
+declares
+whether the two-di\-men\-sion\-al control-panel is automatically displayed
+or not.
+%
+\item[{\bf graphs}]\funArgs{viewport}
+returns a list
+\index{graphics!2D commands!graphs}
+describing the state of each graph.
+If the graph state is not being used this is shown by {\tt "undefined"},
+otherwise a description of the graph's contents is shown.
+%
+\item[{\bf graphStates}]\funArgs{viewport}
+displays
+\index{graphics!2D commands!state of graphs}
+a list of all the graph states available for {\it viewport}, giving the
+values for every property.
+%
+\item[{\bf key}]\funArgs{viewport}
+returns the process
+\index{graphics!2D commands!key}
+ID number for {\it viewport}.
+%
+\item[{\bf move}]\funArgs{viewport,
+$integer_{x}$(viewPosDefault),
+$integer_{y}$(viewPosDefault)}
+moves {\it viewport} on the screen so that the
+\index{graphics!2D commands!move}
+upper left-hand corner of {\it viewport} is at the position {\it (x,y)}.
+%
+\item[{\bf options}]\funArgs{\it viewport}
+returns a list
+\index{graphics!2D commands!options}
+of all the {\tt DrawOption}s used by {\it viewport}.
+%
+\item[{\bf points}]\funArgs{viewport, integer\argDef{1}, string\argDef{"on"}}
+specifies whether the graph points for graph {\it integer} are
+\index{graphics!2D commands!points}
+to be displayed or not.
+%
+\item[{\bf region}]\funArgs{viewport, integer\argDef{1}, string\argDef{"off"}}
+declares whether graph {\it integer} is or is not to be displayed
+with a bounding rectangle.
+%
+\item[{\bf reset}]\funArgs{viewport}
+resets all the properties of {\it viewport}.
+%
+\item[{\bf resize}]\funArgs{viewport,
+$integer_{width}$,$integer_{height}$}
+\index{graphics!2D commands!resize}
+resizes {\it viewport} with a new {\it width} and {\it height}.
+%
+\item[{\bf scale}]\funArgs{viewport, $integer_{n}$\argDef{1},
+$integer_{x}$\argDef{0.9}, $integer_{y}$\argDef{0.9}}
+scales values for the
+\index{graphics!2D commands!scale}
+{\it x} and {\it y} coordinates of graph {\it n}.
+%
+\item[{\bf show}]\funArgs{viewport, $integer_{n}$\argDef{1},
+string\argDef{"on"}}
+indicates if graph {\it n} is shown or not.
+%
+\item[{\bf title}]\funArgs{viewport, string\argDef{"Axiom 2D"}}
+designates the title for {\it viewport}.
+%
+\item[{\bf translate}]\funArgs{viewport,
+$integer_{n}$\argDef{1},
+$float_{x}$\argDef{0.0}, $float_{y}$\argDef{0.0}}
+\index{graphics!2D commands!translate}
+causes graph {\it n} to be moved {\it x} and {\it y} units in the respective directions.
+%
+\item[{\bf write}]\funArgs{viewport, $string_{directory}$,
+\optArg{strings}}
+if no third argument is given, writes the {\bf data} file onto the directory
+with extension {\bf data}.
+The third argument can be a single string or a list of strings with some or
+all the entries {\tt "pixmap"}, {\tt "bitmap"}, {\tt "postscript"}, and
+{\tt "image"}.
+\end{description}
+
+\subsection{Addendum: Building Two-Dimensional Graphs}
+\label{ugGraphTwoDbuild}
+
+In this section we demonstrate how to create two-di\-men\-sion\-al graphs from
+lists of points and give an example showing how to read the lists
+of points from a file.
+
+\subsubsection{Creating a Two-Dimensional Viewport from a List of Points}
+
+Axiom creates lists of points in a two-di\-men\-sion\-al viewport by utilizing
+the {\tt GraphImage} and {\tt TwoDimensionalViewport} domains.
+In this example, the \spadfunFrom{makeGraphImage}{GraphImage}
+function takes a list of lists of points parameter, a list of colors for
+each point in the graph, a list of colors for each line in the graph, and
+a list of sizes for each point in the graph.
+%
+
+The following expressions create a list of lists of points which will be read
+by Axiom and made into a two-di\-men\-sion\-al viewport.
+
+\spadcommand{p1 := point [1,1]\$(Point DFLOAT) }
+$$
+\left[
+{1.0},  {1.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p2 := point [0,1]\$(Point DFLOAT) }
+$$
+\left[
+{0.0},  {1.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p3 := point [0,0]\$(Point DFLOAT) }
+$$
+\left[
+{0.0},  {0.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p4 := point [1,0]\$(Point DFLOAT) }
+$$
+\left[
+{1.0},  {0.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p5 := point [1,.5]\$(Point DFLOAT) }
+$$
+\left[
+{1.0},  {0.5} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p6 := point [.5,0]\$(Point DFLOAT) }
+$$
+\left[
+{0.5},  {0.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p7 := point [0,0.5]\$(Point DFLOAT) }
+$$
+\left[
+{0.0},  {0.5} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p8 := point [.5,1]\$(Point DFLOAT) }
+$$
+\left[
+{0.5},  {1.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p9 := point [.25,.25]\$(Point DFLOAT) }
+$$
+\left[
+{0.25},  {0.25} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p10 := point [.25,.75]\$(Point DFLOAT) }
+$$
+\left[
+{0.25},  {0.75} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p11 := point [.75,.75]\$(Point DFLOAT) }
+$$
+\left[
+{0.75},  {0.75} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p12 := point [.75,.25]\$(Point DFLOAT) }
+$$
+\left[
+{0.75},  {0.25} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+Finally, here is the list.
+
+\spadcommand{llp := [ [p1,p2], [p2,p3], [p3,p4], [p4,p1], [p5,p6], [p6,p7], [p7,p8], [p8,p5], [p9,p10], [p10,p11], [p11,p12], [p12,p9] ]  }
+$$
+\left[
+{\left[ {\left[ {1.0},  {1.0} 
+\right]},
+ {\left[ {0.0},  {1.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.0},  {1.0} 
+\right]},
+ {\left[ {0.0},  {0.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.0},  {0.0} 
+\right]},
+ {\left[ {1.0},  {0.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {1.0},  {0.0} 
+\right]},
+ {\left[ {1.0},  {1.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {1.0},  {0.5} 
+\right]},
+ {\left[ {0.5},  {0.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.5},  {0.0} 
+\right]},
+ {\left[ {0.0},  {0.5} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.0},  {0.5} 
+\right]},
+ {\left[ {0.5},  {1.0} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.5},  {1.0} 
+\right]},
+ {\left[ {1.0},  {0.5} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.25},  {0.25} 
+\right]},
+ {\left[ {0.25},  {0.75} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.25},  {0.75} 
+\right]},
+ {\left[ {0.75},  {0.75} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.75},  {0.75} 
+\right]},
+ {\left[ {0.75},  {0.25} 
+\right]}
+\right]},
+ {\left[ {\left[ {0.75},  {0.25} 
+\right]},
+ {\left[ {0.25},  {0.25} 
+\right]}
+\right]}
+\right]
+$$
+\returnType{Type: List List Point DoubleFloat}
+
+Now we set the point sizes for all components of the graph.
+
+\spadcommand{size1 := 6::PositiveInteger }
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{size2 := 8::PositiveInteger }
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{size3 := 10::PositiveInteger }
+
+\spadcommand{lsize := [size1, size1, size1, size1, size2, size2, size2, size2, size3, size3, size3, size3]  }
+$$
+\left[
+6,  6,  6,  6,  8,  8,  8,  8,  size3,  size3,  size3,  
+size3 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+Here are the colors for the points.
+
+\spadcommand{pc1 := pastel red() }
+$$
+[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Pastel \mbox{\rm palette} 
+$$
+\returnType{Type: Palette}
+
+\spadcommand{pc2 := dim green() }
+$$
+[{ \mbox{\rm Hue: } {14} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Dim \mbox{\rm palette} 
+$$
+\returnType{Type: Palette}
+
+\spadcommand{pc3 := pastel yellow() }
+$$
+[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Pastel \mbox{\rm palette} 
+$$
+\returnType{Type: Palette}
+
+\spadcommand{lpc := [pc1, pc1, pc1, pc1, pc2, pc2, pc2, pc2, pc3, pc3, pc3, pc3]  }
+$$
+\left[
+{[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } 
+{1.0}} \mbox{\rm ] from the } Pastel \mbox{\rm palette} },  {[{ \mbox{\rm 
+Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Pastel \mbox{\rm 
+palette} },  {[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] 
+from the } Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {14} 
+\mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Dim \mbox{\rm palette} }, 
+ {[{ \mbox{\rm Hue: } {14} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the 
+} Dim \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {14} \mbox{\rm Weight: } 
+{1.0}} \mbox{\rm ] from the } Dim \mbox{\rm palette} },  {[{ \mbox{\rm Hue: 
+} {14} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Dim \mbox{\rm 
+palette} },  {[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } {1.0}} \mbox{\rm 
+] from the } Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {11} 
+\mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Pastel \mbox{\rm palette} 
+},  {[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from 
+the } Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {11} \mbox{\rm 
+Weight: } {1.0}} \mbox{\rm ] from the } Pastel \mbox{\rm palette} } 
+\right]
+$$
+\returnType{Type: List Palette}
+
+Here are the colors for the lines.
+
+\spadcommand{lc := [pastel blue(), light yellow(), dim green(), bright red(), light green(), dim yellow(), bright blue(), dark red(), pastel red(), light blue(), dim green(), light yellow()] }
+$$
+\left[
+{[{ \mbox{\rm Hue: } {22} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } 
+Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } 
+{1.0}} \mbox{\rm ] from the } Light \mbox{\rm palette} },  {[{ \mbox{\rm 
+Hue: } {14} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Dim \mbox{\rm 
+palette} },  {[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] 
+from the } Bright \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {14} 
+\mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Light \mbox{\rm palette} }, 
+ {[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the 
+} Dim \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {22} \mbox{\rm Weight: } 
+{1.0}} \mbox{\rm ] from the } Bright \mbox{\rm palette} },  {[{ \mbox{\rm 
+Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Dark \mbox{\rm 
+palette} },  {[{ \mbox{\rm Hue: } 1 \mbox{\rm Weight: } {1.0}} \mbox{\rm ] 
+from the } Pastel \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {22} 
+\mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the } Light \mbox{\rm palette} }, 
+ {[{ \mbox{\rm Hue: } {14} \mbox{\rm Weight: } {1.0}} \mbox{\rm ] from the 
+} Dim \mbox{\rm palette} },  {[{ \mbox{\rm Hue: } {11} \mbox{\rm Weight: } 
+{1.0}} \mbox{\rm ] from the } Light \mbox{\rm palette} } 
+\right]
+$$
+\returnType{Type: List Palette}
+
+Now the {\tt GraphImage} is created according to the component
+specifications indicated above.
+
+\spadcommand{g := makeGraphImage(llp,lpc,lc,lsize)\$GRIMAGE  }
+
+The \spadfunFrom{makeViewport2D}{TwoDimensionalViewport} function now
+creates a {\tt TwoDimensionalViewport} for this graph according to the
+list of options specified within the brackets.
+
+\spadgraph{makeViewport2D(g,[title("Lines")])\$VIEW2D }
+
+%See Figure #.#.
+
+This example demonstrates the use of the {\tt GraphImage} functions
+\spadfunFrom{component}{GraphImage} and \spadfunFrom{appendPoint}{GraphImage}
+in adding points to an empty {\tt GraphImage}.
+
+\spadcommand{)clear all }
+
+\spadcommand{g := graphImage()\$GRIMAGE }
+$$
+\mbox{\rm Graph with } 0 \mbox{\rm point lists} 
+$$
+\returnType{Type: GraphImage}
+
+\spadcommand{p1 := point [0,0]\$(Point DFLOAT) }
+$$
+\left[
+{0.0},  {0.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p2 := point [.25,.25]\$(Point DFLOAT) }
+$$
+\left[
+{0.25},  {0.25} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p3 := point [.5,.5]\$(Point DFLOAT) }
+$$
+\left[
+{0.5},  {0.5} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p4 := point [.75,.75]\$(Point DFLOAT) }
+$$
+\left[
+{0.75},  {0.75} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{p5 := point [1,1]\$(Point DFLOAT) }
+$$
+\left[
+{1.0},  {1.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{component(g,p1)\$GRIMAGE}
+\returnType{Type: Void}
+
+\spadcommand{component(g,p2)\$GRIMAGE}
+\returnType{Type: Void}
+
+\spadcommand{appendPoint(g,p3)\$GRIMAGE}
+\returnType{Type: Void}
+
+\spadcommand{appendPoint(g,p4)\$GRIMAGE}
+\returnType{Type: Void}
+
+\spadcommand{appendPoint(g,p5)\$GRIMAGE}
+\returnType{Type: Void}
+
+\spadcommand{g1 := makeGraphImage(g)\$GRIMAGE  }
+
+Here is the graph.
+
+\spadgraph{makeViewport2D(g1,[title("Graph Points")])\$VIEW2D }
+
+%
+%See Figure #.#.
+%
+
+A list of points can also be made into a {\tt GraphImage} by using
+the operation \spadfunFrom{coerce}{GraphImage}.  It is equivalent to adding
+each point to $g2$ using \spadfunFrom{component}{GraphImage}.
+
+\spadcommand{g2 := coerce([ [p1],[p2],[p3],[p4],[p5] ])\$GRIMAGE   }
+
+Now, create an empty {\tt TwoDimensionalViewport}.
+
+\spadcommand{v := viewport2D()\$VIEW2D }
+
+\spadcommand{options(v,[title("Just Points")])\$VIEW2D }
+
+Place the graph into the viewport.
+
+\spadcommand{putGraph(v,g2,1)\$VIEW2D }
+
+Take a look.
+
+\spadgraph{makeViewport2D(v)\$VIEW2D }
+
+%See Figure #.#.
+
+\subsubsection{Creating a Two-Dimensional Viewport of a List of Points from a File}
+
+The following three functions read a list of points from a
+file and then draw the points and the connecting lines. The
+points are stored in the file in readable form as floating point numbers
+(specifically, {\tt DoubleFloat} values) as an alternating
+stream of $x$- and $y$-values. For example,
+\begin{verbatim}
+0.0 0.0     1.0 1.0     2.0 4.0
+3.0 9.0     4.0 16.0    5.0 25.0
+\end{verbatim}
+
+\begin{verbatim}
+drawPoints(lp:List Point DoubleFloat):VIEW2D ==
+  g := graphImage()$GRIMAGE
+  for p in lp repeat
+    component(g,p,pointColorDefault(),lineColorDefault(),
+      pointSizeDefault())
+  gi := makeGraphImage(g)$GRIMAGE
+  makeViewport2D(gi,[title("Points")])$VIEW2D
+
+drawLines(lp:List Point DoubleFloat):VIEW2D ==
+  g := graphImage()$GRIMAGE
+  component(g, lp, pointColorDefault(), lineColorDefault(),
+    pointSizeDefault())$GRIMAGE
+  gi := makeGraphImage(g)$GRIMAGE
+  makeViewport2D(gi,[title("Points")])$VIEW2D
+
+plotData2D(name, title) ==
+  f:File(DFLOAT) := open(name,"input")
+  lp:LIST(Point DFLOAT) := empty()
+  while ((x := readIfCan!(f)) case DFLOAT) repeat
+    y : DFLOAT := read!(f)
+    lp := cons(point [x,y]$(Point DFLOAT), lp)
+    lp
+  close!(f)
+  drawPoints(lp)
+  drawLines(lp)
+\end{verbatim}
+%
+This command will actually create the viewport and the graph if
+the point data is in the file $"file.data"$.
+\begin{verbatim}
+plotData2D("file.data", "2D Data Plot")
+\end{verbatim}
+
+\subsection{Addendum: Appending a Graph to a Viewport Window Containing a Graph}
+\label{ugGraphTwoDappend}
+
+This section demonstrates how to append a two-di\-men\-sion\-al graph to a viewport
+already containing other graphs.
+The default {\bf draw} command places a graph into the first
+{\tt GraphImage} slot position of the {\tt TwoDimensionalViewport}.
+
+This graph is in the first slot in its viewport.
+
+\spadcommand{v1 := draw(sin(x),x=0..2*\%pi) }
+
+So is this graph.
+
+\spadcommand{v2 := draw(cos(x),x=0..2*\%pi, curveColor==light red()) }
+
+The operation \spadfunFrom{getGraph}{TwoDimensionalViewport}
+retrieves the {\tt GraphImage} $g1$ from the first slot position
+in the viewport $v1$.
+
+\spadcommand{g1 := getGraph(v1,1) }
+
+Now \spadfunFrom{putGraph}{TwoDimensionalViewport}
+places $g1$ into the the second slot position of $v2$.
+
+\spadcommand{putGraph(v2,g1,2) }
+
+Display the new {\tt TwoDimensionalViewport} containing both graphs.
+
+\spadgraph{makeViewport2D(v2) }
+
+%
+%See Figure #.#.
+%
+
+\section{Three-Dimensional Graphics}
+\label{ugGraphThreeD}
+
+%
+The Axiom three-di\-men\-sion\-al graphics package provides the ability to
+\index{graphics!three-dimensional}
+%
+\begin{itemize}
+%
+\item generate surfaces defined by a function of two real variables
+%
+\item generate space curves and tubes defined by parametric equations
+%
+\item generate surfaces defined by parametric equations
+\end{itemize}
+These graphs can be modified by using various options, such as calculating
+points in the spherical coordinate system or changing the polygon grid size
+of a surface.
+
+\subsection{Plotting Three-Dimensional Functions of Two Variables}
+\label{ugGraphThreeDPlot}
+
+\index{surface!two variable function}
+The simplest three-di\-men\-sion\-al graph is that of a surface defined by a function
+of two variables, $z = f(x,y)$.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a surface defined by a formula $f(x,y)$
+of two variables $x$ and $y$ is:
+%
+\begin{center}
+{\tt draw(f(x,y), x = a..b, y = c..d, {\it options})}
+\end{center}
+where $a..b$ and $c..d$ define the range of $x$
+and $y$, and where {\it options} prescribes zero or more
+options as described in \ref{ugGraphThreeDOptions} 
+on page~\pageref{ugGraphThreeDOptions}.
+An example of an option is $title == "Title of Graph".$
+An alternative format involving a function $f$ is also
+available.\\
+}
+
+The simplest way to plot a function of two variables is to use a formula.
+With formulas you always precede the range specifications with
+the variable name and an {\tt =} sign.
+
+\spadgraph{draw(cos(x*y),x=-3..3,y=-3..3)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3d2vara.ps}
+
+If you intend to use a function more than once,
+or it is long and complex, then first
+give its definition to Axiom.
+
+\spadcommand{f(x,y) == sin(x)*cos(y) }
+\returnType{Type: Void}
+
+To draw the function, just give its name and drop the variables
+from the range specifications.
+Axiom compiles your function for efficient computation
+of data for the graph.
+Notice that Axiom uses the text of your function as a
+default title.
+
+\spadgraph{draw(f,-\%pi..\%pi,-\%pi..\%pi) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3d2varb.ps}
+
+\subsection{Plotting Three-Dimensional Parametric Space Curves}
+\label{ugGraphThreeDParm}
+
+
+A second kind of three-di\-men\-sion\-al graph is a three-di\-men\-sion\-al space curve
+\index{curve!parametric space}
+defined by the parametric equations for $x(t)$, $y(t)$,
+\index{parametric space curve}
+and $z(t)$ as a function of an independent variable $t$.
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a three-di\-men\-sion\-al space curve defined by
+parametric formulas $x = f(t)$, $y = g(t)$, and
+$z = h(t)$ is:
+%
+\begin{center}
+{\tt draw(curve(f(t),g(t),h(t)), t = a..b, {\it options})}
+\end{center}
+where $a..b$ defines the range of the independent variable
+$t$, and where {\it options} prescribes zero or more options
+as described in \ref{ugGraphThreeDOptions} 
+on page~\pageref{ugGraphThreeDOptions}.
+An example of an option is $title == "Title of Graph".$
+An alternative format involving functions $f$, $g$ and
+$h$ is also available.\\
+}
+
+If you use explicit formulas to draw a space curve, always precede
+the range specification with the variable name and an
+{\tt =} sign.
+
+\spadgraph{draw(curve(5*cos(t), 5*sin(t),t), t=-12..12)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dpsca.ps}
+
+Alternatively, you can draw space curves by referring to functions.
+
+\spadcommand{i1(t:DFLOAT):DFLOAT == sin(t)*cos(3*t/5) }
+\begin{verbatim}
+   Function declaration i1 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+This is useful if the functions are to be used more than once \ldots
+
+\spadcommand{i2(t:DFLOAT):DFLOAT == cos(t)*cos(3*t/5) }
+\begin{verbatim}
+   Function declaration i2 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+or if the functions are long and complex.
+
+\spadcommand{i3(t:DFLOAT):DFLOAT == cos(t)*sin(3*t/5) }
+\begin{verbatim}
+   Function declaration i3 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Give the names of the functions and
+drop the variable name specification in the second argument.
+Again, Axiom supplies a default title.
+
+\spadgraph{draw(curve(i1,i2,i3),0..15*\%pi) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dpscb.ps}
+
+\subsection{Plotting Three-Dimensional Parametric Surfaces}
+\label{ugGraphThreeDPar}
+
+\index{surface!parametric}
+A third kind of three-di\-men\-sion\-al graph is a surface defined by
+\index{parametric surface}
+parametric equations for $x(u,v)$, $y(u,v)$, and
+$z(u,v)$ of two independent variables $u$ and $v$.
+
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The general format for drawing a three-di\-men\-sion\-al graph defined by
+parametric formulas $x = f(u,v)$, $y = g(u,v)$,
+and $z = h(u,v)$ is:
+%
+\begin{center}
+{\tt draw(surface(f(u,v),g(u,v),h(u,v)), u = a..b, v = c..d, {\it options})}
+\end{center}
+where $a..b$ and $c..d$ define the range of the
+independent variables $u$ and $v$, and where
+{\it options} prescribes zero or more options as described in
+\ref{ugGraphThreeDOptions} on page~\pageref{ugGraphThreeDOptions}.
+An example of an option is $title == "Title of Graph".$
+An alternative format involving functions $f$, $g$ and
+$h$ is also available.\\
+}
+
+This example draws a graph of a surface plotted using the
+parabolic cylindrical coordinate system option.
+\index{coordinate system!parabolic cylindrical}
+The values of the functions supplied to {\bf surface} are
+\index{parabolic cylindrical coordinate system}
+interpreted in coordinates as given by a {\tt coordinates} option,
+here as parabolic cylindrical coordinates (see
+\ref{ugGraphCoord} on page~\pageref{ugGraphCoord}).
+
+\spadgraph{draw(surface(u*cos(v), u*sin(v), v*cos(u)), u=-4..4, v=0..\%pi, coordinates== parabolicCylindrical)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dpsa.ps}
+
+Again, you can graph these parametric surfaces using functions,
+if the functions are long and complex.
+
+Here we declare the types of arguments and values to be of type
+{\tt DoubleFloat}.
+
+\spadcommand{n1(u:DFLOAT,v:DFLOAT):DFLOAT == u*cos(v) }
+\begin{verbatim}
+   Function declaration n1 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+As shown by previous examples, these declarations are necessary.
+
+\spadcommand{n2(u:DFLOAT,v:DFLOAT):DFLOAT == u*sin(v) }
+\begin{verbatim}
+   Function declaration n2 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+In either case, Axiom compiles the functions
+when needed to graph a result.
+
+\spadcommand{n3(u:DFLOAT,v:DFLOAT):DFLOAT == u }
+\begin{verbatim}
+   Function declaration n3 : DoubleFloat -> DoubleFloat has been added 
+      to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Without these declarations, you have to suffix floats
+with $@DFLOAT$ to get a {\tt DoubleFloat} result.
+However, a call here with an unadorned float produces a {\tt DoubleFloat}.
+
+\spadcommand{n3(0.5,1.0)}
+\begin{verbatim}
+   Compiling function n3 with type (DoubleFloat,DoubleFloat) -> 
+      DoubleFloat 
+\end{verbatim}
+\returnType{Type: DoubleFloat}
+
+Draw the surface by referencing the function names, this time
+choosing the toroidal coordinate system.
+\index{coordinate system!toroidal}
+\index{toroidal coordinate system}
+
+\spadgraph{draw(surface(n1,n2,n3), 1..4, 1..2*\%pi, coordinates == toroidal(1\$DFLOAT)) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dpsb.ps}
+
+\subsection{Three-Dimensional Options}
+\label{ugGraphThreeDOptions}
+
+\index{graphics!3D options}
+The {\bf draw} commands optionally take an optional list of options such
+as {\tt coordinates} as shown in the last example.
+Each option is given by the syntax: $name$ {\tt ==} $value$.
+Here is a list of the available options in the order that they are
+described below:
+
+\begin{tabular}{llll}
+title&coordinates&var1Steps\\
+style&tubeRadius&var2Steps\\
+colorFunction&tubePoints&space\\
+\end{tabular}
+
+The option $title$ gives your graph a title.
+\index{graphics!3D options!title}
+
+\spadgraph{draw(cos(x*y),x=0..2*\%pi,y=0..\%pi,title == "Title of Graph") }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptttl.ps}
+
+The $style$ determines which of four rendering algorithms is used for
+\index{rendering}
+the graph.
+The choices are
+{\tt "wireMesh"}, {\tt "solid"}, {\tt "shade"}, and {\tt "smooth"}.
+
+\spadgraph{draw(cos(x*y),x=-3..3,y=-3..3, style=="smooth", title=="Smooth Option")}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptsty.ps}
+
+In all but the wire-mesh style, polygons in a surface or tube plot
+are normally colored in a graph according to their
+$z$-coordinate value.  Space curves are colored according to their
+parametric variable value.
+\index{graphics!3D options!color function}
+To change this, you can give a coloring function.
+\index{function!coloring}
+The coloring function is sampled across the range of its arguments, then
+normalized onto the standard Axiom colormap.
+
+A function of one variable  makes the color depend on the
+value of the parametric variable specified for a tube plot.
+
+\spadcommand{color1(t) == t }
+\returnType{Type: Void}
+
+\spadgraph{draw(curve(sin(t), cos(t),0), t=0..2*\%pi, tubeRadius == .3, colorFunction == color1) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptcf1.ps}
+
+A function of two variables makes the color depend on the
+values of the independent variables.
+
+\spadcommand{color2(u,v) == u**2 - v**2 }
+\returnType{Type: Void}
+
+Use the option {\tt colorFunction} for special coloring.
+
+\spadgraph{draw(cos(u*v), u=-3..3, v=-3..3, colorFunction == color2) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptcf2.ps}
+
+With a three variable function, the
+color also depends on the value of the function.
+
+\spadcommand{color3(x,y,fxy) == sin(x*fxy) + cos(y*fxy) }
+\returnType{Type: Void}
+
+\spadgraph{draw(cos(x*y), x=-3..3, y=-3..3, colorFunction == color3) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptcf3.ps}
+
+Normally the Cartesian coordinate system is used.
+\index{Cartesian!coordinate system}
+To change this, use the {\tt coordinates} option.
+\index{coordinate system!Cartesian}
+For details, see \ref{ugGraphCoord} on page~\pageref{ugGraphCoord}.
+
+\spadcommand{m(u:DFLOAT,v:DFLOAT):DFLOAT == 1 }
+\begin{verbatim}
+   Function declaration m : (DoubleFloat,DoubleFloat) -> DoubleFloat 
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Use the spherical
+\index{spherical coordinate system}
+coordinate system.
+\index{coordinate system!spherical}
+
+\spadgraph{draw(m, 0..2*\%pi,0..\%pi, coordinates == spherical, style=="shade") }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptcrd.ps}
+
+Space curves may be displayed as tubes with polygonal cross sections.
+\index{tube}
+Two options, {\tt tubeRadius} and {\tt tubePoints},  control the size and
+shape of this cross section.
+%
+
+The {\tt tubeRadius} option specifies the radius of the tube that
+\index{tube!radius}
+encircles the specified space curve.
+
+\spadgraph{draw(curve(sin(t),cos(t),0),t=0..2*\%pi, style=="shade", tubeRadius == .3)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptrad.ps}
+
+The {\tt tubePoints} option specifies the number of vertices
+\index{tube!points in polygon}
+defining the polygon that is used to create a tube around the
+specified space curve.
+The larger this number is, the more cylindrical the tube becomes.
+
+\spadgraph{draw(curve(sin(t), cos(t), 0), t=0..2*\%pi, style=="shade", tubeRadius == .25, tubePoints == 3)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptpts.ps}
+
+\index{graphics!3D options!variable steps}
+%
+
+Options \spadfunFrom{var1Steps}{DrawOption} and
+\spadfunFrom{var2Steps}{DrawOption} specify the number of intervals into
+which the grid defining a surface plot is subdivided with respect to the
+first and second parameters of the surface function(s).
+
+\spadgraph{draw(cos(x*y),x=-3..3,y=-3..3, style=="shade", var1Steps == 30, var2Steps == 30)}
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3doptvb.ps}
+
+The {\tt space} option
+of a {\bf draw} command lets you build multiple graphs in three space.
+To use this option, first create an empty three-space object,
+then use the {\tt space} option thereafter.
+There is no restriction as to the number or kinds
+of graphs that can be combined this way.
+
+Create an empty three-space object.
+
+\spadcommand{s := create3Space()\$(ThreeSpace DFLOAT) }
+$$
+{3-Space with }0 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{m(u:DFLOAT,v:DFLOAT):DFLOAT == 1 }
+\begin{verbatim}
+   Function declaration m : (DoubleFloat,DoubleFloat) -> DoubleFloat 
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Add a graph to this three-space object.
+The new graph destructively inserts the graph
+into $s$.
+
+\spadgraph{draw(m,0..\%pi,0..2*\%pi, coordinates == spherical, space == s) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dmult1a.ps}
+
+Add a second graph to $s$.
+
+\spadgraph{v := draw(curve(1.5*sin(t), 1.5*cos(t),0), t=0..2*\%pi, tubeRadius == .25, space == s)  }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dmult1b.ps}
+
+A three-space object can also be obtained from an existing three-di\-men\-sion\-al viewport
+using the \spadfunFrom{subspace}{ThreeSpace} command.
+You can then use {\bf makeViewport3D} to create a viewport window.
+
+Assign to $subsp$ the three-space object in viewport $v$.
+
+\spadcommand{subsp := subspace v  }
+
+Reset the space component of $v$ to the value of $subsp$.
+
+\spadcommand{subspace(v, subsp)  }
+
+Create a viewport window from a three-space object.
+
+\spadgraph{makeViewport3D(subsp,"Graphs") }
+
+\subsection{The makeObject Command}
+\label{ugGraphMakeObject}
+
+An alternate way to create multiple graphs is to use
+{\bf makeObject}.
+The {\bf makeObject} command is similar to the {\bf draw}
+command, except that it returns a three-space object rather than a
+{\tt ThreeDimensionalViewport}.
+In fact, {\bf makeObject} is called by the {\bf draw}
+command to create the {\tt ThreeSpace} then
+\spadfunFrom{makeViewport3D}{ThreeDimensionalViewport} to create a
+viewport window.
+
+\spadcommand{m(u:DFLOAT,v:DFLOAT):DFLOAT == 1 }
+\begin{verbatim}
+   Function declaration m : (DoubleFloat,DoubleFloat) -> DoubleFloat 
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Do the last example a new way.
+First use {\bf makeObject} to
+create a three-space object $sph$.
+
+\spadcommand{sph := makeObject(m, 0..\%pi, 0..2*\%pi, coordinates==spherical)}
+\begin{verbatim}
+   Compiling function m with type (DoubleFloat,DoubleFloat) -> 
+      DoubleFloat 
+\end{verbatim}
+$$
+{3-Space with }1 \mbox{\rm component} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+Add a second object to $sph$.
+
+\spadcommand{makeObject(curve(1.5*sin(t), 1.5*cos(t), 0), t=0..2*\%pi, space == sph, tubeRadius == .25) }
+\begin{verbatim}
+   Compiling function %D with type DoubleFloat -> DoubleFloat 
+   Compiling function %F with type DoubleFloat -> DoubleFloat 
+   Compiling function %H with type DoubleFloat -> DoubleFloat 
+\end{verbatim}
+$$
+{3-Space with }2 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+Create and display a viewport
+containing $sph$.
+
+\spadgraph{makeViewport3D(sph,"Multiple Objects") }
+
+Note that an undefined {\tt ThreeSpace} parameter declared in a
+{\bf makeObject} or {\bf draw} command results in an error.
+Use the \spadfunFrom{create3Space}{ThreeSpace} function to define a
+{\tt ThreeSpace}, or obtain a {\tt ThreeSpace} that has been
+previously generated before including it in a command line.
+
+\subsection{Building Three-Dimensional Objects From Primitives}
+\label{ugGraphThreeDBuild}
+
+Rather than using the {\bf draw} and {\bf makeObject} commands,
+\index{graphics!advanced!build 3D objects}
+you can create three-di\-men\-sion\-al graphs from primitives.
+Operation \spadfunFrom{create3Space}{ThreeSpace} creates a
+three-space object to which points, curves and polygons
+can be added using the operations from the {\tt ThreeSpace}
+domain.
+The resulting object can then be displayed in a viewport using
+\spadfunFrom{makeViewport3D}{ThreeDimensionalViewport}.
+
+Create the empty three-space object $space$.
+
+\spadcommand{space := create3Space()\$(ThreeSpace DFLOAT) }
+$$
+{3-Space with }0 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+Objects can be sent to this $space$ using the operations
+exported by the {\tt ThreeSpace} domain.
+\index{ThreeSpace}
+The following examples place curves into $space$.
+
+Add these eight curves to the space.
+
+\spadcommand{closedCurve(space,[ [0,30,20], [0,30,30], [0,40,30], [0,40,100], [0,30,100],[0,30,110], [0,60,110], [0,60,100], [0,50,100], [0,50,30], [0,60,30], [0,60,20] ])  }
+$$
+{3-Space with }1 \mbox{\rm component} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [80,0,30], [80,0,100], [70,0,110], [40,0,110], [30,0,100], [30,0,90], [40,0,90], [40,0,95], [45,0,100], [65,0,100], [70,0,95], [70,0,35] ])  }
+$$
+{3-Space with }2 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [70,0,35], [65,0,30], [45,0,30], [40,0,35], [40,0,60], [50,0,60], [50,0,70], [30,0,70], [30,0,30], [40,0,20], [70,0,20], [80,0,30] ])  }
+$$
+{3-Space with }3 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [0,70,20], [0,70,110], [0,110,110], [0,120,100], [0,120,70], [0,115,65], [0,120,60], [0,120,30], [0,110,20], [0,80,20], [0,80,30], [0,80,20] ])  }
+$$
+{3-Space with }4 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [0,105,30], [0,110,35], [0,110,55], [0,105,60], [0,80,60], [0,80,70], [0,105,70], [0,110,75], [0,110,95], [0,105,100], [0,80,100], [0,80,20], [0,80,30] ])  }
+$$
+{3-Space with }5 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [140,0,20], [140,0,110], [130,0,110], [90,0,20], [101,0,20],[114,0,50], [130,0,50], [130,0,60], [119,0,60], [130,0,85], [130,0,20] ])  }
+$$
+{3-Space with }6 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [0,140,20], [0,140,110], [0,150,110], [0,170,50], [0,190,110], [0,200,110], [0,200,20], [0,190,20], [0,190,75], [0,175,35], [0,165,35],[0,150,75], [0,150,20] ])  }
+$$
+{3-Space with }7 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{closedCurve(space,[ [200,0,20], [200,0,110], [189,0,110], [160,0,45], [160,0,110], [150,0,110], [150,0,20], [161,0,20], [190,0,85], [190,0,20] ])  }
+$$
+{3-Space with }8 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+Create and display the viewport using {\bf makeViewport3D}.
+Options may also be given but here are displayed as a list with values
+enclosed in parentheses.
+
+\spadgraph{makeViewport3D(space, title == "Letters") }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dbuilda.ps}
+
+\subsubsection{Cube Example}
+
+As a second example of the use of primitives, we generate a cube using a
+polygon mesh.
+It is important to use a consistent orientation of the polygons for
+correct generation of three-di\-men\-sion\-al objects.
+
+Again start with an empty three-space object.
+
+\spadcommand{spaceC := create3Space()\$(ThreeSpace DFLOAT) }
+$$
+{3-Space with }0 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+For convenience,
+give {\tt DoubleFloat} values $+1$ and $-1$ names.
+
+\spadcommand{x: DFLOAT := 1 }
+$$
+1.0 
+$$
+\returnType{Type: DoubleFloat}
+
+\spadcommand{y: DFLOAT := -1 }
+$$
+-{1.0} 
+$$
+\returnType{Type: DoubleFloat}
+
+Define the vertices of the cube.
+
+\spadcommand{a := point [x,x,y,1::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+{1.0},  {1.0},  -{1.0},  {1.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{b := point [y,x,y,4::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+-{1.0},  {1.0},  -{1.0},  {4.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{c := point [y,x,x,8::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+-{1.0},  {1.0},  {1.0},  {8.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{d := point [x,x,x,12::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+{1.0},  {1.0},  {1.0},  {12.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{e := point [x,y,y,16::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+{1.0},  -{1.0},  -{1.0},  {16.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{f := point [y,y,y,20::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+-{1.0},  -{1.0},  -{1.0},  {20.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{g := point [y,y,x,24::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+-{1.0},  -{1.0},  {1.0},  {24.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+\spadcommand{h := point [x,y,x,27::DFLOAT]\$(Point DFLOAT)  }
+$$
+\left[
+{1.0},  -{1.0},  {1.0},  {27.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+Add the faces of the cube as polygons to the space using a
+consistent orientation.
+
+\spadcommand{polygon(spaceC,[d,c,g,h])  }
+$$
+{3-Space with }1 \mbox{\rm component} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{polygon(spaceC,[d,h,e,a])  }
+$$
+{3-Space with }2 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{polygon(spaceC,[c,d,a,b])  }
+$$
+{3-Space with }3 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{polygon(spaceC,[g,c,b,f])  }
+$$
+{3-Space with }4 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{polygon(spaceC,[h,g,f,e])  }
+$$
+{3-Space with }5 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+\spadcommand{polygon(spaceC,[e,f,b,a])  }
+$$
+{3-Space with }6 \mbox{\rm components} 
+$$
+\returnType{Type: ThreeSpace DoubleFloat}
+
+Create and display the viewport.
+
+\spadgraph{makeViewport3D(spaceC, title == "Cube") }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/3dbuildb.ps}
+
+\subsection{Coordinate System Transformations}
+\label{ugGraphCoord}
+\index{graphics!advanced!coordinate systems}
+
+The {\tt CoordinateSystems} package provides coordinate transformation
+functions that map a given data point from the coordinate system specified
+into the Cartesian coordinate system.
+\index{CoordinateSystems}
+The default coordinate system, given a triplet $(f(u,v), u, v)$, assumes
+that $z = f(u, v)$, $x = u$ and $y = v$,
+that is, reads the coordinates in $(z, x, y)$ order.
+
+\spadcommand{m(u:DFLOAT,v:DFLOAT):DFLOAT == u**2 }
+\begin{verbatim}
+   Function declaration m : (DoubleFloat,DoubleFloat) -> DoubleFloat 
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Graph plotted in default coordinate system.
+
+\spadgraph{draw(m,0..3,0..5) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/defcoord.ps}
+
+The $z$ coordinate comes first since the first argument of
+the {\bf draw} command gives its values.
+In general, the coordinate systems Axiom provides, or any
+that you make up, must provide a map to an $(x, y, z)$ triplet in
+order to be compatible with the
+\spadfunFrom{coordinates}{DrawOption} {\tt DrawOption}.
+\index{DrawOption}
+Here is an example.
+
+Define the identity function.
+
+\spadcommand{cartesian(point:Point DFLOAT):Point DFLOAT == point }
+\begin{verbatim}
+   Function declaration cartesian : Point DoubleFloat -> Point 
+      DoubleFloat has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Pass $cartesian$ as the \spadfunFrom{coordinates}{DrawOption}
+parameter to the {\bf draw} command.
+
+\spadgraph{draw(m,0..3,0..5,coordinates==cartesian) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/cartcoord.ps}
+
+What happened?  The option {\tt coordinates == cartesian} directs
+Axiom to treat the dependent variable $m$ defined by $m=u^2$ as the
+$x$ coordinate.  Thus the triplet of values $(m, u, v)$ is transformed
+to coordinates $(x, y, z)$ and so we get the graph of $x=y^2$.
+
+Here is another example.
+The \spadfunFrom{cylindrical}{CoordinateSystems} transform takes
+\index{coordinate system!cylindrical}
+input of the form $(w,u,v)$, interprets it in the order
+\index{cylindrical coordinate system}
+($r$,$\theta$,$z$)
+and maps it to the Cartesian coordinates
+$x=r\cos(\theta)$, $y=r\sin(\theta)$, $z=z$
+in which
+$r$ is the radius,
+$\theta$ is the angle and
+$z$ is the z-coordinate.
+
+An example using the \spadfunFrom{cylindrical}{CoordinateSystems}
+coordinates for the constant $r = 3$.
+
+\spadcommand{f(u:DFLOAT,v:DFLOAT):DFLOAT == 3 }
+\begin{verbatim}
+   Function declaration f : (DoubleFloat,DoubleFloat) -> DoubleFloat 
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+Graph plotted in cylindrical coordinates.
+
+\spadgraph{draw(f,0..\%pi,0..6,coordinates==cylindrical) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/cylcoord.ps}
+
+Suppose you would like to specify $z$ as a function of
+$r$ and $\theta$ instead of just $r$?
+Well, you still can use the {\bf cylindrical} Axiom
+transformation but we have to reorder the triplet before
+passing it to the transformation.
+
+First, let's create a point to
+work with and call it $pt$ with some color $col$.
+
+\spadcommand{col := 5 }
+$$
+5 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{pt := point[1,2,3,col]\$(Point DFLOAT)  }
+$$
+\left[
+{1.0},  {2.0},  {3.0},  {5.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+The reordering you want is
+$(z,r, \theta)$ to
+$(r, \theta,z)$
+so that the first element is moved to the third element, while the second
+and third elements move forward and the color element does not change.
+
+Define a function {\bf reorder} to reorder the point elements.
+
+\spadcommand{reorder(p:Point DFLOAT):Point DFLOAT == point[p.2, p.3, p.1, p.4] }
+\begin{verbatim}
+   Function declaration reorder : Point DoubleFloat -> Point 
+      DoubleFloat has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+The function moves the second and third elements
+forward but the color does not change.
+
+\spadcommand{reorder pt }
+$$
+\left[
+{2.0},  {3.0},  {1.0},  {5.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+The function {\bf newmap} converts our reordered version of
+the cylindrical coordinate system to the standard
+$(x,y,z)$ Cartesian system.
+
+\spadcommand{newmap(pt:Point DFLOAT):Point DFLOAT == cylindrical(reorder pt)  }
+\begin{verbatim}
+   Function declaration newmap : Point DoubleFloat -> Point DoubleFloat
+      has been added to workspace.
+\end{verbatim}
+\returnType{Type: Void}
+
+\spadcommand{newmap pt  }
+$$
+\left[
+-{1.9799849932008908},  {0.28224001611973443},  {1.0},  {5.0} 
+\right]
+$$
+\returnType{Type: Point DoubleFloat}
+
+Graph the same function $f$ using the coordinate mapping of the function
+$newmap$, so it is now interpreted as
+$z=3$:
+
+\spadgraph{draw(f,0..3,0..2*\%pi,coordinates==newmap) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/newmap.ps}
+
+% I think this is good to say here: it shows a lot of depth. RSS
+%{\sloppy
+The {\tt CoordinateSystems} package exports the following
+\index{coordinate system}
+operations:
+{\bf bipolar},
+{\bf bipolarCylindrical},
+{\bf cartesian},
+{\bf conical},
+{\bf cylindrical},
+{\bf elliptic},
+{\bf ellipticCylindrical},
+{\bf oblateSpheroidal},
+{\bf parabolic},
+{\bf parabolicCylindrical},
+{\bf paraboloidal},
+{\bf polar},
+{\bf prolateSpheroidal},
+{\bf spherical}, and
+{\bf toroidal}.
+Use Browse or the {\tt )show} system command
+\index{show}
+to get more information.
+
+\subsection{Three-Dimensional Clipping}
+\label{ugGraphClip}
+
+A three-di\-men\-sion\-al graph can be explicitly clipped within the {\bf draw}
+\index{graphics!advanced!clip}
+command by indicating a minimum and maximum threshold for the
+\index{clipping}
+given function definition.
+These thresholds can be defined using the Axiom {\bf min}
+and {\bf max} functions.
+
+\begin{verbatim}
+gamma(x,y) ==
+  g := Gamma complex(x,y)
+  point [x, y, max( min(real g, 4), -4), argument g]
+\end{verbatim}
+
+Here is an example that clips
+the gamma function in order to eliminate the extreme divergence it creates.
+
+\spadgraph{draw(gamma,-\%pi..\%pi,-\%pi..\%pi,var1Steps==50,var2Steps==50) }
+
+% window was 300 x 300
+%\epsffile[0 0 295 295]{ps/clipgamma.ps}
+
+\subsection{Three-Dimensional Control-Panel}
+\label{ugGraphThreeDControl}
+
+\index{graphics!3D control-panel}
+Once you have created a viewport, move your mouse to the viewport
+and click with your left mouse button.
+This displays a control-panel on the side of the viewport
+that is closest to where you clicked.
+
+\begin{figure}[htbp]
+%{\epsfverbosetrue\epsfxsize=2in%
+%\def\epsfsize#1#2{\epsfxsize}\hspace*{\baseLeftSkip}%
+%%\epsffile[0 0 144 289]{ps/3dctrl.ps}}
+\begin{picture}(183,252)%(-125,0)
+\hspace*{\baseLeftSkip}\special{psfile=ps/3dctrl.ps}
+\end{picture}
+\caption{Three-dimensional control-panel.}
+\end{figure}
+
+\subsubsection{Transformations}
+
+We recommend you first select the {\bf Bounds} button while
+\index{graphics!3D control-panel!transformations}
+executing transformations since the bounding box displayed
+indicates the object's position as it changes.
+%
+\begin{description}
+%
+\item[Rotate:]  A rotation transformation occurs by clicking the mouse
+\index{graphics!3D control-panel!rotate}
+within the {\bf Rotate} window in the upper left corner of the
+control-panel.
+The rotation is computed in spherical coordinates, using the
+horizontal mouse position to increment or decrement the value of
+the longitudinal angle $\theta$ within the
+range of 0 to 2$\pi$ and the vertical mouse position
+to increment or decrement the value of the latitudinal angle
+$\phi$ within the range of -$\pi$
+to $\pi$.
+The active mode of rotation is displayed in green on a color
+monitor or in clear text on a black and white monitor, while the
+inactive mode is displayed in red for color display or a mottled
+pattern for black and white.
+%
+\begin{description}
+%
+\item[origin:]  The {\bf origin} button indicates that the
+rotation is to occur with respect to the origin of the viewing space, that is
+indicated by the axes.
+%
+\item[object:]  The {\bf object} button indicates that the
+rotation is to occur with respect to the center of volume of the object,
+independent of the axes' origin position.
+\end{description}
+%
+\item[Scale:]  A scaling transformation occurs by clicking the mouse
+\index{graphics!3D control-panel!scale}
+within the {\bf Scale} window in the upper center of the
+control-panel, containing a zoom arrow.
+The axes along which the scaling is to occur are indicated by
+selecting the appropriate button above the zoom arrow window.
+The selected axes are displayed in green on a color monitor or in
+clear text on a black and white monitor, while the unselected axes
+are displayed in red for a color display or a mottled pattern for
+black and white.
+%
+\begin{description}
+%
+\item[uniform:]  Uniform scaling along the {\tt x}, {\tt y}
+and {\tt z} axes occurs when all the axes buttons are selected.
+%
+\item[non-uniform:]  If any of the axes buttons are
+not selected, non-uniform scaling occurs, that is, scaling occurs only in the
+direction of the axes that are selected.
+\end{description}
+%
+\item[Translate:]  Translation occurs by indicating with the mouse in the
+\index{graphics!3D control-panel!translate}
+{\bf Translate} window the direction you want the graph to move.
+This window is located in the upper right corner of the
+control-panel and contains a potentiometer with crossed arrows
+pointing up, down, left and right.
+Along the top of the {\bf Translate} window are three buttons
+({\bf XY},
+{\bf XZ}, and {\bf YZ}) indicating the three orthographic projection planes.
+Each orientates the group as a view into that plane.
+Any translation of the graph occurs only along this plane.
+\end{description}
+
+\subsubsection{Messages}
+
+\index{graphics!3D control-panel!messages}
+
+The window directly below the potentiometer windows for transformations is
+used to display system messages relating to the viewport, the control-panel
+and the current graph displaying status.
+
+\subsubsection{Colormap}
+
+\index{graphics!3D control-panel!color map}
+
+Directly below the message window is the colormap range indicator
+window.
+\index{colormap}
+The Axiom Colormap shows a sampling of the spectrum from
+which hues can be drawn to represent the colors of a surface.
+The Colormap is composed of five shades for each of the hues along
+this spectrum.
+By moving the markers above and below the Colormap, the range of
+hues that are used to color the existing surface are set.
+The bottom marker shows the hue for the low end of the color range
+and the top marker shows the hue for the upper end of the range.
+Setting the bottom and top markers at the same hue results in
+monochromatic smooth shading of the graph when {\bf Smooth} mode is selected.
+At each end of the Colormap are {\bf +} and {\bf -} buttons.
+When clicked on, these increment or decrement the top or bottom
+marker.
+
+\subsubsection{Buttons}
+\index{graphics!3D control-panel!buttons}
+
+Below the Colormap window and to the left are located various
+buttons that determine the characteristics of a graph.
+The buttons along the bottom and right hand side all have special
+meanings; the remaining buttons in the first row indicate the mode
+or style used to display the graph.
+The second row are toggles that turn on or off a property of the
+graph.
+On a color monitor, the property is on if green (clear text, on a
+monochrome monitor) and off if red (mottled pattern, on a
+monochrome monitor).
+Here is a list of their functions.
+%
+\begin{description}
+%
+\item[Wire] displays surface and tube plots as a
+\index{graphics!3D control-panel!wire}
+wireframe image in a single color (blue) with no hidden surfaces removed,
+or displays space curve plots in colors based upon their parametric variables.
+This is the fastest mode for displaying a graph.
+This is very useful when you
+want to find a good orientation of your graph.
+%
+\item[Solid] displays the graph with hidden
+\index{graphics!3D control-panel!solid}
+surfaces removed, drawing each polygon beginning with the furthest
+from the viewer.
+The edges of the polygons are displayed in the hues specified by
+the range in the Colormap window.
+%
+\item[Shade] displays the graph with hidden
+\index{graphics!3D control-panel!shade}
+surfaces removed and with the polygons shaded, drawing each
+polygon beginning with the furthest from the viewer.
+Polygons are shaded in the hues specified by the range in the
+Colormap window using the Phong illumination model.
+\index{Phong!illumination model}
+%
+\item[Smooth] displays the graph using a
+\index{graphics!3D control-panel!smooth}
+renderer that computes the graph one line at a time.
+The location and color of the graph at each visible point on the
+screen are determined and displayed using the Phong illumination
+\index{Phong!illumination model}
+model.
+Smooth shading is done in one of two ways, depending on the range
+selected in the colormap window and the number of colors available
+from the hardware and/or window manager.
+When the top and bottom markers of the colormap range are set to
+different hues, the graph is rendered by dithering between the
+\index{dithering}
+transitions in color hue.
+When the top and bottom markers of the colormap range are set to
+the same hue, the graph is rendered using the Phong smooth shading
+model.
+\index{Phong!smooth shading model}
+However, if enough colors cannot be allocated for this purpose,
+the renderer reverts to the color dithering method until a
+sufficient color supply is available.
+For this reason, it may not be possible to render multiple Phong
+smooth shaded graphs at the same time on some systems.
+%
+\item[Bounds] encloses the entire volume of the
+viewgraph within a bounding box, or removes the box if previously selected.
+\index{graphics!3D control-panel!bounds}
+The region that encloses the entire volume of the viewport graph is displayed.
+%
+\item[Axes] displays Cartesian
+\index{graphics!3D control-panel!axes}
+coordinate axes of the space, or turns them off if previously selected.
+%
+\item[Outline] causes
+\index{graphics!3D control-panel!outline}
+quadrilateral polygons forming the graph surface to be outlined in black when
+the graph is displayed in {\bf Shade} mode.
+%
+\item[BW] converts a color viewport to black and white, or vice-versa.
+\index{graphics!3D control-panel!bw}
+When this button is selected the
+control-panel and viewport switch to an immutable colormap composed of a range
+of grey scale patterns or tiles that are used wherever shading is necessary.
+%
+\item[Light] takes you to a control-panel described below.
+%
+\item[ViewVolume] takes you to another control-panel as described below.
+\index{graphics!3D control-panel!save}
+%
+\item[Save] creates a menu of the possible file types that can
+be written using the control-panel.
+The {\bf Exit} button leaves the save menu.
+The {\bf Pixmap} button writes an Axiom pixmap of
+\index{graphics!3D control-panel!pixmap}
+the current viewport contents.  The file is called {\bf axiom3D.pixmap} and is
+located in the directory from which Axiom or {\bf viewalone} was
+started.
+The {\bf PS} button writes the current viewport contents to
+\index{graphics!3D control-panel!ps}
+PostScript output rather than to the viewport window.
+By default the file is called {\bf axiom3D.ps}; however, if a file
+\index{file!.Xdefaults @{\bf .Xdefaults}}
+name is specified in the user's {\bf .Xdefaults} file it is
+\index{graphics!.Xdefaults!PostScript file name}
+used.
+The file is placed in the directory from which the Axiom or
+{\bf viewalone} session was begun.
+See also the \spadfunFrom{write}{ThreeDimensionalViewport}
+function.
+\index{PostScript}
+%
+\item[Reset] returns the object transformation
+\index{graphics!3D control-panel!reset}
+characteristics back to their initial states.
+%
+\item[Hide] causes the control-panel for the
+\index{graphics!3D control-panel!hide}
+corresponding viewport to disappear from the screen.
+%
+\item[Quit]  queries whether the current viewport
+\index{graphics!3D control-panel!quit}
+session should be terminated.
+\end{description}
+
+\subsubsection{Light}
+
+\index{graphics!3D control-panel!light}
+
+%>>>\begin{figure}[htbp]
+%>>>\begin{picture}(183,252)(-125,0)
+%>>>\special{psfile=ps/3dlight.ps}
+%>>>\end{picture}
+%>>>\caption{Three-Dimensional Lighting Panel.}
+%>>>\end{figure}
+
+The {\bf Light} button changes the control-panel into the
+{\bf Lighting Control-Panel}.  At the top of this panel, the three axes
+are shown with the same orientation as the object.  A light vector from
+the origin of the axes shows the current position of the light source
+relative to the object.  At the bottom of the panel is an {\bf Abort}
+button that cancels any changes to the lighting that were made, and a
+{\bf Return} button that carries out the current set of lighting changes
+on the graph.
+%
+\begin{description}
+%
+\item[XY:]  The {\bf XY} lighting axes window is below the
+\index{graphics!3D control-panel!move xy}
+{\bf Lighting Control-Panel} title and to the left.
+This changes the light vector within the {\bf XY} view plane.
+%
+\item[Z:]  The {\bf Z} lighting axis window is below the
+\index{graphics!3D control-panel!move z}
+{\bf Lighting Control-Panel} title and in the center.  This
+changes the {\bf Z}
+location of the light vector.
+%
+\item[Intensity:]
+Below the {\bf Lighting Control-Panel} title
+\index{graphics!3D control-panel!intensity}
+and to the right is the light intensity meter.
+Moving the intensity indicator down decreases the amount of
+light emitted from the light source.
+When the indicator is at the top of the meter the light source is
+emitting at 100\% intensity.
+At the bottom of the meter the light source is emitting at a level
+slightly above ambient lighting.
+\end{description}
+
+\subsubsection{View Volume}
+
+\index{graphics!3D control-panel!view volume}
+
+The {\bf View Volume} button changes the control-panel into
+the {\bf Viewing Volume Panel}.
+At the bottom of the viewing panel is an {\bf Abort} button that
+cancels any changes to the viewing volume that were made and a
+{\it Return} button that carries out the current set of
+viewing changes to the graph.
+%
+%>>>\begin{figure}[htbp]
+%>>>\begin{picture}(183,252)(-125,0)
+%>>>\special{psfile=ps/3dvolume.ps}
+%>>>\end{picture}
+%>>>\caption{Three-Dimensional Volume Panel.}
+%>>>\end{figure}
+
+\begin{description}
+
+\item[Eye Reference:]  At the top of this panel is the
+\index{graphics!3D control-panel!eye reference}
+{\bf Eye Reference} window.
+It shows a planar projection of the viewing pyramid from the eye
+of the viewer relative to the location of the object.
+This has a bounding region represented by the rectangle on the
+left.
+Below the object rectangle is the {\bf Hither} window.
+By moving the slider in this window the hither clipping plane sets
+\index{hither clipping plane}
+the front of the view volume.
+As a result of this depth clipping all points of the object closer
+to the eye than this hither plane are not shown.
+The {\bf Eye Distance} slider to the right of the {\bf Hither}
+slider is used to change the degree of perspective in the image.
+%
+\item[Clip Volume:]  The {\bf Clip Volume} window is at the
+\index{graphics!3D control-panel!clip volume}
+bottom of the {\bf Viewing Volume Panel}.
+On the right is a {\bf Settings} menu.
+In this menu are buttons to select viewing attributes.
+Selecting the {\bf Perspective} button computes the image using
+perspective projection.
+\index{graphics!3D control-panel!perspective}
+The {\bf Show Region} button indicates whether the clipping region
+of the
+\index{graphics!3D control-panel!show clip region}
+volume is to be drawn in the viewport and the {\bf Clipping On}
+button shows whether the view volume clipping is to be in effect
+when the image
+\index{graphics!3D control-panel!clipping on}
+is drawn.
+The left side of the {\bf Clip Volume} window shows the clipping
+\index{graphics!3D control-panel!clip volume}
+boundary of the graph.
+Moving the knobs along the {\bf X}, {\bf Y}, and {\bf Z} sliders
+adjusts the volume of the clipping region accordingly.
+\end{description}
+
+\subsection{Operations for Three-Dimensional Graphics}
+\label{ugGraphThreeDops}
+
+
+Here is a summary of useful Axiom operations for three-di\-men\-sion\-al
+graphics.
+Each operation name is followed by a list of arguments.
+Each argument is written as a variable informally named according
+to the type of the argument (for example, {\it integer}).
+If appropriate, a default value for an argument is given in
+parentheses immediately following the name.
+
+%
+\bgroup\hbadness = 10001\sloppy
+\begin{description}
+%
+\item[{\bf adaptive3D?}]\funArgs{}
+tests whether space curves are to be plotted
+\index{graphics!plot3d defaults!adaptive}
+according to the
+\index{adaptive plotting}
+adaptive refinement algorithm.
+
+%
+\item[{\bf axes}]\funArgs{viewport, string\argDef{"on"}}
+turns the axes on and off.
+\index{graphics!3D commands!axes}
+
+%
+\item[{\bf close}]\funArgs{viewport}
+closes the viewport.
+\index{graphics!3D commands!close}
+
+%
+\item[{\bf colorDef}]\funArgs{viewport,
+$\hbox{\it color}_{1}$\argDef{1}, $\hbox{\it color}_{2}$\argDef{27}}
+sets the colormap
+\index{graphics!3D commands!define color}
+range to be from
+$\hbox{\it color}_{1}$ to $\hbox{\it color}_{2}$.
+
+%
+\item[{\bf controlPanel}]\funArgs{viewport, string\argDef{"off"}}
+declares whether the
+\index{graphics!3D commands!control-panel}
+control-panel for the viewport is to be displayed or not.
+
+%
+\item[{\bf diagonals}]\funArgs{viewport, string\argDef{"off"}}
+declares whether the
+\index{graphics!3D commands!diagonals}
+polygon outline includes the diagonals or not.
+
+%
+\item[{\bf drawStyle}]\funArgs{viewport, style}
+selects which of four drawing styles
+\index{graphics!3D commands!drawing style}
+are used: {\tt "wireMesh", "solid", "shade",} or {\tt "smooth".}
+
+%
+\item[{\bf eyeDistance}]\funArgs{viewport,float\argDef{500}}
+sets the distance of the eye from the origin of the object
+\index{graphics!3D commands!eye distance}
+for use in the \spadfunFrom{perspective}{ThreeDimensionalViewport}.
+
+%
+\item[{\bf key}]\funArgs{viewport}
+returns the operating
+\index{graphics!3D commands!key}
+system process ID number for the viewport.
+
+%
+\item[{\bf lighting}]\funArgs{viewport,
+$float_{x}$\argDef{-0.5},
+$float_{y}$\argDef{0.5}, $float_{z}$\argDef{0.5}}
+sets the Cartesian
+\index{graphics!3D commands!lighting}
+coordinates of the light source.
+
+%
+\item[{\bf modifyPointData}]\funArgs{viewport,integer,point}
+replaces the coordinates of the point with
+\index{graphics!3D commands!modify point data}
+the index {\it integer} with {\it point}.
+
+%
+\item[{\bf move}]\funArgs{viewport,
+$integer_{x}$\argDef{viewPosDefault},
+$integer_{y}$\argDef{viewPosDefault}}
+moves the upper
+\index{graphics!3D commands!move}
+left-hand corner of the viewport to screen position
+\allowbreak
+({\small $integer_{x}$, $integer_{y}$}).
+
+%
+\item[{\bf options}]\funArgs{viewport}
+returns a list of all current draw options.
+
+%
+\item[{\bf outlineRender}]\funArgs{viewport, string\argDef{"off"}}
+turns polygon outlining
+\index{graphics!3D commands!outline}
+off or on when drawing in {\tt "shade"} mode.
+
+%
+\item[{\bf perspective}]\funArgs{viewport, string\argDef{"on"}}
+turns perspective
+\index{graphics!3D commands!perspective}
+viewing on and off.
+
+%
+\item[{\bf reset}]\funArgs{viewport}
+resets the attributes of a viewport to their
+\index{graphics!3D commands!reset}
+initial settings.
+
+%
+\item[{\bf resize}]\funArgs{viewport,
+$integer_{width}$ \argDef{viewSizeDefault},
+$integer_{height}$ \argDef{viewSizeDefault}}
+resets the width and height
+\index{graphics!3D commands!resize}
+values for a viewport.
+
+%
+\item[{\bf rotate}]\funArgs{viewport,
+$number_{\theta}$\argDef{viewThetaDefapult},
+$number_{\phi}$\argDef{viewPhiDefault}}
+rotates the viewport by rotation angles for longitude
+({\it $\theta$}) and
+latitude ({\it $\phi$}).
+Angles designate radians if given as floats, or degrees if given
+\index{graphics!3D commands!rotate}
+as integers.
+
+%
+\item[{\bf setAdaptive3D}]\funArgs{boolean\argDef{true}}
+sets whether space curves are to be plotted
+\index{graphics!plot3d defaults!set adaptive}
+according to the adaptive
+\index{adaptive plotting}
+refinement algorithm.
+
+%
+\item[{\bf setMaxPoints3D}]\funArgs{integer\argDef{1000}}
+ sets the default maximum number of possible
+\index{graphics!plot3d defaults!set max points}
+points to be used when constructing a three-di\-men\-sion\-al space curve.
+
+%
+\item[{\bf setMinPoints3D}]\funArgs{integer\argDef{49}}
+sets the default minimum number of possible
+\index{graphics!plot3d defaults!set min points}
+points to be used when constructing a three-di\-men\-sion\-al space curve.
+
+%
+\item[{\bf setScreenResolution3D}]\funArgs{integer\argDef{49}}
+sets the default screen resolution constant
+\index{graphics!plot3d defaults!set screen resolution}
+used in setting the computation limit of adaptively
+\index{adaptive plotting}
+generated three-di\-men\-sion\-al space curve plots.
+
+%
+\item[{\bf showRegion}]\funArgs{viewport, string\argDef{"off"}}
+declares whether the bounding
+\index{graphics!3D commands!showRegion}
+box of a graph is shown or not.
+%
+\item[{\bf subspace}]\funArgs{viewport}
+returns the space component.
+%
+\item[{\bf subspace}]\funArgs{viewport, subspace}
+resets the space component
+\index{graphics!3D commands!subspace}
+to {\it subspace}.
+
+%
+\item[{\bf title}]\funArgs{viewport, string}
+gives the viewport the
+\index{graphics!3D commands!title}
+title {\it string}.
+
+%
+\item[{\bf translate}]\funArgs{viewport,
+$float_{x}$\argDef{viewDeltaXDefault},
+$float_{y}$\argDef{viewDeltaYDefault}}
+translates
+\index{graphics!3D commands!translate}
+the object horizontally and vertically relative to the center of the viewport.
+
+%
+\item[{\bf intensity}]\funArgs{viewport,float\argDef{1.0}}
+resets the intensity {\it I} of the light source,
+\index{graphics!3D commands!intensity}
+$0 \le I \le 1.$
+
+%
+\item[{\bf tubePointsDefault}]\funArgs{\optArg{integer\argDef{6}}}
+sets or indicates the default number of
+\index{graphics!3D defaults!tube points}
+vertices defining the polygon that is used to create a tube around
+a space curve.
+
+%
+\item[{\bf tubeRadiusDefault}]\funArgs{\optArg{float\argDef{0.5}}}
+sets or indicates the default radius of
+\index{graphics!3D defaults!tube radius}
+the tube that encircles a space curve.
+
+%
+\item[{\bf var1StepsDefault}]\funArgs{\optArg{integer\argDef{27}}}
+sets or indicates the default number of
+\index{graphics!3D defaults!var1 steps}
+increments into which the grid defining a surface plot is subdivided with
+respect to the first parameter declared in the surface function.
+
+%
+\item[{\bf var2StepsDefault}]\funArgs{\optArg{integer\argDef{27}}}
+sets or indicates the default number of
+\index{graphics!3D defaults!var2 steps}
+increments into which the grid defining a surface plot is subdivided with
+respect to the second parameter declared in the surface function.
+
+%
+\item[{\bf viewDefaults}]\funArgs{{\tt [}$integer_{point}$, 
+$integer_{line}$, $integer_{axes}$,
+$integer_{units}$, $float_{point}$,
+\allowbreak$list_{position}$,
+$list_{size}${\tt ]}}
+resets the default settings for the
+\index{graphics!3D defaults!reset viewport defaults}
+point color, line color, axes color, units color, point size,
+viewport upper left-hand corner position, and the viewport size.
+
+%
+\item[{\bf viewDeltaXDefault}]\funArgs{\optArg{float\argDef{0}}}
+resets the default horizontal offset
+\index{graphics!3D commands!deltaX default}
+from the center of the viewport, or returns the current default offset if no argument is given.
+
+%
+\item[{\bf viewDeltaYDefault}]\funArgs{\optArg{float\argDef{0}}}
+resets the default vertical offset
+\index{graphics!3D commands!deltaY default}
+from the center of the viewport, or returns the current default offset if no argument is given.
+
+%
+\item[{\bf viewPhiDefault}]\funArgs{\optArg{float\argDef{-$\pi$/4}}}
+resets the default latitudinal view angle,
+or returns the current default angle if no argument is given.
+\index{graphics!3D commands!phi default}
+$\phi$ is set to this value.
+
+%
+\item[{\bf viewpoint}]\funArgs{viewport, $float_{x}$,
+$float_{y}$, $float_{z}$}
+sets the viewing position in Cartesian coordinates.
+
+%
+\item[{\bf viewpoint}]\funArgs{viewport,
+$float_{\theta}$,
+$Float_{\phi}$}
+sets the viewing position in spherical coordinates.
+
+%
+\item[{\bf viewpoint}]\funArgs{viewport,
+$Float_{\theta}$,
+$Float_{\phi}$,
+$Float_{scaleFactor}$,
+$Float_{xOffset}$, $Float_{yOffset}$}
+sets the viewing position in spherical coordinates,
+the scale factor, and offsets.
+\index{graphics!3D commands!viewpoint}
+$\theta$ (longitude) and
+$\phi$ (latitude) are in radians.
+
+%
+\item[{\bf viewPosDefault}]\funArgs{\optArg{list\argDef{[0,0]}}}
+sets or indicates the position of the upper
+\index{graphics!3D defaults!viewport position}
+left-hand corner of a two-di\-men\-sion\-al viewport, relative to the display root
+window (the upper left-hand corner of the display is $[0, 0]$).
+
+%
+\item[{\bf viewSizeDefault}]\funArgs{\optArg{list\argDef{[400,400]}}}
+sets or indicates the width and height dimensions
+\index{graphics!3D defaults!viewport size}
+of a viewport.
+
+%
+\item[{\bf viewThetaDefault}]\funArgs{\optArg{float\argDef{$\pi$/4}}}
+resets the default longitudinal view angle,
+or returns the current default angle if no argument is given.
+\index{graphics!3D commands!theta default}
+When a parameter is specified, the default longitudinal view angle
+$\theta$ is set to this value.
+
+%
+\item[{\bf viewWriteAvailable}]\funArgs{\optArg{list\argDef{["pixmap",
+"bitmap", "postscript", "image"]}}}
+indicates the possible file types
+\index{graphics!3D defaults!available viewport writes}
+that can be created with the \spadfunFrom{write}{ThreeDimensionalViewport} function.
+
+%
+\item[{\bf viewWriteDefault}]\funArgs{\optArg{list\argDef{[]}}}
+sets or indicates the default types of files
+that are created in addition to the {\bf data} file when a
+\spadfunFrom{write}{ThreeDimensionalViewport} command
+\index{graphics!3D defaults!viewport writes}
+is executed on a viewport.
+
+%
+\item[{\bf viewScaleDefault}]\funArgs{\optArg{float}}
+sets the default scaling factor, or returns
+\index{graphics!3D commands!scale default}
+the current factor if no argument is given.
+
+%
+\item[{\bf write}]\funArgs{viewport, directory, \optArg{option}}
+writes the file {\bf data} for {\it viewport}
+in the directory {\it directory}.
+An optional third argument specifies a file type (one of {\tt
+pixmap}, {\tt bitmap}, {\tt postscript}, or {\tt image}), or a
+list of file types.
+An additional file is written for each file type listed.
+
+%
+\item[{\bf scale}]\funArgs{viewport, float\argDef{2.5}}
+specifies the scaling factor.
+\index{graphics!3D commands!scale}
+\index{scaling graphs}
+\end{description}
+\egroup
+
+\subsection{Customization using .Xdefaults}
+\label{ugXdefaults}
+
+\index{graphics!.Xdefaults}
+
+Both the two-di\-men\-sion\-al and three-di\-men\-sion\-al drawing facilities consult
+the {\bf .Xdefaults} file for various defaults.
+\index{file!.Xdefaults @{\bf .Xdefaults}}
+The list of defaults that are recognized by the graphing routines
+is discussed in this section.
+These defaults are preceded by {\tt Axiom.3D.}
+for three-di\-men\-sion\-al viewport defaults, {\tt Axiom.2D.}
+for two-di\-men\-sion\-al viewport defaults, or {\tt Axiom*} (no dot) for
+those defaults that are acceptable to either viewport type.
+
+%
+\begin{description}
+%
+\item[{\tt Axiom*buttonFont:\ \it font}] \ \newline
+This indicates which
+\index{graphics!.Xdefaults!button font}
+font type is used for the button text on the control-panel.
+{\bf Rom11}
+%
+\item[{\tt Axiom.2D.graphFont:\ \it font}] \quad (2D only) \newline
+This indicates
+\index{graphics!.Xdefaults!graph number font}
+which font type is used for displaying the graph numbers and
+slots in the {\bf Graphs} section of the two-di\-men\-sion\-al control-panel.
+{\bf Rom22}
+%
+\item[{\tt Axiom.3D.headerFont:\ \it font}] \ \newline
+This indicates which
+\index{graphics!.Xdefaults!graph label font}
+font type is used for the axes labels and potentiometer
+header names on three-di\-men\-sion\-al viewport windows.
+This is also used for two-di\-men\-sion\-al control-panels for indicating
+which font type is used for potentionmeter header names and
+multiple graph title headers.
+%for example, {\tt Axiom.2D.headerFont: 8x13}.
+{\bf Itl14}
+%
+\item[{\tt Axiom*inverse:\ \it switch}] \ \newline
+This indicates whether the
+\index{graphics!.Xdefaults!inverting background}
+background color is to be inverted from white to black.
+If {\tt on}, the graph viewports use black as the background
+color.
+If {\tt off} or no declaration is made, the graph viewports use a
+white background.
+{\bf off}
+%
+\item[{\tt Axiom.3D.lightingFont:\ \it font}] \quad (3D only) \newline
+This indicates which font type is used for the {\bf x},
+\index{graphics!.Xdefaults!lighting font}
+{\bf y}, and {\bf z} labels of the two lighting axes potentiometers, and for
+the {\bf Intensity} title on the lighting control-panel.
+{\bf Rom10}
+%
+\item[{\tt Axiom.2D.messageFont, Axiom.3D.messageFont:\ \it font}] \ \newline
+These indicate the font type
+\index{graphics!.Xdefaults!message font}
+to be used for the text in the control-panel message window.
+{\bf Rom14}
+%
+\item[{\tt Axiom*monochrome:\ \it switch}] \ \newline
+This indicates whether the
+\index{graphics!.Xdefaults!monochrome}
+graph viewports are to be displayed as if the monitor is black and
+white, that is, a 1 bit plane.
+If {\tt on} is specified, the viewport display is black and white.
+If {\tt off} is specified, or no declaration for this default is
+given, the viewports are displayed in the normal fashion for the
+monitor in use.
+{\bf off}
+%
+\item[{\tt Axiom.2D.postScript:\ \it filename}] \ \newline
+This specifies
+\index{graphics!.Xdefaults!PostScript file name}
+the name of the file that is generated when a 2D PostScript graph
+\index{PostScript}
+is saved.
+{\bf axiom2d.ps}
+%
+\item[{\tt Axiom.3D.postScript:\ \it filename}] \ \newline
+This specifies
+\index{graphics!.Xdefaults!PostScript file name}
+the name of the file that is generated when a 3D PostScript graph
+\index{PostScript}
+is saved.
+{\bf axiom3D.ps}
+%
+\item[{\tt Axiom*titleFont \it font}] \ \newline
+This
+\index{graphics!.Xdefaults!title font}
+indicates which font type is used
+for the title text and, for three-di\-men\-sion\-al graphs,
+in the lighting and viewing-volume control-panel windows.
+\index{graphics!Xdefaults!2d}
+{\bf Rom14}
+%
+\item[{\tt Axiom.2D.unitFont:\ \it font}] \quad (2D only) \newline
+This indicates
+\index{graphics!.Xdefaults!unit label font}
+which font type is used for displaying the unit labels on
+two-di\-men\-sion\-al viewport graphs.
+{\bf 6x10}
+%
+\item[{\tt Axiom.3D.volumeFont:\ \it font}] \quad (3D only) \newline
+This indicates which font type is used for the {\bf x},
+\index{graphics!.Xdefaults!volume label font}
+{\bf y}, and {\bf z} labels of the clipping region sliders; for the
+{\bf Perspective}, {\bf Show Region}, and {\bf Clipping On} buttons under
+{\bf Settings}, and above the windows for the {\bf Hither} and
+{\bf Eye Distance} sliders in the {\bf Viewing Volume Panel} of the
+three-di\-men\-sion\-al control-panel.
+{\bf Rom8}
+\end{description}
+
+\setcounter{chapter}{7} % Chapter 8
+% viewSizeDefault [300,300]
+
+\chapter{Advanced Problem Solving}
+\label{ugProblem}
+
+In this chapter we describe techniques useful in solving advanced problems
+with Axiom.
+
+\section{Numeric Functions}
+\label{ugProblemNumeric}
+
+%
+Axiom provides two basic floating-point types: {\tt Float} and
+{\tt DoubleFloat}.  This section describes how to use numerical
+\index{function!numeric}
+operations defined on these types and the related complex types.
+\index{numeric operations}
+%
+As we mentioned in Chapter 
+\ref{ugIntro} on page~\pageref{ugIntro}, the {\tt Float} type is a software
+implementation of floating-point numbers in which the exponent and the
+\index{floating-point number}
+significand may have any number of digits.
+\index{number!floating-point}
+See 
+\ref{FloatXmpPage} on page~\pageref{FloatXmpPage} 
+for detailed information about this domain.
+The {\tt DoubleFloat} (see \ref{DoubleFloatXmpPage} on 
+page~\pageref{DoubleFloatXmpPage}) is usually a hardware implementation 
+of floating point numbers, corresponding to machine double
+precision.
+The types {\tt Complex Float} and {\tt Complex DoubleFloat} are
+\index{floating-point number!complex}
+the corresponding software implementations of complex floating-point numbers.
+\index{complex!floating-point number}
+In this section the term {\it floating-point type}  means any of these
+\index{number!complex floating-point}
+four types.
+%
+The floating-point types implement the basic elementary functions.
+These include (where {\tt \$} means
+{\tt DoubleFloat},
+{\tt Float},
+{\tt Complex DoubleFloat}, or
+{\tt Complex Float}):
+
+\noindent
+{\bf exp},  {\bf log}: $\$ -> \$$ \newline
+{\bf sin},  {\bf cos}, {\bf tan}, {\bf cot}, {\bf sec}, {\bf csc}: $\$ -> \$$ \newline
+{\bf sin},  {\bf cos}, {\bf tan}, {\bf cot}, {\bf sec}, {\bf csc}: $\$ -> \$$  \newline
+{\bf asin}, {\bf acos}, {\bf atan}, {\bf acot}, {\bf asec}, {\bf acsc}: $\$ -> \$$  \newline
+{\bf sinh},  {\bf cosh}, {\bf tanh}, {\bf coth}, {\bf sech}, {\bf csch}: $\$ -> \$$  \newline
+{\bf asinh}, {\bf acosh}, {\bf atanh}, {\bf acoth}, {\bf asech}, {\bf acsch}: $\$ -> \$$  \newline
+{\bf pi}: $() -> \$$  \newline
+{\bf sqrt}: $\$ -> \$$ \newline
+{\bf nthRoot}: $(\$, Integer) -> \$$  \newline
+\spadfunFrom{**}{Float}: $(\$, Fraction Integer) -> \$$ \newline
+\spadfunFrom{**}{Float}: $(\$,\$) -> \$$  \newline
+
+The handling of roots depends on whether the floating-point type
+\index{root!numeric approximation}
+is real or complex: for the real floating-point types,
+{\tt DoubleFloat} and {\tt Float}, if a real root exists
+the one with the same sign as the radicand is returned; for the
+complex floating-point types, the principal value is returned.
+\index{principal value}
+Also, for real floating-point types the inverse functions
+produce errors if the results are not real.
+This includes cases such as $asin(1.2)$, $log(-3.2)$,
+$sqrt(-1.1)$.
+%
+
+The default floating-point type is {\tt Float} so to evaluate
+functions using {\tt Float} or {\tt Complex Float}, just use
+normal decimal notation.
+
+\spadcommand{exp(3.1)}
+$$
+22.1979512814 41633405 
+$$
+\returnType{Type: Float}
+
+\spadcommand{exp(3.1 + 4.5 * \%i)}
+$$
+-{4.6792348860 969899118} -{{21.6991659280 71731864} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+To evaluate functions using {\tt DoubleFloat}
+or {\tt Complex DoubleFloat},
+a declaration or conversion is required.
+
+\spadcommand{r: DFLOAT := 3.1; t: DFLOAT := 4.5; exp(r + t*\%i)}
+$$
+-{4.6792348860969906} -{{21.699165928071732} \  i} 
+$$
+\returnType{Type: Complex DoubleFloat}
+
+\spadcommand{exp(3.1::DFLOAT + 4.5::DFLOAT * \%i)}
+$$
+-{4.6792348860969906} -{{21.699165928071732} \  i} 
+$$
+\returnType{Type: Complex DoubleFloat}
+
+A number of special functions are provided by the package
+{\tt DoubleFloatSpecialFunctions} for the machine-precision
+\index{special functions}
+floating-point types.
+\index{DoubleFloatSpecialFunctions}
+The special functions provided are listed below, where $F$ stands for
+the types {\tt DoubleFloat} and {\tt Complex DoubleFloat}.
+The real versions of the functions yield an error if the result is not real.
+\index{function!special}
+
+\noindent
+{\bf Gamma}: $F -> F$\hfill\newline
+$Gamma(z)$ is the Euler gamma function,
+\index{function!Gamma}
+   $\Gamma(z)$,
+   defined by
+\index{Euler!gamma function}
+   $$\Gamma(z) = \int_{0}^{\infty} t^{z-1} e^{-t} dt.$$
+   
+
+\noindent
+{\bf Beta}: $F -> F$\hfill\newline
+   $Beta(u, v)$ is the Euler Beta function,
+\index{function!Euler Beta}
+   $Beta(u,v)$, defined by
+\index{Euler!Beta function}
+   $$Beta(u,v) = \int_{0}^{1} t^{u-1} (1-t)^{v-1} dt.$$
+   
+   This is related to $\Gamma(z)$ by
+   $$Beta(u,v) = \frac{\Gamma(u) \Gamma(v)}{\Gamma(u + v)}.$$
+
+\noindent
+{\bf logGamma}: $F -> F$\hfill\newline
+   $logGamma(z)$ is the natural logarithm of
+$\Gamma(z)$.
+   This can often be computed even if $\Gamma(z)$
+cannot.
+%
+
+\noindent
+{\bf digamma}: $F -> F$\hfill\newline
+   $digamma(z)$, also called $psi(z)$,
+\index{psi @ $\psi$}
+is the function $\psi(z)$,
+\index{function!digamma}
+   defined by $$\psi(z) = \Gamma'(z)/\Gamma(z).$$
+
+\noindent
+{\bf polygamma}: $(NonNegativeInteger, F) -> F$\hfill\newline
+   $polygamma(n, z)$ is the $n$-th derivative of
+\index{function!polygamma}
+   $\psi(z)$, written $\psi^{(n)}(z)$.
+
+\noindent
+{\bf E1}: $(DoubleFloat) -> OnePointCompletion DoubleFloat$\hfill\newline
+   E1(x) is the Exponential Integral function
+   The current implementation is a piecewise approximation
+   involving one poly from $-4..4$ and a second poly for $x > 4$
+\index{function!E1}
+
+\noindent
+{\bf En}: $(PI, DFLOAT) -> OnePointCompletion DoubleFloat$\hfill\newline
+   En(PI,R) is the nth Exponential Integral
+\index{function!En}
+
+\noindent
+{\bf Ei}: $(OnePointCompletion DFLOAT) -> OnePointCompletion DFLOAT$
+\hfill\newline
+   Ei is the Exponential Integral function
+   This is computed using a 6 part piecewise approximation.
+   DoubleFloat can only preserve about 16 digits but the
+   Chebyshev approximation used can give 30 digits.
+\index{function!Ei}
+
+\noindent
+{\bf Ei1}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei1 is the first approximation of Ei where the result is
+   $x*e^-x*Ei(x)$ from -infinity to -10 (preserves digits)
+\index{function!Ei1}
+
+\noindent
+{\bf Ei2}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei2 is the first approximation of Ei where the result is
+   $x*e^-x*Ei(x)$ from -10 to -4 (preserves digits)
+\index{function!Ei2}
+
+\noindent
+{\bf Ei3}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei3 is the first approximation of Ei where the result is
+   $(Ei(x)-log |x| - gamma)/x$ from -4 to 4 (preserves digits)
+\index{function!Ei3}
+
+\noindent
+{\bf Ei4}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei4 is the first approximation of Ei where the result is
+   $x*e^-x*Ei(x)$ from 4 to 12 (preserves digits)
+\index{function!Ei4}
+
+\noindent
+{\bf Ei5}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei5 is the first approximation of Ei where the result is
+   $x*e^-x*Ei(x)$ from 12 to 32 (preserves digits)
+\index{function!Ei5}
+
+\noindent
+{\bf Ei6}: $(DoubleFloat) -> DoubleFloat$\hfill\newline
+   Ei6 is the first approximation of Ei where the result is
+   $x*e^-x*Ei(x)$ from 32 to infinity (preserves digits)
+\index{function!Ei6}
+
+\noindent
+{\bf besselJ}: $(F,F) -> F$\hfill\newline
+   $besselJ(v,z)$ is the Bessel function of the first kind,
+\index{function!Bessel}
+   $J_\nu (z)$.
+   This function satisfies the differential equation
+   $$z^2 w''(z) + z w'(z) + (z^2-\nu^2)w(z) = 0.$$
+
+\noindent
+{\bf besselY}: $(F,F) -> F$\hfill\newline
+   $besselY(v,z)$ is the Bessel function of the second kind,
+\index{function!Bessel}
+   $Y_\nu (z)$.
+   This function satisfies the same differential equation as
+   {\bf besselJ}.
+   The implementation simply uses the relation
+  $$Y_\nu (z) = \frac{J_\nu (z) \cos(\nu \pi) - J_{-\nu} (z)}{\sin(\nu \pi)}.$$
+
+\noindent
+{\bf besselI}: $(F,F) -> F$\hfill\newline
+   $besselI(v,z)$ is the modified Bessel function of the first kind,
+\index{function!Bessel}
+   $I_\nu (z)$.
+   This function satisfies the differential equation
+   $$z^2 w''(z) + z w'(z) - (z^2+\nu^2)w(z) = 0.$$
+
+\noindent
+{\bf besselK}: $(F,F) -> F$\hfill\newline
+   $besselK(v,z)$ is the modified Bessel function of the second kind,
+\index{function!Bessel}
+   $K_\nu (z)$.
+   This function satisfies the same differential equation as {\bf besselI}.
+\index{Bessel function}
+   The implementation simply uses the relation
+   $$K_\nu (z) = \pi \frac{I_{-\nu} (z) - I_{\nu} (z)}{2 \sin(\nu \pi)}.$$
+   
+
+\noindent
+{\bf airyAi}: $F -> F$\hfill\newline
+   $airyAi(z)$ is the Airy function $Ai(z)$.
+\index{function!Airy Ai}
+   This function satisfies the differential equation
+   $w''(z) - z w(z) = 0.$
+   The implementation simply uses the relation
+   $$Ai(-z) = \frac{1}{3}\sqrt{z} ( J_{-1/3} (\frac{2}{3}z^{3/2}) + J_{1/3} (\frac{2}{3}z^{3/2}) ).$$
+
+\noindent
+{\bf airyBi}: $F -> F$\hfill\newline
+   $airyBi(z)$ is the Airy function $Bi(z)$.
+\index{function!Airy Bi}
+   This function satisfies the same differential equation as {\bf airyAi}.
+\index{Airy function}
+   The implementation simply uses the relation
+   $$Bi(-z) = \frac{1}{3}\sqrt{3 z} ( J_{-1/3} (\frac{2}{3}z^{3/2}) - J_{1/3} (\frac{2}{3}z^{3/2}) ).$$
+   
+\noindent
+{\bf hypergeometric0F1}: $(F,F) -> F$\hfill\newline
+   $hypergeometric0F1(c,z)$ is the hypergeometric function
+\index{function!hypergeometric}
+   ${}_0 F_1 ( ; c; z)$.
+
+The above special functions are defined only for small floating-point types.
+If you give {\tt Float} arguments, they are converted to
+{\tt DoubleFloat} by Axiom.
+
+\spadcommand{Gamma(0.5)**2}
+$$
+3.14159265358979 
+$$
+\returnType{Type: DoubleFloat}
+
+\spadcommand{a := 2.1; b := 1.1; besselI(a + \%i*b, b*a + 1)}
+$$
+{2.489481690673867} -{{2.365846713181643} \  i} 
+$$
+\returnType{Type: Complex DoubleFloat}
+
+A number of additional operations may be used to compute numerical values.
+These are special polynomial functions that can be evaluated for values in
+any commutative ring $R$, and in particular for values in any
+floating-point type.
+The following operations are provided by the package
+{\tt OrthogonalPolynomialFunctions}:
+\index{OrthogonalPolynomialFunctions}
+
+\noindent
+{\bf chebyshevT}: $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $chebyshevT(n,z)$ is the $n$-th Chebyshev polynomial of the first
+   kind, $T_n (z)$.  These are defined by
+   $$\frac{1-t z}{1-2 t z+t^2} = \sum_{n=0}^{\infty} T_n (z) t^n.$$
+
+\noindent
+{\bf chebyshevU}: $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $chebyshevU(n,z)$ is the $n$-th Chebyshev polynomial of the second
+   kind, $U_n (z)$. These are defined by
+   $$\frac{1}{1-2 t z+t^2} = \sum_{n=0}^{\infty} U_n (z) t^n.$$
+
+\noindent
+{\bf hermiteH}:   $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $hermiteH(n,z)$ is the $n$-th Hermite polynomial,
+   $H_n (z)$.
+   These are defined by
+   $$e^{2 t z - t^2} = \sum_{n=0}^{\infty} H_n (z) \frac{t^n}{n!}.$$
+
+\noindent
+{\bf laguerreL}:  $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $laguerreL(n,z)$ is the $n$-th Laguerre polynomial,
+   $L_n (z)$.
+   These are defined by
+   $$\frac{e^{-\frac{t z}{1-t}}}{1-t} = \sum_{n=0}^{\infty} L_n (z) \frac{t^n}{n!}.$$
+
+\noindent
+{\bf laguerreL}:  $(NonNegativeInteger, NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $laguerreL(m,n,z)$ is the associated Laguerre polynomial,
+   $L^m_n (z)$.
+   This is the $m$-th derivative of $L_n (z)$.
+
+\noindent
+{\bf legendreP}:  $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $legendreP(n,z)$ is the $n$-th Legendre polynomial,
+   $P_n (z)$.  These are defined by
+   $$\frac{1}{\sqrt{1-2 t z+t^2}} = \sum_{n=0}^{\infty} P_n (z) t^n.$$
+
+These operations require non-negative integers for the indices, but otherwise
+the argument can be given as desired.
+
+\spadcommand{[chebyshevT(i, z) for i in 0..5]}
+$$
+\left[
+1,  z,  {{2 \  {z \sp 2}} -1},  {{4 \  {z \sp 3}} -{3 \  z}},  {{8 \  
+{z \sp 4}} -{8 \  {z \sp 2}}+1},  {{{16} \  {z \sp 5}} -{{20} \  {z \sp 
+3}}+{5 \  z}} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+The expression $chebyshevT(n,z)$ evaluates to the $n$-th Chebyshev
+\index{polynomial!Chebyshev!of the first kind}
+polynomial of the first kind.
+
+\spadcommand{chebyshevT(3, 5.0 + 6.0*\%i)}
+$$
+-{1675.0}+{{918.0} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+\spadcommand{chebyshevT(3, 5.0::DoubleFloat)}
+$$
+485.0 
+$$
+\returnType{Type: DoubleFloat}
+
+The expression $chebyshevU(n,z)$ evaluates to the $n$-th Chebyshev
+\index{polynomial!Chebyshev!of the second kind}
+polynomial of the second kind.
+
+\spadcommand{[chebyshevU(i, z) for i in 0..5]}
+$$
+\left[
+1,  {2 \  z},  {{4 \  {z \sp 2}} -1},  {{8 \  {z \sp 3}} -{4 \  z}},  
+{{{16} \  {z \sp 4}} -{{12} \  {z \sp 2}}+1},  {{{32} \  {z \sp 5}} -{{32} 
+\  {z \sp 3}}+{6 \  z}} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+\spadcommand{chebyshevU(3, 0.2)}
+$$
+-{0.736} 
+$$
+\returnType{Type: Float}
+
+The expression $hermiteH(n,z)$ evaluates to the $n$-th Hermite
+\index{polynomial!Hermite}
+polynomial.
+
+\spadcommand{[hermiteH(i, z) for i in 0..5]}
+$$
+\left[
+1,  {2 \  z},  {{4 \  {z \sp 2}} -2},  {{8 \  {z \sp 3}} -{{12} \  z}}, 
+ {{{16} \  {z \sp 4}} -{{48} \  {z \sp 2}}+{12}},  {{{32} \  {z \sp 5}} 
+-{{160} \  {z \sp 3}}+{{120} \  z}} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+\spadcommand{hermiteH(100, 1.0)}
+$$
+-{0.1448706729 337934088 E 93} 
+$$
+\returnType{Type: Float}
+
+The expression $laguerreL(n,z)$ evaluates to the $n$-th Laguerre
+\index{polynomial!Laguerre}
+polynomial.
+
+\spadcommand{[laguerreL(i, z) for i in 0..4]}
+$$
+\left[
+1,  {-z+1},  {{z \sp 2} -{4 \  z}+2},  {-{z \sp 3}+{9 \  {z \sp 2}} 
+-{{18} \  z}+6},  {{z \sp 4} -{{16} \  {z \sp 3}}+{{72} \  {z \sp 2}} 
+-{{96} \  z}+{24}} 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+\spadcommand{laguerreL(4, 1.2)}
+$$
+-{13.0944} 
+$$
+\returnType{Type: Float}
+
+\spadcommand{[laguerreL(j, 3, z) for j in 0..4]}
+$$
+\left[
+{-{z \sp 3}+{9 \  {z \sp 2}} -{{18} \  z}+6},  {-{3 \  {z \sp 2}}+{{18} \  
+z} -{18}},  {-{6 \  z}+{18}},  -6,  0 
+\right]
+$$
+\returnType{Type: List Polynomial Integer}
+
+\spadcommand{laguerreL(1, 3, 2.1)}
+$$
+6.57 
+$$
+\returnType{Type: Float}
+
+The expression
+\index{polynomial!Legendre}
+$legendreP(n,z)$ evaluates to the $n$-th Legendre polynomial,
+
+\spadcommand{[legendreP(i,z) for i in 0..5]}
+$$
+\left[
+1,  z,  {{{3 \over 2} \  {z \sp 2}} -{1 \over 2}},  {{{5 \over 2} \  {z 
+\sp 3}} -{{3 \over 2} \  z}},  {{{{35} \over 8} \  {z \sp 4}} -{{{15} \over 
+4} \  {z \sp 2}}+{3 \over 8}},  {{{{63} \over 8} \  {z \sp 5}} -{{{35} 
+\over 4} \  {z \sp 3}}+{{{15} \over 8} \  z}} 
+\right]
+$$
+\returnType{Type: List Polynomial Fraction Integer}
+
+\spadcommand{legendreP(3, 3.0*\%i)}
+$$
+-{{72.0} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+Finally, three number-theoretic polynomial operations may be evaluated.
+\index{number theory}
+The following operations are provided by the package
+{\tt NumberTheoreticPolynomialFunctions}.
+\index{NumberTheoreticPolynomialFunctions}.
+
+\noindent
+{\bf bernoulliB}: $(NonNegativeInteger, R) -> R$ \hbox{}\hfill\newline
+   $bernoulliB(n,z)$ is the $n$-th Bernoulli polynomial,
+\index{polynomial!Bernoulli}
+   $B_n (z)$.  These are defined by
+   $$\frac{t e^{z t}}{e^t - 1} = \sum_{n=0}^{\infty} B_n (z) \frac{t^n}{n!}.$$
+
+\noindent
+{\bf eulerE}: $(NonNegativeInteger, R) -> R$ \hbox{}\hfill\newline
+   $eulerE(n,z)$ is the $n$-th Euler polynomial,
+\index{Euler!polynomial}
+   $E_n (z)$.  These are defined by
+\index{polynomial!Euler}
+   $$\frac{2 e^{z t}}{e^t + 1} = \sum_{n=0}^{\infty} E_n (z) \frac{t^n}{n!}.$$
+
+\noindent
+{\bf cyclotomic}: $(NonNegativeInteger, R) -> R$\hbox{}\hfill\newline
+   $cyclotomic(n,z)$ is the $n$-th cyclotomic polynomial
+   $\Phi_n (z)$.  This is the polynomial whose
+   roots are precisely the primitive $n$-th roots of unity.
+\index{Euler!totient function}
+   This polynomial has degree given by the Euler totient function
+\index{function!totient}
+   $\phi(n)$.
+
+The expression $bernoulliB(n,z)$ evaluates to the $n$-th Bernoulli
+\index{polynomial!Bernouilli}
+polynomial.
+
+\spadcommand{bernoulliB(3, z)}
+$$
+{z \sp 3} -{{3 \over 2} \  {z \sp 2}}+{{1 \over 2} \  z} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+\spadcommand{bernoulliB(3, 0.7 + 0.4 * \%i)}
+$$
+-{0.138} -{{0.116} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+The expression
+\index{polynomial!Euler}
+$eulerE(n,z)$ evaluates to the $n$-th Euler polynomial.
+
+\spadcommand{eulerE(3, z)}
+$$
+{z \sp 3} -{{3 \over 2} \  {z \sp 2}}+{1 \over 4} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+\spadcommand{eulerE(3, 0.7 + 0.4 * \%i)}
+$$
+-{0.238} -{{0.316} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+The expression
+\index{polynomial!cyclotomic}
+$cyclotomic(n,z)$ evaluates to the $n$-th cyclotomic polynomial.
+\index{cyclotomic polynomial}
+
+\spadcommand{cyclotomic(3, z)}
+$$
+{z \sp 2}+z+1 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{cyclotomic(3, (-1.0 + 0.0 * \%i)**(2/3))}
+$$
+0.0 
+$$
+\returnType{Type: Complex Float}
+
+Drawing complex functions in Axiom is presently somewhat
+awkward compared to drawing real functions.
+It is necessary to use the {\bf draw} operations that operate
+on functions rather than expressions.
+
+This is the complex exponential function (rotated interactively).
+\index{function!complex exponential}
+When this is displayed in color, the height is the value of the real part of
+the function and the color is the imaginary part.
+Red indicates large negative imaginary values, green indicates imaginary
+values near zero and blue/violet indicates large positive imaginary values.
+
+\spadgraph{draw((x,y)+-> real exp complex(x,y), -2..2, -2*\%pi..2*\%pi, colorFunction == (x, y) +->  imag exp complex(x,y), title=="exp(x+\%i*y)", style=="smooth")}
+
+%\epsffile[0 0 295 295]{ps/compexp.ps}
+
+This is the complex arctangent function.
+\index{function!complex arctangent}
+Again, the height is the real part of the function value but here
+the color indicates the function value's phase.
+The position of the branch cuts are clearly visible and one can
+see that the function is real only for a real argument.
+
+\spadgraph{vp := draw((x,y) +-> real atan complex(x,y), -\%pi..\%pi, -\%pi..\%pi, colorFunction==(x,y) +->argument atan complex(x,y), title=="atan(x+\%i*y)", style=="shade"); rotate(vp,-160,-45); vp}
+
+%\epsffile[0 0 295 295]{ps/compatan.ps}
+
+This is the complex Gamma function.
+
+\spadgraph{draw((x,y) +-> max(min(real Gamma complex(x,y),4),-4), -\%pi..\%pi, -\%pi..\%pi, style=="shade", colorFunction == (x,y) +-> argument Gamma complex(x,y), title == "Gamma(x+\%i*y)", var1Steps == 50, var2Steps== 50)}
+
+%\epsffile[0 0 295 295]{ps/compgamm.ps}
+
+This shows the real Beta function near the origin.
+
+\spadgraph{draw(Beta(x,y)/100, x=-1.6..1.7, y = -1.6..1.7, style=="shade", title=="Beta(x,y)", var1Steps==40, var2Steps==40)}
+
+%\epsffile[0 0 295 295]{ps/realbeta.ps}
+
+This is the Bessel function $J_\alpha (x)$
+for index $\alpha$ in the range $-6..4$ and
+argument $x$ in the range $2..14$.
+
+\spadgraph{draw((alpha,x) +-> min(max(besselJ(alpha, x+8), -6), 6), -6..4, -6..6, title=="besselJ(alpha,x)", style=="shade", var1Steps==40, var2Steps==40)}
+
+%\epsffile[0 0 295 295]{ps/bessel.ps}
+
+This is the modified Bessel function
+$I_\alpha (x)$
+evaluated for various real values of the index $\alpha$
+and fixed argument $x = 5$.
+
+\spadgraph{draw(besselI(alpha, 5), alpha = -12..12, unit==[5,20])}
+
+%\epsffile[0 0 295 295]{ps/modbess.ps}
+
+This is similar to the last example
+except the index $\alpha$
+takes on complex values in a $6 x 6$ rectangle  centered on the origin.
+
+\spadgraph{draw((x,y) +-> real besselI(complex(x/20, y/20),5), -60..60, -60..60, colorFunction == (x,y)+-> argument besselI(complex(x/20,y/20),5), title=="besselI(x+i*y,5)", style=="shade")}
+
+%\epsffile[0 0 295 295]{ps/modbessc.ps}
+
+\section{Polynomial Factorization}
+\label{ugProblemFactor}
+
+%
+The Axiom polynomial factorization
+\index{polynomial!factorization}
+facilities are available for all polynomial types and a wide variety of
+coefficient domains.
+\index{factorization}
+Here are some examples.
+
+\subsection{Integer and Rational Number Coefficients}
+\label{ugProblemFactorIntRat}
+
+Polynomials with integer
+\index{polynomial!factorization!integer coefficients}
+coefficients can be be factored.
+
+\spadcommand{v := (4*x**3+2*y**2+1)*(12*x**5-x**3*y+12) }
+$$
+-{2 \  {x \sp 3} \  {y \sp 3}}+{{\left( {{24} \  {x \sp 5}}+{24} 
+\right)}
+\  {y \sp 2}}+{{\left( -{4 \  {x \sp 6}} -{x \sp 3} 
+\right)}
+\  y}+{{48} \  {x \sp 8}}+{{12} \  {x \sp 5}}+{{48} \  {x \sp 3}}+{12} 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{factor v }
+$$
+-{{\left( {{x \sp 3} \  y} -{{12} \  {x \sp 5}} -{12} 
+\right)}
+\  {\left( {2 \  {y \sp 2}}+{4 \  {x \sp 3}}+1 
+\right)}}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+Also, Axiom can factor polynomials with
+\index{polynomial!factorization!rational number coefficients}
+rational number coefficients.
+
+\spadcommand{w := (4*x**3+(2/3)*x**2+1)*(12*x**5-(1/2)*x**3+12) }
+$$
+{{48} \  {x \sp 8}}+{8 \  {x \sp 7}} -{2 \  {x \sp 6}}+{{{35} \over 3} \  {x 
+\sp 5}}+{{{95} \over 2} \  {x \sp 3}}+{8 \  {x \sp 2}}+{12} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+\spadcommand{factor w }
+$$
+{48} \  {\left( {x \sp 3}+{{1 \over 6} \  {x \sp 2}}+{1 \over 4} 
+\right)}
+\  {\left( {x \sp 5} -{{1 \over {24}} \  {x \sp 3}}+1 
+\right)}
+$$
+\returnType{Type: Factored Polynomial Fraction Integer}
+
+\subsection{Finite Field Coefficients}
+\label{ugProblemFactorFF}
+
+Polynomials with coefficients in a finite field
+\index{polynomial!factorization!finite field coefficients}
+can be also be factored.
+\index{finite field!factoring polynomial with coefficients in}
+
+\spadcommand{u : POLY(PF(19)) :=3*x**4+2*x**2+15*x+18 }
+$$
+{3 \  {x \sp 4}}+{2 \  {x \sp 2}}+{{15} \  x}+{18} 
+$$
+\returnType{Type: Polynomial PrimeField 19}
+
+These include the integers mod $p$, where $p$ is prime, and
+extensions of these fields.
+
+\spadcommand{factor u }
+$$
+3 \  {\left( x+{18} 
+\right)}
+\  {\left( {x \sp 3}+{x \sp 2}+{8 \  x}+{13} 
+\right)}
+$$
+\returnType{Type: Factored Polynomial PrimeField 19}
+
+Convert this to have coefficients in the finite
+field with $19^3$ elements.
+See \ref{ugProblemFinite} on page~\pageref{ugProblemFinite} 
+for more information about finite fields.
+
+\spadcommand{factor(u :: POLY FFX(PF 19,3)) }
+$$
+3 \  {\left( x+{18} 
+\right)}
+\  {\left( x+{5 \  { \%I \sp 2}}+{3 \  \%I}+{13} 
+\right)}
+\  {\left( x+{{16} \  { \%I \sp 2}}+{{14} \  \%I}+{13} 
+\right)}
+\  {\left( x+{{17} \  { \%I \sp 2}}+{2 \  \%I}+{13} 
+\right)}
+$$
+\returnType{Type: Factored Polynomial FiniteFieldExtension(PrimeField 19,3)}
+
+\subsection{Simple Algebraic Extension Field Coefficients}
+\label{ugProblemFactorAlg}
+
+Polynomials with coefficients in simple algebraic extensions
+\index{polynomial!factorization!algebraic extension field coefficients}
+of the rational numbers can be factored.
+\index{algebraic number}
+\index{number!algebraic}
+
+Here, $aa$ and $bb$ are symbolic roots of polynomials.
+
+\spadcommand{aa := rootOf(aa**2+aa+1) }
+$$
+aa 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{p:=(x**3+aa**2*x+y)*(aa*x**2+aa*x+aa*y**2)**2 }
+$$
+\begin{array}{@{}l}
+{{\left( -aa -1 \right)} \  {y \sp 5}}+
+{{\left( {{\left( -aa -1 \right)}\  {x \sp 3}}+
+{aa \  x} \right)}\  {y \sp 4}}+
+\\
+\\
+\displaystyle
+{{\left( {{\left( -{2 \  aa} -2 \right)}\  {x \sp 2}}+
+{{\left( -{2 \  aa} -2 \right)}\  x} \right)}\  {y \sp 3}}+
+\\
+\\
+\displaystyle
+{{\left( {{\left( -{2 \  aa} -2 \right)}\  {x \sp 5}}+
+{{\left( -{2 \  aa} -2 \right)}\  {x \sp 4}}+
+{2 \  aa \  {x \sp 3}}+{2 \  aa \  {x \sp 2}} \right)}\  {y \sp 2}}+
+\\
+\\
+\displaystyle
+{{\left( {{\left( -aa -1 \right)}\  {x \sp 4}}+
+{{\left( -{2 \  aa} -2 \right)}\  {x \sp 3}}+
+{{\left( -aa -1 \right)}\  {x \sp 2}} \right)}\  y}+
+\\
+\\
+\displaystyle
+{{\left( -aa -1 \right)}\  {x \sp 7}}+
+{{\left( -{2 \  aa} -2 \right)}\  {x \sp 6}} -
+{x \sp 5}+
+{2 \  aa \  {x \sp 4}}+
+{aa \  {x \sp 3}} 
+\end{array}
+$$
+\returnType{Type: Polynomial AlgebraicNumber}
+
+Note that the second argument to factor can be a list of
+algebraic extensions to factor over.
+
+\spadcommand{factor(p,[aa]) }
+%Note: this answer differs from the book but is equivalent.
+$$
+{\left( -aa -1 
+\right)}
+\  {\left( y+{x \sp 3}+{{\left( -aa -1 
+\right)}
+\  x} 
+\right)}
+\  {{\left( {y \sp 2}+{x \sp 2}+x 
+\right)}
+\sp 2} 
+$$
+\returnType{Type: Factored Polynomial AlgebraicNumber}
+
+This factors $x**2+3$ over the integers.
+
+\spadcommand{factor(x**2+3)}
+$$
+{x \sp 2}+3 
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+Factor the same polynomial over the field obtained by adjoining
+$aa$ to the rational numbers.
+
+\spadcommand{factor(x**2+3,[aa]) }
+$$
+{\left( x -{2 \  aa} -1 
+\right)}
+\  {\left( x+{2 \  aa}+1 
+\right)}
+$$
+\returnType{Type: Factored Polynomial AlgebraicNumber}
+
+Factor $x**6+108$ over the same field.
+
+\spadcommand{factor(x**6+108,[aa]) }
+$$
+{\left( {x \sp 3} -{{12} \  aa} -6 
+\right)}
+\  {\left( {x \sp 3}+{{12} \  aa}+6 
+\right)}
+$$
+\returnType{Type: Factored Polynomial AlgebraicNumber}
+
+\spadcommand{bb:=rootOf(bb**3-2) }
+$$
+bb 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{factor(x**6+108,[bb]) }
+$$
+{\left( {x \sp 2} -{3 \  bb \  x}+{3 \  {bb \sp 2}} 
+\right)}
+\  {\left( {x \sp 2}+{3 \  {bb \sp 2}} 
+\right)}
+\  {\left( {x \sp 2}+{3 \  bb \  x}+{3 \  {bb \sp 2}} 
+\right)}
+$$
+\returnType{Type: Factored Polynomial AlgebraicNumber}
+
+Factor again over the field obtained by adjoining both $aa$
+and $bb$ to the rational numbers.
+
+\spadcommand{factor(x**6+108,[aa,bb]) }
+$$
+\begin{array}{@{}l}
+{\left( x+{{\left( -{2 \  aa} -1 \right)}\  bb} \right)}
+\  {\left( x+{{\left( -aa -2 \right)}\  bb} \right)}
+\  {\left( x+{{\left( -aa+1 \right)}\  bb} \right)}
+\\
+\\
+\displaystyle
+\  {\left( x+{{\left( aa -1 \right)}\  bb} \right)}
+\  {\left( x+{{\left( aa+2 \right)}\  bb} \right)}
+\  {\left( x+{{\left( {2 \  aa}+1 \right)}\  bb} \right)}
+\end{array}
+$$
+\returnType{Type: Factored Polynomial AlgebraicNumber}
+
+\subsection{Factoring Rational Functions}
+\label{ugProblemFactorRatFun}
+
+Since fractions of polynomials form a field, every element (other than zero)
+\index{rational function!factoring}
+divides any other, so there is no useful notion of irreducible factors.
+Thus the {\bf factor} operation is not very useful for fractions
+of polynomials.
+
+There is, instead, a specific operation {\bf factorFraction}
+that separately factors the numerator and denominator and returns
+a fraction of the factored results.
+
+\spadcommand{factorFraction((x**2-4)/(y**2-4))}
+$$
+{{\left( x -2 
+\right)}
+\  {\left( x+2 
+\right)}}
+\over {{\left( y -2 
+\right)}
+\  {\left( y+2 
+\right)}}
+$$
+\returnType{Type: Fraction Factored Polynomial Integer}
+
+You can also use {\bf map}. This expression
+applies the {\bf factor} operation
+to the numerator and denominator.
+
+\spadcommand{map(factor,(x**2-4)/(y**2-4))}
+$$
+{{\left( x -2 
+\right)}
+\  {\left( x+2 
+\right)}}
+\over {{\left( y -2 
+\right)}
+\  {\left( y+2 
+\right)}}
+$$
+\returnType{Type: Fraction Factored Polynomial Integer}
+
+\section{Manipulating Symbolic Roots of a Polynomial}
+\label{ugProblemSymRoot}
+
+%
+In this section we show you how to work with one root or all roots
+\index{root!symbolic}
+of a polynomial.
+These roots are represented symbolically (as opposed to being
+numeric approximations).
+See \ref{ugxProblemOnePol} on page~\pageref{ugxProblemOnePol} and 
+\ref{ugxProblemPolSys} on page~\pageref{ugxProblemPolSys} for
+information about solving for the roots of one or more
+polynomials.
+
+\subsection{Using a Single Root of a Polynomial}
+\label{ugxProblemSymRootOne}
+
+Use {\bf rootOf} to get a symbolic root of a polynomial:
+$rootOf(p, x)$ returns a root of $p(x)$.
+
+This creates an algebraic number $a$.
+\index{algebraic number}
+\index{number!algebraic}
+
+\spadcommand{a := rootOf(a**4+1,a) }
+$$
+a 
+$$
+\returnType{Type: Expression Integer}
+
+To find the algebraic relation that defines $a$,
+use {\bf definingPolynomial}.
+
+\spadcommand{definingPolynomial a }
+$$
+{a \sp 4}+1 
+$$
+\returnType{Type: Expression Integer}
+
+You can use $a$ in any further expression,
+including a nested {\bf rootOf}.
+
+\spadcommand{b := rootOf(b**2-a-1,b) }
+$$
+b 
+$$
+\returnType{Type: Expression Integer}
+
+Higher powers of the roots are automatically reduced during
+calculations.
+
+\spadcommand{a + b }
+$$
+b+a 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{\% ** 5 }
+$$
+{{\left( {{10} \  {a \sp 3}}+{{11} \  {a \sp 2}}+{2 \  a} -4 
+\right)}
+\  b}+{{15} \  {a \sp 3}}+{{10} \  {a \sp 2}}+{4 \  a} -{10} 
+$$
+\returnType{Type: Expression Integer}
+
+The operation {\bf zeroOf} is similar to {\bf rootOf},
+except that it may express the root using radicals in some cases.
+\index{radical}
+
+\spadcommand{rootOf(c**2+c+1,c)}
+$$
+c 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{zeroOf(d**2+d+1,d)}
+$$
+{{\sqrt {-3}} -1} \over 2 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{rootOf(e**5-2,e)}
+$$
+e 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{zeroOf(f**5-2,f)}
+$$
+\root {5} \of {2} 
+$$
+\returnType{Type: Expression Integer}
+
+\subsection{Using All Roots of a Polynomial}
+\label{ugxProblemSymRootAll}
+
+Use {\bf rootsOf} to get all symbolic roots of a polynomial:
+$rootsOf(p, x)$ returns a
+list of all the roots of $p(x)$.
+If $p(x)$ has a multiple root of order $n$, then that root
+\index{root!multiple}
+appears $n$ times in the list.
+\typeout{Make sure these variables are x0 etc}
+
+Compute all the roots of $x**4 + 1$.
+
+\spadcommand{l := rootsOf(x**4+1,x) }
+$$
+\left[
+ \%x0,  { \%x0 \  \%x1},  - \%x0,  -{ \%x0 \  \%x1} 
+\right]
+$$
+\returnType{Type: List Expression Integer}
+
+As a side effect, the variables $\%x0, \%x1$ and $\%x2$ are bound
+to the first three roots of $x**4+1$.
+
+\spadcommand{\%x0**5 }
+$$
+- \%x0 
+$$
+\returnType{Type: Expression Integer}
+
+Although they all satisfy $x**4 + 1 = 0, \%x0, \%x1,$
+and $\%x2$ are different algebraic numbers.
+To find the algebraic relation that defines each of them,
+use {\bf definingPolynomial}.
+
+\spadcommand{definingPolynomial \%x0 }
+$$
+{ \%x0 \sp 4}+1 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{definingPolynomial \%x1 }
+$$
+{ \%x1 \sp 2}+1 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{definingPolynomial \%x2 }
+$$
+- \%x2+ \%\%var 
+$$
+\returnType{Type: Expression Integer}
+
+We can check that the sum and product of the roots of $x**4+1$ are
+its trace and norm.
+
+\spadcommand{x3 := last l  }
+$$
+-{ \%x0 \  \%x1} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{\%x0 + \%x1 + \%x2 + x3 }
+$$
+{{\left( - \%x0+1 
+\right)}
+\  \%x1}+ \%x0+ \%x2 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{\%x0 * \%x1 * \%x2 * x3 }
+$$
+ \%x2 \  { \%x0 \sp 2} 
+$$
+\returnType{Type: Expression Integer}
+
+Corresponding to the pair of operations
+{\bf rootOf}/{\bf zeroOf} in
+\ref{ugxProblemOnePol} on page~\pageref{ugxProblemOnePol}, there is
+an operation {\bf zerosOf} that, like {\bf rootsOf},
+computes all the roots
+of a given polynomial, but which expresses some of them in terms of
+radicals.
+
+\spadcommand{zerosOf(y**4+1,y) }
+$$
+\left[
+{{{\sqrt {-1}}+1} \over {\sqrt {2}}},  {{{\sqrt {-1}} -1} \over {\sqrt 
+{2}}},  {{-{\sqrt {-1}} -1} \over {\sqrt {2}}},  {{-{\sqrt {-1}}+1} \over 
+{\sqrt {2}}} 
+\right]
+$$
+\returnType{Type: List Expression Integer}
+
+As you see, only one implicit algebraic number was created
+($\%y1$), and its defining equation is this.
+The other three roots are expressed in radicals.
+
+\spadcommand{definingPolynomial \%y1 }
+$$
+{ \%\%var \sp 2}+1 
+$$
+\returnType{Type: Expression Integer}
+
+\section{Computation of Eigenvalues and Eigenvectors}
+\label{ugProblemEigen}
+%
+In this section we show you
+some of Axiom's facilities for computing and
+\index{eigenvalue}
+manipulating eigenvalues and eigenvectors, also called
+\index{eigenvector}
+characteristic values and characteristic vectors,
+\index{characteristic!value}
+respectively.
+\index{characteristic!vector}
+
+\vskip 4pc
+
+Let's first create a matrix with integer entries.
+
+\spadcommand{m1 := matrix [ [1,2,1],[2,1,-2],[1,-2,4] ] }
+$$
+\left[
+\begin{array}{ccc}
+1 & 2 & 1 \\ 
+2 & 1 & -2 \\ 
+1 & -2 & 4 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+To get a list of the {\it rational} eigenvalues,
+use the operation {\bf eigenvalues}.
+
+\spadcommand{leig := eigenvalues(m1)  }
+$$
+\left[
+5,  {\left( \%K \mid {{ \%K \sp 2} - \%K -5} 
+\right)}
+\right]
+$$
+\returnType{Type: List Union(Fraction Polynomial Integer,SuchThat(Symbol,Polynomial Integer))}
+
+Given an explicit eigenvalue, {\bf eigenvector} computes the eigenvectors
+corresponding to it.
+
+\spadcommand{eigenvector(first(leig),m1) }
+$$
+\left[
+{\left[ 
+\begin{array}{c}
+0 \\ 
+-{1 \over 2} \\ 
+1 
+\end{array}
+\right]}
+\right]
+$$
+\returnType{Type: List Matrix Fraction Polynomial Fraction Integer}
+
+The operation {\bf eigenvectors} returns a list of pairs of values and
+vectors. When an eigenvalue is rational, Axiom gives you
+the value explicitly; otherwise, its minimal polynomial is given,
+(the polynomial of lowest degree with the eigenvalues as roots),
+together with a parametric representation of the eigenvector using the
+eigenvalue.
+This means that if you ask Axiom to {\bf solve}
+the minimal polynomial, then you can substitute these roots
+\index{polynomial!minimal}
+into the parametric form of the corresponding eigenvectors.
+\index{minimal polynomial}
+
+You must be aware that unless an exact eigenvalue has been computed,
+the eigenvector may be badly in error.
+
+\spadcommand{eigenvectors(m1) }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {eigval=5},  {eigmult=1},  {eigvec=
+{\left[ 
+{\left[ 
+\begin{array}{c}
+0 \\ 
+-{1 \over 2} \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]},
+\right.
+\\
+\\
+\displaystyle
+\left.
+{\left[ 
+{eigval={\left( \%L \mid {{ \%L \sp 2} - \%L -5} \right)}},
+{eigmult=1},  {eigvec=
+{\left[ 
+{\left[ 
+\begin{array}{c}
+ \%L \\ 
+2 \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List Record(eigval: Union(Fraction Polynomial Integer,SuchThat(Symbol,Polynomial Integer)),eigmult: NonNegativeInteger,eigvec: List Matrix Fraction Polynomial Integer)}
+
+Another possibility is to use the operation
+{\bf radicalEigenvectors}
+tries to compute explicitly the eigenvectors
+in terms of radicals.
+\index{radical}
+
+\spadcommand{radicalEigenvectors(m1) }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {radval={{{\sqrt {{21}}}+1} \over 2}},  {radmult=1},  
+{radvect={\left[ {\left[ 
+\begin{array}{c}
+{{{\sqrt {{21}}}+1} \over 2} \\ 
+2 \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]},
+\right.
+\\
+\\
+\displaystyle
+ \left[ {radval={{-{\sqrt {{21}}}+1} \over 2}},  {radmult=1},  
+{radvect={\left[ {\left[ 
+\begin{array}{c}
+{{-{\sqrt {{21}}}+1} \over 2} \\ 
+2 \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right],
+\\
+\\
+\displaystyle
+\left.
+ \left[ {radval=5},  {radmult=1},  
+{radvect={\left[ {\left[ 
+\begin{array}{c}
+0 \\ 
+-{1 \over 2} \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]
+\right]
+\end{array}
+$$
+\returnType{Type: List Record(radval: Expression Integer,radmult: Integer,radvect: List Matrix Expression Integer)}
+
+Alternatively, Axiom can compute real or complex approximations to the
+\index{approximation}
+eigenvectors and eigenvalues using the operations {\bf realEigenvectors}
+or {\bf complexEigenvectors}.
+They each take an additional argument $\epsilon$
+to specify the ``precision'' required.
+\index{precision}
+In the real case, this means that each approximation will be within
+$\pm\epsilon$ of the actual
+result.
+In the complex case, this means that each approximation will be within
+$\pm\epsilon$ of the actual result
+in each of the real and imaginary parts.
+
+The precision can be specified as a {\tt Float} if the results are
+desired in floating-point notation, or as {\tt Fraction Integer} if the
+results are to be expressed using rational (or complex rational) numbers.
+
+\spadcommand{realEigenvectors(m1,1/1000) }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {outval=5},  {outmult=1},  {outvect={\left[ {\left[ 
+\begin{array}{c}
+0 \\ 
+-{1 \over 2} \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]},
+\right.
+\\
+\\
+\displaystyle
+ {\left[ {outval={{5717} \over {2048}}},  {outmult=1},  
+{outvect={\left[ {\left[ 
+\begin{array}{c}
+{{5717} \over {2048}} \\ 
+2 \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]},
+\\
+\\
+\displaystyle
+\left.
+ {\left[ {outval=-{{3669} \over {2048}}},  {outmult=1},  
+{outvect={\left[ {\left[ 
+\begin{array}{c}
+-{{3669} \over {2048}} \\ 
+2 \\ 
+1 
+\end{array}
+\right]}
+\right]}}
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List Record(outval: Fraction Integer,outmult: Integer,outvect: List Matrix Fraction Integer)}
+
+If an $n$ by $n$ matrix has $n$ distinct eigenvalues (and
+therefore $n$ eigenvectors) the operation {\bf eigenMatrix}
+gives you a matrix of the eigenvectors.
+
+\spadcommand{eigenMatrix(m1) }
+$$
+\left[
+\begin{array}{ccc}
+{{{\sqrt {{21}}}+1} \over 2} & {{-{\sqrt {{21}}}+1} \over 2} & 0 \\ 
+2 & 2 & -{1 \over 2} \\ 
+1 & 1 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: Union(Matrix Expression Integer,...)}
+
+\spadcommand{m2 := matrix [ [-5,-2],[18,7] ] }
+$$
+\left[
+\begin{array}{cc}
+-5 & -2 \\ 
+{18} & 7 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+\spadcommand{eigenMatrix(m2) }
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+If a symmetric matrix
+\index{matrix!symmetric}
+has a basis of orthonormal eigenvectors, then
+\index{basis!orthonormal}
+{\bf orthonormalBasis} computes a list of these vectors.
+\index{orthonormal basis}
+
+\spadcommand{m3 := matrix [ [1,2],[2,1] ] }
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+2 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+\spadcommand{orthonormalBasis(m3) }
+$$
+\left[
+{\left[ 
+\begin{array}{c}
+-{1 \over {\sqrt {2}}} \\ 
+{1 \over {\sqrt {2}}} 
+\end{array}
+\right]},
+ {\left[ 
+\begin{array}{c}
+{1 \over {\sqrt {2}}} \\ 
+{1 \over {\sqrt {2}}} 
+\end{array}
+\right]}
+\right]
+$$
+\returnType{Type: List Matrix Expression Integer}
+
+\section{Solution of Linear and Polynomial Equations}
+\label{ugProblemLinPolEqn}
+%
+In this section we discuss the Axiom facilities for solving
+systems of linear equations, finding the roots of polynomials and
+\index{linear equation}
+solving systems of polynomial equations.
+For a discussion of the solution of differential equations, see
+\ref{ugProblemDEQ} on page~\pageref{ugProblemDEQ}.
+
+\subsection{Solution of Systems of Linear Equations}
+\label{ugxProblemLinSys}
+
+You can use the operation {\bf solve} to solve systems of linear equations.
+\index{equation!linear!solving}
+
+The operation {\bf solve} takes two arguments, the list of equations and the
+list of the unknowns to be solved for.
+A system of linear equations need not have a unique solution.
+
+To solve the linear system:
+$$
+\begin{array}{rcrcrcr}
+  x &+&   y &+&   z &=& 8 \\
+3 x &-& 2 y &+&   z &=& 0 \\
+  x &+& 2 y &+& 2 z &=& 17
+\end{array}
+$$
+evaluate this expression.
+
+\spadcommand{solve([x+y+z=8,3*x-2*y+z=0,x+2*y+2*z=17],[x,y,z])}
+$$
+\left[
+{\left[ {x=-1},  {y=2},  {z=7} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+Parameters are given as new variables starting with a percent sign and
+{\tt \%} and
+the variables are expressed in terms of the parameters.
+If the system has no solutions then the empty list is returned.
+
+When you solve the linear system
+$$
+\begin{array}{rcrcrcr}
+  x&+&2 y&+&3 z&=&2 \\
+2 x&+&3 y&+&4 z&=&2 \\
+3 x&+&4 y&+&5 z&=&2
+\end{array}
+$$
+with this expression
+you get a solution involving a parameter.
+
+\spadcommand{solve([x+2*y+3*z=2,2*x+3*y+4*z=2,3*x+4*y+5*z=2],[x,y,z])}
+$$
+\left[
+{\left[ {x={ \%Q -2}},  {y={-{2 \  \%Q}+2}},  {z= \%Q} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+The system can also be presented as a matrix and a vector.
+The matrix contains the coefficients of the linear equations and
+the vector contains the numbers appearing on the right-hand sides
+of the equations.
+You may input the matrix as a list of rows and the vector as a
+list of its elements.
+
+To solve the system:
+$$
+\begin{array}{rcrcrcr}
+  x&+&  y&+&  z&=&8  \\
+3 x&-&2 y&+&  z&=&0  \\
+  x&+&2 y&+&2 z&=&17
+\end{array}
+$$
+in matrix form you would evaluate this expression.
+
+\spadcommand{solve([ [1,1,1],[3,-2,1],[1,2,2] ],[8,0,17])}
+$$
+\left[
+{particular={\left[ -1, 2,  7\right]}},
+{basis={\left[ {\left[ 0, 0, 0\right]}\right]}}
+\right]
+$$
+\returnType{Type: Record(particular: Union(Vector Fraction Integer,"failed"),
+basis: List Vector Fraction Integer)}
+
+The solutions are presented as a {\tt Record} with two
+components: the component {\it particular} contains a particular solution of the given system or
+the item {\tt "failed"} if there are no solutions, the component
+{\it basis} contains a list of vectors that
+are a basis for the space of solutions of the corresponding
+homogeneous system.
+If the system of linear equations does not have a unique solution,
+then the {\it basis} component contains
+non-trivial vectors.
+
+This happens when you solve the linear system
+$$
+\begin{array}{rcrcrcr}
+  x&+&2 y&+&3 z&=&2 \\
+2 x&+&3 y&+&4 z&=&2 \\
+3 x&+&4 y&+&5 z&=&2
+\end{array}
+$$
+with this command.
+
+\spadcommand{solve([ [1,2,3],[2,3,4],[3,4,5] ],[2,2,2])}
+$$
+\left[
+{particular={\left[ -2, 2, 0 \right]}},
+{basis={\left[ {\left[ 1, -2, 1 \right]}\right]}}
+\right]
+$$
+\returnType{Type: Record(particular: Union(Vector Fraction Integer,"failed"),
+basis: List Vector Fraction Integer)}
+
+
+All solutions of this system are obtained by adding the particular
+solution with a linear combination of the {\it basis} vectors.
+
+When no solution exists then {\tt "failed"} is returned as the
+{\it particular} component, as follows:
+
+\spadcommand{solve([ [1,2,3],[2,3,4],[3,4,5] ],[2,3,2])}
+$$
+\left[
+{particular= \mbox{\tt "failed"} }, 
+{basis={\left[ {\left[ 1, -2, 1\right]}\right]}}
+\right]
+$$
+\returnType{Type: Record(particular: Union(Vector Fraction Integer,"failed"),
+basis: List Vector Fraction Integer)}
+
+When you want to solve a system of homogeneous equations (that is,
+a system where the numbers on the right-hand sides of the
+\index{nullspace}
+equations are all zero) in the matrix form you can omit the second
+argument and use the {\bf nullSpace} operation.
+
+This computes the solutions of the following system of equations:
+$$
+\begin{array}{rcrcrcr}
+  x&+&2 y&+&3 z&=&0  \\
+2 x&+&3 y&+&4 z&=&0  \\
+3 x&+&4 y&+&5 z&=&0
+\end{array}
+$$
+The result is given as a list of vectors and
+these vectors form a basis for the solution space.
+
+\spadcommand{nullSpace([ [1,2,3],[2,3,4],[3,4,5] ])}
+$$
+\left[
+{\left[ 1, -2, 1 \right]}
+\right]
+$$
+\returnType{Type: List Vector Integer}
+
+\subsection{Solution of a Single Polynomial Equation}
+\label{ugxProblemOnePol}
+
+Axiom can solve polynomial equations producing either approximate
+\index{polynomial!root finding}
+or exact solutions.
+\index{equation!polynomial!solving}
+Exact solutions are either members of the ground
+field or can be presented symbolically as roots of irreducible polynomials.
+
+This returns the one rational root along with an irreducible
+polynomial describing the other solutions.
+
+\spadcommand{solve(x**3  = 8,x)}
+$$
+\left[
+{x=2},  {{{x \sp 2}+{2 \  x}+4}=0} 
+\right]
+$$
+\returnType{Type: List Equation Fraction Polynomial Integer}
+
+If you want solutions expressed in terms of radicals you would use this
+instead.
+\index{radical}
+
+\spadcommand{radicalSolve(x**3  = 8,x)}
+$$
+\left[
+{x={-{\sqrt {-3}} -1}}, {x={{\sqrt {-3}} -1}}, {x=2} 
+\right]
+$$
+\returnType{Type: List Equation Expression Integer}
+
+The {\bf solve} command always returns a value but
+{\bf radicalSolve} returns only the solutions that it is
+able to express in terms of radicals.
+\index{radical}
+
+If the polynomial equation has rational coefficients
+you can ask for approximations to its real roots by calling
+solve with a second argument that specifies the ``precision''
+\index{precision}
+$\epsilon$.
+This means that each approximation will be within
+$\pm\epsilon$ of the actual
+result.
+
+Notice that the type of second argument controls the type of the result.
+
+\spadcommand{solve(x**4 - 10*x**3 + 35*x**2 - 50*x + 25,.0001)}
+$$
+\left[
+{x={3.6180114746 09375}}, {x={1.3819885253 90625}} 
+\right]
+$$
+\returnType{Type: List Equation Polynomial Float}
+
+If you give a floating-point precision you get a floating-point result;
+if you give the precision as a rational number you get a rational result.
+
+\spadcommand{solve(x**3-2,1/1000)}
+$$
+\left[
+{x={{2581} \over {2048}}} 
+\right]
+$$
+\returnType{Type: List Equation Polynomial Fraction Integer}
+
+If you want approximate complex results you should use the
+\index{approximation}
+command {\bf complexSolve} that takes the same precision argument
+$\epsilon$.
+
+\spadcommand{complexSolve(x**3-2,.0001)}
+$$
+\begin{array}{@{}l}
+\left[
+{x={1.2599182128 90625}},
+\right.
+\\
+\\
+\displaystyle
+{x={-{0.6298943279 5395613131} -{{1.0910949707 03125} \  i}}}, 
+\\
+\\
+\displaystyle
+\left.
+{x={-{0.6298943279 5395613131}+{{1.0910949707 03125} \  
+i}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List Equation Polynomial Complex Float}
+
+Each approximation will be within
+$\pm\epsilon$ of the actual result
+in each of the real and imaginary parts.
+
+\spadcommand{complexSolve(x**2-2*\%i+1,1/100)}
+$$
+\left[
+{x={-{{13028925} \over {16777216}} -{{{325} \over {256}} \  i}}}, 
+{x={{{13028925} \over {16777216}}+{{{325} \over {256}} \  i}}} 
+\right]
+$$
+\returnType{Type: List Equation Polynomial Complex Fraction Integer}
+
+Note that if you omit the {\tt =} from the first argument
+Axiom generates an equation by equating the first argument to zero.
+Also, when only one variable is present in the equation, you
+do not need to specify the variable to be solved for, that is,
+you can omit the second argument.
+
+Axiom can also solve equations involving rational functions.
+Solutions where the denominator vanishes are discarded.
+
+\spadcommand{radicalSolve(1/x**3 + 1/x**2 + 1/x = 0,x)}
+$$
+\left[
+{x={{-{\sqrt {-3}} -1} \over 2}}, {x={{{\sqrt {-3}} -1} \over 2}} 
+\right]
+$$
+\returnType{Type: List Equation Expression Integer}
+
+\subsection{Solution of Systems of Polynomial Equations}
+\label{ugxProblemPolSys}
+
+Given a system of equations of rational functions with exact coefficients:
+\index{equation!polynomial!solving}
+\vskip 0.1cm
+$$
+\begin{array}{c}
+p_1(x_1, \ldots, x_n) \\ \vdots \\ p_m(x_1,\ldots,x_n)
+\end{array}
+$$
+
+Axiom can find
+numeric or symbolic solutions.
+The system is first split into irreducible components, then for
+each component, a triangular system of equations is found that reduces
+the problem to sequential solution of univariate polynomials resulting
+from substitution of partial solutions from the previous stage.
+$$
+\begin{array}{c}
+q_1(x_1, \ldots, x_n) \\ \vdots \\ q_m(x_n)
+\end{array}
+$$
+
+Symbolic solutions can be presented using ``implicit'' algebraic numbers
+defined as roots of irreducible polynomials or in terms of radicals.
+Axiom can also find approximations to the real or complex roots
+of a system of polynomial equations to any user-specified accuracy.
+
+The operation {\bf solve} for systems is used in a way similar
+to {\bf solve} for single equations.
+Instead of a polynomial equation, one has to give a list of
+equations and instead of a single variable to solve for, a list of
+variables.
+For solutions of single equations see 
+\ref{ugxProblemOnePol} on page~\pageref{ugxProblemOnePol}.
+
+Use the operation {\bf solve} if you want implicitly presented
+solutions.
+
+\spadcommand{solve([3*x**3 + y + 1,y**2 -4],[x,y])}
+$$
+\left[
+{\left[ {x=-1}, {y=2} \right]},
+{\left[ {{{x \sp 2} -x+1}=0}, {y=2} \right]},
+{\left[ {{{3 \  {x \sp 3}} -1}=0}, {y=-2} \right]}
+\right]
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+\spadcommand{solve([x = y**2-19,y = z**2+x+3,z = 3*x],[x,y,z])}
+$$
+\left[
+{\left[ {x={z \over 3}}, 
+{y={{{3 \  {z \sp 2}}+z+9} \over 3}}, 
+{{{9 \  {z \sp 4}}+{6 \  {z \sp 3}}+{{55} \  {z \sp 2}}+{{15} \  z} -{90}}=0} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+Use {\bf radicalSolve} if you want your solutions expressed
+in terms of radicals.
+
+\spadcommand{radicalSolve([3*x**3 + y + 1,y**2 -4],[x,y])}
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {x={{{\sqrt {-3}}+1} \over 2}}, {y=2} \right]},
+{\left[ {x={{-{\sqrt {-3}}+1} \over 2}}, {y=2} \right]},
+\right.
+\\
+\\
+\displaystyle
+{\left[ {x={{-{{\sqrt {-1}} \  {\sqrt {3}}} -1} \over {2 \  {\root {3} \of 
+{3}}}}}, {y=-2} \right]},
+{\left[ {x={{{{\sqrt {-1}} \  {\sqrt {3}}} -1} \over {2 \  {\root {3} \of 
+{3}}}}}, {y=-2} \right]},
+\\
+\\
+\displaystyle
+\left.
+{\left[ {x={1 \over {\root {3} \of {3}}}}, {y=-2} \right]},
+{\left[ {x=-1}, {y=2} \right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List List Equation Expression Integer}
+
+To get numeric solutions you only need to give the list of
+equations and the precision desired.
+The list of variables would be redundant information since there
+can be no parameters for the numerical solver.
+
+If the precision is expressed as a floating-point number you get
+results expressed as floats.
+
+\spadcommand{solve([x**2*y - 1,x*y**2 - 2],.01)}
+$$
+\left[
+{\left[ {y={1.5859375}}, {x={0.79296875}} \right]}
+\right]
+$$
+\returnType{Type: List List Equation Polynomial Float}
+
+To get complex numeric solutions, use the operation {\bf complexSolve},
+which takes the same arguments as in the real case.
+
+\spadcommand{complexSolve([x**2*y - 1,x*y**2 - 2],1/1000)}
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {y={{1625} \over {1024}}}, {x={{1625} \over {2048}}} \right]},
+\right.
+\\
+\\
+\displaystyle
+{\left[ {y={-{{435445573689} \over {549755813888}} -{{{1407} \over {1024}} 
+\  i}}}, 
+{x={-{{435445573689} \over {1099511627776}} -{{{1407} \over {2048}} \  i}}} 
+\right]},
+\\
+\\
+\displaystyle
+\left.
+{\left[ {y={-{{435445573689} \over {549755813888}}+{{{1407} \over {1024}} 
+\  i}}}, 
+{x={-{{435445573689} \over {1099511627776}}+{{{1407} \over {2048}} \  i}}} 
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List List Equation Polynomial Complex Fraction Integer}
+
+
+It is also possible to solve systems of equations in rational functions
+over the rational numbers.
+Note that $[x = 0.0, a = 0.0]$ is not returned as a solution since
+the denominator vanishes there.
+
+\spadcommand{solve([x**2/a = a,a = a*x],.001)}
+$$
+\left[
+{\left[ {x={1.0}}, {a=-{1.0}} \right]},
+{\left[ {x={1.0}}, {a={1.0}} \right]}
+\right]
+$$
+\returnType{Type: List List Equation Polynomial Float}
+
+
+When solving equations with
+denominators, all solutions where the denominator vanishes are
+discarded.
+
+\spadcommand{radicalSolve([x**2/a + a + y**3 - 1,a*y + a + 1],[x,y])}
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {x=-{\sqrt {{{-{a \sp 4}+{2 \  {a \sp 3}}+{3 \  {a \sp 2}}+{3 \  
+a}+1} \over {a \sp 2}}}}}, {y={{-a -1} \over a}} 
+\right]},
+\right.
+\\
+\\
+\displaystyle
+\left.
+{\left[ {x={\sqrt {{{-{a \sp 4}+{2 \  {a \sp 3}}+{3 \  {a \sp 2}}+{3 \  
+a}+1} \over {a \sp 2}}}}}, {y={{-a -1} \over a}} 
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List List Equation Expression Integer}
+
+\section{Limits}
+\label{ugProblemLimits}
+
+%
+To compute a limit, you must specify a functional expression,
+\index{limit}
+a variable, and a limiting value for that variable.
+If you do not specify a direction, Axiom attempts to
+compute a two-sided limit.
+
+Issue this to compute the limit
+$$\lim_{x \rightarrow 1}{{\displaystyle x^2 - 3x +
+2}\over{\displaystyle x^2 - 1}}.$$
+
+\spadcommand{limit((x**2 - 3*x + 2)/(x**2 - 1),x = 1)}
+$$
+-{1 \over 2} 
+$$
+\returnType{Type: Union(OrderedCompletion Fraction Polynomial Integer,...)}
+
+Sometimes the limit when approached from the left is different from
+the limit from the right and, in this case, you may wish to ask for a
+one-sided limit.  Also, if you have a function that is only defined on
+one side of a particular value, \index{limit!one-sided vs. two-sided}
+you can compute a one-sided limit.
+
+The function $log(x)$ is only defined to the right of zero, that is,
+for $x > 0$.  Thus, when computing limits of functions involving
+$log(x)$, you probably want a ``right-hand'' limit.
+
+\spadcommand{limit(x * log(x),x = 0,"right")}
+$$
+0 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+When you do not specify ``$right$'' or ``$left$'' as the optional fourth
+argument, {\bf limit} tries to compute a two-sided limit.  Here the
+limit from the left does not exist, as Axiom indicates when you try to
+take a two-sided limit.
+
+\spadcommand{limit(x * log(x),x = 0)}
+$$
+\left[
+{leftHandLimit= \mbox{\tt "failed"} }, {rightHandLimit=0} 
+\right]
+$$
+\returnType{Type: Union(Record(leftHandLimit: 
+Union(OrderedCompletion Expression Integer,"failed"),
+rightHandLimit: Union(OrderedCompletion Expression Integer,"failed")),...)}
+
+A function can be defined on both sides of a particular value, but
+tend to different limits as its variable approaches that value from
+the left and from the right.  We can construct an example of this as
+follows: Since $\sqrt{y^2}$ is simply the absolute value of $y$, the
+function $\sqrt{y^2} / y$ is simply the sign ($+1$ or $-1$) of the
+nonzero real number $y$.  Therefore, $\sqrt{y^2} / y = -1$ for $y < 0$
+and $\sqrt{y^2} / y = +1$ for $y > 0$.
+
+This is what happens when we take the limit at $y = 0$.
+The answer returned by Axiom gives both a
+``left-hand'' and a ``right-hand'' limit.
+
+\spadcommand{limit(sqrt(y**2)/y,y = 0)}
+$$
+\left[
+{leftHandLimit=-1}, {rightHandLimit=1} 
+\right]
+$$
+\returnType{Type: Union(Record(leftHandLimit: 
+Union(OrderedCompletion Expression Integer,"failed"),
+rightHandLimit: Union(OrderedCompletion Expression Integer,"failed")),...)}
+
+Here is another example, this time using a more complicated function.
+
+\spadcommand{limit(sqrt(1 - cos(t))/t,t = 0)}
+$$
+\left[
+{leftHandLimit=-{1 \over {\sqrt {2}}}}, 
+{rightHandLimit={1 \over {\sqrt {2}}}} 
+\right]
+$$
+\returnType{Type: Union(Record(leftHandLimit: 
+Union(OrderedCompletion Expression Integer,"failed"),
+rightHandLimit: Union(OrderedCompletion Expression Integer,"failed")),...)}
+
+You can compute limits at infinity by passing either 
+\index{limit!at infinity} $+\infty$ or $-\infty$ as the third 
+argument of {\bf limit}.
+
+To do this, use the constants $\%plusInfinity$ and $\%minusInfinity$.
+
+\spadcommand{limit(sqrt(3*x**2 + 1)/(5*x),x = \%plusInfinity)}
+$$
+{\sqrt {3}} \over 5 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+\spadcommand{limit(sqrt(3*x**2 + 1)/(5*x),x = \%minusInfinity)}
+$$
+-{{\sqrt {3}} \over 5} 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+You can take limits of functions with parameters.
+\index{limit!of function with parameters}
+As you can see, the limit is expressed in terms of the parameters.
+
+\spadcommand{limit(sinh(a*x)/tan(b*x),x = 0)}
+$$
+a \over b 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+When you use {\bf limit}, you are taking the limit of a real
+function of a real variable.
+
+When you compute this, Axiom returns $0$ because, as a function of a
+real variable, $sin(1/z)$ is always between $-1$ and $1$, so 
+$z * sin(1/z)$ tends to $0$ as $z$ tends to $0$.
+
+\spadcommand{limit(z * sin(1/z),z = 0)}
+$$
+0 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+However, as a function of a {\it complex} variable, $sin(1/z)$ is badly
+\index{limit!real vs. complex}
+behaved near $0$ (one says that $sin(1/z)$ has an
+\index{essential singularity}
+{\it essential singularity} at $z = 0$).
+\index{singularity!essential}
+
+When viewed as a function of a complex variable, $z * sin(1/z)$
+does not approach any limit as $z$ tends to $0$ in the complex plane.
+Axiom indicates this when we call {\bf complexLimit}.
+
+\spadcommand{complexLimit(z * sin(1/z),z = 0)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+Here is another example.
+As $x$ approaches $0$ along the real axis, $exp(-1/x**2)$
+tends to $0$.
+\spadcommand{limit(exp(-1/x**2),x = 0)}
+$$
+0 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+However, if $x$ is allowed to approach $0$ along any path in the
+complex plane, the limiting value of $exp(-1/x**2)$ depends on the
+path taken because the function has an essential singularity at $x=0$.
+This is reflected in the error message returned by the function.
+\spadcommand{complexLimit(exp(-1/x**2),x = 0)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+You can also take complex limits at infinity, that is, limits of a
+function of $z$ as $z$ approaches infinity on the Riemann sphere.  Use
+the symbol $\%infinity$ to denote ``complex infinity.''
+
+As above, to compute complex limits rather than real limits, use
+{\bf complexLimit}.
+
+\spadcommand{complexLimit((2 + z)/(1 - z),z = \%infinity)}
+$$
+-1 
+$$
+\returnType{Type: OnePointCompletion Fraction Polynomial Integer}
+
+In many cases, a limit of a real function of a real variable exists
+when the corresponding complex limit does not.  This limit exists.
+
+\spadcommand{limit(sin(x)/x,x = \%plusInfinity)}
+$$
+0 
+$$
+\returnType{Type: Union(OrderedCompletion Expression Integer,...)}
+
+But this limit does not.
+
+\spadcommand{complexLimit(sin(x)/x,x = \%infinity)}
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+\section{Laplace Transforms}
+\label{ugProblemLaplace}
+
+Axiom can compute some forward Laplace transforms, mostly
+\index{Laplace transform} of elementary \index{function!elementary}
+functions \index{transform!Laplace} not involving logarithms, although
+some cases of special functions are handled.
+
+To compute the forward Laplace transform of $F(t)$ with respect to
+$t$ and express the result as $f(s)$, issue the command
+$laplace(F(t), t, s)$.
+
+\spadcommand{laplace(sin(a*t)*cosh(a*t)-cos(a*t)*sinh(a*t), t, s)}
+$$
+{4 \  {a \sp 3}} \over {{s \sp 4}+{4 \  {a \sp 4}}} 
+$$
+\returnType{Type: Expression Integer}
+
+Here are some other non-trivial examples.
+
+\spadcommand{laplace((exp(a*t) - exp(b*t))/t, t, s)}
+$$
+-{\log \left({{s -a}} \right)}+{\log\left({{s -b}} \right)}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{laplace(2/t * (1 - cos(a*t)), t, s)}
+$$
+{\log \left({{{s \sp 2}+{a \sp 2}}} \right)}-{2 \  {\log \left({s} \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{laplace(exp(-a*t) * sin(b*t) / b**2, t, s)}
+$$
+1 \over {{b \  {s \sp 2}}+{2 \  a \  b \  s}+{b \sp 3}+{{a \sp 2} \  b}} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{laplace((cos(a*t) - cos(b*t))/t, t, s)}
+$$
+{{\log \left({{{s \sp 2}+{b \sp 2}}} \right)}-
+{\log \left({{{s \sp 2}+{a \sp 2}}} \right)}}
+\over 2 
+$$
+\returnType{Type: Expression Integer}
+
+Axiom also knows about a few special functions.
+
+\spadcommand{laplace(exp(a*t+b)*Ei(c*t), t, s)}
+$$
+{{e \sp b} \  {\log \left({{{s+c -a} \over c}} \right)}}\over {s -a} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{laplace(a*Ci(b*t) + c*Si(d*t), t, s)}
+$$
+{{a \  {\log \left({{{{s \sp 2}+{b \sp 2}} \over {b \sp 2}}} \right)}}+
+{2\  c \  {\arctan \left({{d \over s}} \right)}}}\over {2 \  s} 
+$$
+\returnType{Type: Expression Integer}
+
+When Axiom does not know about a particular transform,
+it keeps it as a formal transform in the answer.
+
+\spadcommand{laplace(sin(a*t) - a*t*cos(a*t) + exp(t**2), t, s)}
+$$
+{{{\left( {s \sp 4}+{2 \  {a \sp 2} \  {s \sp 2}}+{a \sp 4} \right)}
+\  {laplace \left({{e \sp {t \sp 2}}, t, s} \right)}}+
+{2\  {a \sp 3}}} \over {{s \sp 4}+{2 \  {a \sp 2} \  {s \sp 2}}+{a \sp 4}} 
+$$
+\returnType{Type: Expression Integer}
+
+\section{Integration}
+\label{ugProblemIntegration}
+
+%
+Integration is the reverse process of differentiation, that is,
+\index{integration} an {\it integral} of a function $f$ with respect
+to a variable $x$ is any function $g$ such that $D(g,x)$ is equal to
+$f$.
+
+The package {\tt FunctionSpaceIntegration} provides the top-level
+integration operation, \spadfunFrom{integrate}{FunctionSpaceIntegration},
+for integrating real-valued elementary functions.
+\index{FunctionSpaceIntegration}
+
+\spadcommand{integrate(cosh(a*x)*sinh(a*x), x)}
+$$
+{{{\sinh \left({{a \  x}} \right)}\sp 2}+
+{{\cosh \left({{a \  x}} \right)}\sp 2}} 
+\over {4 \  a} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Unfortunately, antiderivatives of most functions cannot be expressed in
+terms of elementary functions.
+
+\spadcommand{integrate(log(1 + sqrt(a * x + b)) / x, x)}
+$$
+\int \sp{\displaystyle x} {{{\log 
+\left(
+{{{\sqrt {{b+{ \%M \  a}}}}+1}} 
+\right)}
+\over \%M} \  {d \%M}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Given an elementary function to integrate, Axiom returns a formal
+integral as above only when it can prove that the integral is not
+elementary and not when it cannot determine the integral.
+In this rare case it prints a message that it cannot
+determine if an elementary integral exists.
+
+Similar functions may have antiderivatives \index{antiderivative}
+that look quite different because the form of the antiderivative
+depends on the sign of a constant that appears in the function.
+
+\spadcommand{integrate(1/(x**2 - 2),x)}
+$$
+{\log \left({{{{{\left( {x \sp 2}+2 \right)}\  {\sqrt {2}}} -{4 \  x}} 
+\over {{x \sp 2} -2}}} \right)}
+\over {2 \  {\sqrt {2}}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+\spadcommand{integrate(1/(x**2 + 2),x)}
+$$
+{\arctan \left({{{x \  {\sqrt {2}}} \over 2}} \right)}\over {\sqrt {2}} 
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+If the integrand contains parameters, then there may be several possible
+antiderivatives, depending on the signs of expressions of the parameters.
+
+In this case Axiom returns a list of answers that cover all the
+possible cases.  Here you use the answer involving the square root of
+$a$ when $a > 0$ and \index{integration!result as list of real
+functions} the answer involving the square root of $-a$ when $a < 0$.
+
+\spadcommand{integrate(x**2 / (x**4 - a**2), x)}
+$$
+\begin{array}{@{}l}
+\left[
+{{{\log 
+\left(
+{{{{{\left( {x \sp 2}+a \right)}
+\  {\sqrt {a}}} -{2 \  a \  x}} \over {{x \sp 2} -a}}} 
+\right)}+
+{2\  {\arctan \left({{{x \  {\sqrt {a}}} \over a}} \right)}}}
+\over {4 \  {\sqrt {a}}}}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{{{\log \left({{{{{\left( {x \sp 2} -a \right)}
+\  {\sqrt {-a}}}+{2 \  a \  x}} \over {{x \sp 2}+a}}} 
+\right)}
+-{2 \  {\arctan \left({{{x \  {\sqrt {-a}}} \over a}} \right)}}}
+\over {4 \  {\sqrt {-a}}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: Union(List Expression Integer,...)}
+
+If the parameters and the variables of integration can be complex
+numbers rather than real, then the notion of sign is not defined.  In
+this case all the possible answers can be expressed as one complex
+function.  To get that function, rather than a list of real functions,
+use \spadfunFrom{complexIntegrate}{FunctionSpaceComplexIntegration},
+which is provided by the package \index{integration!result as a
+complex functions} {\tt FunctionSpaceComplexIntegration}.
+\index{FunctionSpaceComplexIntegration}
+
+This operation is used for integrating complex-valued elementary
+functions.
+
+\spadcommand{complexIntegrate(x**2 / (x**4 - a**2), x)}
+$$
+\left(
+\begin{array}{@{}l}
+{{\sqrt {{4 \  a}}} \  {\log 
+\left(
+{{{{x \  {\sqrt {-{4 \  a}}}}+{2 \  a}} \over {\sqrt {-{4 \  a}}}}} 
+\right)}} -
+{{\sqrt {-{4 \  a}}} \  {\log 
+\left(
+{{{{x \  {\sqrt {{4 \  a}}}}+{2 \  a}} \over {\sqrt {{4 \  a}}}}} 
+\right)}}+
+\\
+\\
+\displaystyle
+{{\sqrt{-{4 \  a}}} \  {\log 
+\left(
+{{{{x \  {\sqrt {{4 \  a}}}} -{2 \  a}} \over {\sqrt {{4 \  a}}}}} 
+\right)}}
+-{{\sqrt {{4 \  a}}} \  {\log 
+\left(
+{{{{x \  {\sqrt {-{4 \  a}}}} -{2 \  a}} \over {\sqrt {-{4 \  a}}}}} 
+\right)}}
+\end{array}
+\right)
+\over {2 \  {\sqrt {-{4 \  a}}} \  {\sqrt {{4 \  a}}}} 
+$$
+\returnType{Type: Expression Integer}
+
+As with the real case, antiderivatives for most complex-valued
+functions cannot be expressed in terms of elementary functions.
+
+\spadcommand{complexIntegrate(log(1 + sqrt(a * x + b)) / x, x)}
+$$
+\int \sp{\displaystyle x} 
+{{{\log \left({{{\sqrt {{b+{ \%M \  a}}}}+1}} \right)}
+\over \%M} \  {d \%M}} 
+$$
+\returnType{Type: Expression Integer}
+
+Sometimes {\bf integrate} can involve symbolic algebraic numbers
+such as those returned by \spadfunFrom{rootOf}{Expression}.
+To see how to work with these strange generated symbols (such as
+$\%\%a0$), see 
+\ref{ugxProblemSymRootAll} on page~\pageref{ugxProblemSymRootAll}.
+
+Definite integration is the process of computing the area between
+\index{integration!definite}
+the $x$-axis and the curve of a function $f(x)$.
+The fundamental theorem of calculus states that if $f$ is
+continuous on an interval $a..b$ and if there exists a function $g$
+that is differentiable on $a..b$ and such that $D(g, x)$
+is equal to $f$, then the definite integral of $f$
+for $x$ in the interval $a..b$ is equal to $g(b) - g(a)$.
+
+The package {\tt RationalFunctionDefiniteIntegration} provides
+the top-level definite integration operation,
+\spadfunFrom{integrate}{RationalFunctionDefiniteIntegration},
+for integrating real-valued rational functions.
+
+\spadcommand{integrate((x**4 - 3*x**2 + 6)/(x**6-5*x**4+5*x**2+4), x = 1..2)}
+$$
+{{2 \  {\arctan \left({8} \right)}}+
+{2\  {\arctan \left({5} \right)}}+
+{2\  {\arctan \left({2} \right)}}+
+{2\  {\arctan \left({{1 \over 2}} \right)}}
+-\pi} \over 2 
+$$
+\returnType{Type: Union(f1: OrderedCompletion Expression Integer,...)}
+
+Axiom checks beforehand that the function you are integrating is
+defined on the interval $a..b$, and prints an error message if it
+finds that this is not case, as in the following example:
+\begin{verbatim}
+integrate(1/(x**2-2), x = 1..2)
+
+    >> Error detected within library code:
+       Pole in path of integration
+       You are being returned to the top level
+       of the interpreter.
+\end{verbatim}
+When parameters are present in the function, the function may or may not be
+defined on the interval of integration.
+
+If this is the case, Axiom issues a warning that a pole might
+lie in the path of integration, and does not compute the integral.
+
+\spadcommand{integrate(1/(x**2-a), x = 1..2)}
+$$
+potentialPole 
+$$
+\returnType{Type: Union(pole: potentialPole,...)}
+
+If you know that you are using values of the parameter for which
+the function has no pole in the interval of integration, use the
+string {\tt ``noPole''} as a third argument to
+\spadfunFrom{integrate}{RationalFunctionDefiniteIntegration}:
+
+The value here is, of course, incorrect if $sqrt(a)$ is between
+$1$ and $2.$
+
+\spadcommand{integrate(1/(x**2-a), x = 1..2, "noPole")}
+$$
+\begin{array}{@{}l}
+\left[
+\left(
+\begin{array}{@{}l}
+-{\log \left({{{{{\left( -{4 \  {a \sp 2}} -{4 \  a} \right)}
+\  {\sqrt {a}}}+{a \sp 3}+{6 \  {a \sp 2}}+a} \over {{a \sp 2} -{2 \  a}+1}}} 
+\right)}+
+\\
+\\
+\displaystyle
+{\log\left({{{{{\left( -{8 \  {a \sp 2}} -{{32} \  a} \right)}
+\  {\sqrt {a}}}+{a \sp 3}+{{24} \  {a \sp 2}}+{{16} \  a}} \over {{a \sp 2} 
+-{8 \  a}+{16}}}} 
+\right)}
+\end{array}
+\right)
+\over {4 \  {\sqrt {a}}},
+\right.
+\\
+\\
+\displaystyle
+\left. 
+{{-{\arctan \left({{{2 \  {\sqrt {-a}}} \over a}} \right)}+
+{\arctan\left({{{\sqrt {-a}} \over a}} \right)}}
+\over {\sqrt {-a}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: Union(f2: List OrderedCompletion Expression Integer,...)}
+
+\section{Working with Power Series}
+\label{ugProblemSeries}
+%
+Axiom has very sophisticated facilities for working with power
+\index{series}
+series.
+\index{power series}
+
+Infinite series are represented by a list of the coefficients that
+have already been determined, together with a function for computing
+the additional coefficients if needed.
+
+The system command that determines how many terms of a series is
+displayed is {\tt )set streams calculate}.  For the purposes of this
+book, we have used this system command to display fewer than ten
+terms.  \index{set streams calculate} Series can be created from
+expressions, from functions for the series coefficients, and from
+applications of operations on existing series.  The most general
+function for creating a series is called {\bf series}, although you
+can also use {\bf taylor}, {\bf laurent} and {\bf puiseux} in
+situations where you know what kind of exponents are involved.
+
+For information about solving differential equations in terms of
+power series, see 
+\ref{ugxProblemDEQSeries} on page~\pageref{ugxProblemDEQSeries}.
+
+\subsection{Creation of Power Series}
+\label{ugxProblemSeriesCreate}
+
+This is the easiest way to create a power series.  This tells Axiom
+that $x$ is to be treated as a power series, \index{series!creating}
+so functions of $x$ are again power series.
+
+\spadcommand{x := series 'x }
+$$
+x 
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+We didn't say anything about the coefficients of the power series, so
+the coefficients are general expressions over the integers.  This
+allows us to introduce denominators, symbolic constants, and other
+variables as needed.
+
+Here the coefficients are integers (note that the coefficients are the
+Fibonacci \index{Fibonacci numbers} numbers).
+
+\spadcommand{1/(1 - x - x**2) }
+$$
+1+x+
+{2 \  {x \sp 2}}+
+{3 \  {x \sp 3}}+
+{5 \  {x \sp 4}}+
+{8 \  {x \sp 5}}+
+{{13} \  {x \sp 6}}+
+{{21} \  {x \sp 7}}+
+{{34} \  {x \sp 8}}+
+{{55} \  {x \sp 9}}+
+{{89} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+This series has coefficients that are rational numbers.
+
+\spadcommand{sin(x) }
+$$
+x -
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {120}} \  {x \sp 5}} -
+{{1 \over {5040}} \  {x \sp 7}}+
+{{1 \over {362880}} \  {x \sp 9}} -
+{{1 \over {39916800}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+When you enter this expression you introduce the symbolic constants
+$sin(1)$ and $cos(1).$
+
+\spadcommand{sin(1 + x) }
+$$
+\begin{array}{@{}l}
+{\sin \left({1} \right)}+
+{{\cos\left({1} \right)}\  x} -
+{{{\sin \left({1} \right)}\over 2} \  {x \sp 2}} -
+{{{\cos \left({1} \right)}\over 6} \  {x \sp 3}}+
+{{{\sin \left({1} \right)}\over {24}} \  {x \sp 4}}+
+{{{\cos \left({1} \right)}\over {120}} \  {x \sp 5}} -
+{{{\sin \left({1} \right)}\over {720}} \  {x \sp 6}} -
+\\
+\\
+\displaystyle
+{{{\cos \left({1} \right)}\over {5040}} \  {x \sp 7}}+
+{{{\sin \left({1} \right)}\over {40320}} \  {x \sp 8}}+
+{{{\cos \left({1} \right)}\over {362880}} \  {x \sp 9}} -
+{{{\sin \left({1} \right)}\over {3628800}} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+When you enter the expression
+the variable $a$ appears in the resulting series expansion.
+
+\spadcommand{sin(a * x) }
+$$
+{a \  x} -
+{{{a \sp 3} \over 6} \  {x \sp 3}}+
+{{{a \sp 5} \over {120}} \  {x \sp 5}} -
+{{{a \sp 7} \over {5040}} \  {x \sp 7}}+
+{{{a \sp 9} \over {362880}} \  {x \sp 9}} -
+{{{a \sp {11}} \over {39916800}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+You can also convert an expression into a series expansion.  This
+expression creates the series expansion of $1/log(y)$ about $y = 1$.
+For details and more examples, see \ref{ugxProblemSeriesConversions} 
+on page~\pageref{ugxProblemSeriesConversions}.
+
+\spadcommand{series(1/log(y),y = 1)}
+$$
+\begin{array}{@{}l}
+{{\left( y -1 \right)}\sp {\left( -1 \right)}}+
+{1\over 2} -{{1 \over {12}} \  {\left( y -1 \right)}}+
+{{1\over {24}} \  {{\left( y -1 \right)}\sp 2}} -
+{{{19} \over {720}} \  {{\left( y -1 \right)}\sp 3}}+
+{{3 \over {160}} \  {{\left( y -1 \right)}\sp 4}} -
+\\
+\\
+\displaystyle
+{{{863} \over {60480}} \  {{\left( y -1 \right)}\sp 5}}+
+{{{275} \over {24192}} \  {{\left( y -1 \right)}\sp 6}} -
+{{{33953} \over {3628800}} \  {{\left( y -1 \right)}\sp 7}}+
+\\
+\\
+\displaystyle
+{{{8183} \over {1036800}} \  {{\left( y -1 \right)}\sp 8}} -
+{{{3250433} \over {479001600}} \  {{\left( y -1 \right)}\sp 9}}+
+{O \left({{{\left( y -1 \right)}\sp {10}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,y,1)}
+
+You can create power series with more general coefficients.  You
+normally accomplish this via a type declaration (see 
+\ref{ugTypesDeclare} on page~\pageref{ugTypesDeclare}).  
+See \ref{ugxProblemSeriesFunctions} on 
+page~\pageref{ugxProblemSeriesFunctions} for some warnings about working with 
+declared series.
+
+We declare that $y$ is a one-variable Taylor series
+\index{series!Taylor} ({\tt UTS} is the abbreviation for 
+{\tt UnivariateTaylorSeries}) in the variable $z$ with {\tt FLOAT} 
+(that is, floating-point) coefficients, centered about $0.$ Then, by
+assignment, we obtain the Taylor expansion of $exp(z)$ with
+floating-point coefficients.  \index{UnivariateTaylorSeries}
+
+\spadcommand{y : UTS(FLOAT,'z,0) := exp(z) }
+$$
+\begin{array}{@{}l}
+{1.0}+z+
+{{0.5} \  {z \sp 2}}+
+{{0.1666666666\ 6666666667} \  {z \sp 3}}+
+\\
+\\
+\displaystyle
+{{0.0416666666\ 6666666666 7} \  {z \sp 4}}+
+{{0.0083333333\ 3333333333 34} \  {z \sp 5}}+
+\\
+\\
+\displaystyle
+{{0.0013888888\ 8888888888 89} \  {z \sp 6}}+
+{{0.0001984126\ 9841269841 27} \  {z \sp 7}}+
+\\
+\\
+\displaystyle
+{{0.0000248015\ 8730158730 1587} \  {z \sp 8}}+
+{{0.0000027557\ 3192239858 90653} \  {z \sp 9}}+
+\\
+\\
+\displaystyle
+{{0.2755731922\ 3985890653 E -6} \  {z \sp {10}}}+
+{O \left({{z \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Float,z,0.0)}
+
+You can also create a power series by giving an explicit formula for
+its $n$-th coefficient.  For details and more examples, see
+\ref{ugxProblemSeriesFormula} on page~\pageref{ugxProblemSeriesFormula}.
+
+To create a series about $w = 0$ whose $n$-th Taylor coefficient is
+$1/n!$, you can evaluate this expression.  This is the Taylor
+expansion of $exp(w)$ at $w = 0$.
+
+\spadcommand{series(1/factorial(n),n,w = 0)}
+$$
+\begin{array}{@{}l}
+1+w+
+{{1 \over 2} \  {w \sp 2}}+
+{{1 \over 6} \  {w \sp 3}}+
+{{1 \over {24}} \  {w \sp 4}}+
+{{1 \over {120}} \  {w \sp 5}}+
+{{1 \over {720}} \  {w \sp 6}}+
+{{1 \over {5040}} \  {w \sp 7}}+
+\\
+\\
+\displaystyle
+{{1 \over {40320}} \  {w \sp 8}}+
+{{1 \over {362880}} \  {w \sp 9}}+
+{{1 \over {3628800}} \  {w \sp {10}}}+
+{O \left({{w \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,w,0)}
+
+\subsection{Coefficients of Power Series}
+\label{ugxProblemSeriesCoefficients}
+
+You can extract any coefficient from a power series---even one that
+hasn't been computed yet.  This is possible because in Axiom, infinite
+series are represented by a list of the coefficients that have already
+been determined, together with a function for computing the additional
+coefficients.  (This is known as {\it lazy evaluation}.) When you ask
+for a \index{series!lazy evaluation} coefficient that hasn't yet been
+computed, Axiom computes \index{lazy evaluation} whatever additional
+coefficients it needs and then stores them in the representation of
+the power series.
+
+Here's an example of how to extract the coefficients of a power series.
+\index{series!extracting coefficients}
+
+\spadcommand{x := series(x) }
+$$
+x 
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{y := exp(x) * sin(x)  }
+$$
+\begin{array}{@{}l}
+x+
+{x \sp 2}+
+{{1 \over 3} \  {x \sp 3}} -
+{{1 \over {30}} \  {x \sp 5}} -
+{{1 \over {90}} \  {x \sp 6}} -
+{{1 \over {630}} \  {x \sp 7}}+
+{{1 \over {22680}} \  {x \sp 9}}+
+\\
+\\
+\displaystyle
+{{1 \over {113400}} \  {x \sp {10}}}+
+{{1 \over {1247400}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+This coefficient is readily available.
+
+\spadcommand{coefficient(y,6) }
+$$
+-{1 \over {90}} 
+$$
+\returnType{Type: Expression Integer}
+
+But let's get the fifteenth coefficient of $y$.
+
+\spadcommand{coefficient(y,15)  }
+$$
+-{1 \over {10216206000}} 
+$$
+\returnType{Type: Expression Integer}
+
+If you look at $y$ then you see that the coefficients up to order $15$
+have all been computed.
+
+\spadcommand{y }
+$$
+\begin{array}{@{}l}
+x+
+{x \sp 2}+
+{{1 \over 3} \  {x \sp 3}} -
+{{1 \over {30}} \  {x \sp 5}} -
+{{1 \over {90}} \  {x \sp 6}} -
+{{1 \over {630}} \  {x \sp 7}}+
+{{1 \over {22680}} \  {x \sp 9}}+
+{{1 \over {113400}} \  {x \sp {10}}}+
+\\
+\\
+\displaystyle
+{{1 \over {1247400}} \  {x \sp {11}}} -
+{{1 \over {97297200}} \  {x \sp {13}}} -
+{{1 \over {681080400}} \  {x \sp {14}}} -
+{{1 \over {10216206000}} \  {x \sp {15}}}+
+{O \left({{x \sp {16}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\subsection{Power Series Arithmetic}
+\label{ugxProblemSeriesArithmetic}
+
+You can manipulate power series using the usual arithmetic operations
+\index{series!arithmetic}
+$+$, $-$, $*$, and $/$ (from UnivariatePuiseuxSeries)
+
+The results of these operations are also power series.
+
+\spadcommand{x := series x }
+$$
+x 
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{(3 + x) / (1 + 7*x)}
+$$
+\begin{array}{@{}l}
+3 -
+{{20} \  x}+
+{{140} \  {x \sp 2}} -
+{{980} \  {x \sp 3}}+
+{{6860} \  {x \sp 4}} -
+{{48020} \  {x \sp 5}}+
+{{336140} \  {x \sp 6}} -
+{{2352980} \  {x \sp 7}}+
+\\
+\\
+\displaystyle
+{{16470860} \  {x \sp 8}} -
+{{115296020} \  {x \sp 9}}+
+{{807072140} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+You can also compute $f(x) ** g(x)$, where $f(x)$ and $g(x)$
+are two power series.
+
+\spadcommand{base := 1 / (1 - x)  }
+$$
+1+x+
+{x \sp 2}+
+{x \sp 3}+
+{x \sp 4}+
+{x \sp 5}+
+{x \sp 6}+
+{x \sp 7}+
+{x \sp 8}+
+{x \sp 9}+
+{x \sp {10}}+
+{O \left({{x \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{expon := x * base  }
+$$
+x+
+{x \sp 2}+
+{x \sp 3}+
+{x \sp 4}+
+{x \sp 5}+
+{x \sp 6}+
+{x \sp 7}+
+{x \sp 8}+
+{x \sp 9}+
+{x \sp {10}}+
+{x \sp {11}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{base ** expon }
+$$
+\begin{array}{@{}l}
+1+
+{x \sp 2}+
+{{3 \over 2} \  {x \sp 3}}+
+{{7 \over 3} \  {x \sp 4}}+
+{{{43} \over {12}} \  {x \sp 5}}+
+{{{649} \over {120}} \  {x \sp 6}}+
+{{{241} \over {30}} \  {x \sp 7}}+
+{{{3706} \over {315}} \  {x \sp 8}}+
+\\
+\\
+\displaystyle
+{{{85763} \over {5040}} \  {x \sp 9}}+
+{{{245339} \over {10080}} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\subsection{Functions on Power Series}
+\label{ugxProblemSeriesFunctions}
+
+Once you have created a power series, you can apply transcendental
+functions
+(for example, {\bf exp}, {\bf log}, {\bf sin}, {\bf tan},
+{\bf cosh}, etc.) to it.
+
+To demonstrate this, we first create the power series
+expansion of the rational function
+
+$${\displaystyle x^2} \over {\displaystyle 1 - 6x + x^2}$$
+
+about $x = 0$.
+
+\spadcommand{x := series 'x }
+$$
+x 
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\spadcommand{rat := x**2 / (1 - 6*x + x**2)  }
+$$
+\begin{array}{@{}l}
+{x \sp 2}+
+{6 \  {x \sp 3}}+
+{{35} \  {x \sp 4}}+
+{{204} \  {x \sp 5}}+
+{{1189} \  {x \sp 6}}+
+{{6930} \  {x \sp 7}}+
+{{40391} \  {x \sp 8}}+
+{{235416} \  {x \sp 9}}+
+\\
+\\
+\displaystyle
+{{1372105} \  {x \sp {10}}}+
+{{7997214} \  {x \sp {11}}}+
+{{46611179} \  {x \sp {12}}}+
+{O \left({{x \sp {13}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+If you want to compute the series expansion of
+
+$$\sin\left({\displaystyle x^2} \over {\displaystyle 1 - 6x + x^2}\right)$$
+
+you simply compute the sine of $rat$.
+
+\spadcommand{sin(rat) }
+$$
+\begin{array}{@{}l}
+{x \sp 2}+
+{6 \  {x \sp 3}}+
+{{35} \  {x \sp 4}}+
+{{204} \  {x \sp 5}}+
+{{{7133} \over 6} \  {x \sp 6}}+
+{{6927} \  {x \sp 7}}+
+{{{80711} \over 2} \  {x \sp 8}}+
+{{235068} \  {x \sp 9}}+
+\\
+\\
+\displaystyle
+{{{164285281} \over {120}} \  {x \sp {10}}}+
+{{{31888513} \over 4} \  {x \sp {11}}}+
+{{{371324777} \over 8} \  {x \sp {12}}}+
+{O \left({{x \sp {13}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+\noindent {\bf Warning:}
+the type of the coefficients of a power series may
+affect the kind of computations that you can do with that series.
+This can only happen when you have made a declaration to
+specify a series domain with a certain type of coefficient.\\
+}
+
+If you evaluate then you have declared that $y$ is a one variable
+Taylor series \index{series!Taylor} ({\tt UTS} is the abbreviation for
+{\tt UnivariateTaylorSeries}) in the variable $y$ with {\tt FRAC INT}
+(that is, fractions of integer) coefficients, centered about $0$.
+
+\spadcommand{y : UTS(FRAC INT,y,0) := y }
+$$
+y 
+$$
+\returnType{Type: UnivariateTaylorSeries(Fraction Integer,y,0)}
+
+You can now compute certain power series in $y$, {\it provided} that
+these series have rational coefficients.
+
+\spadcommand{exp(y) }
+$$
+\begin{array}{@{}l}
+1+y+
+{{1 \over 2} \  {y \sp 2}}+
+{{1 \over 6} \  {y \sp 3}}+
+{{1 \over {24}} \  {y \sp 4}}+
+{{1 \over {120}} \  {y \sp 5}}+
+{{1 \over {720}} \  {y \sp 6}}+
+{{1 \over {5040}} \  {y \sp 7}}+
+{{1 \over {40320}} \  {y \sp 8}}+
+\\
+\\
+\displaystyle
+{{1 \over {362880}} \  {y \sp 9}}+
+{{1 \over {3628800}} \  {y \sp {10}}}+
+{O \left({{y \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Fraction Integer,y,0)}
+
+You can get examples of such series by applying transcendental
+functions to series in $y$ that have no constant terms.
+
+\spadcommand{tan(y**2) }
+$$
+{y \sp 2}+
+{{1 \over 3} \  {y \sp 6}}+
+{{2 \over {15}} \  {y \sp {10}}}+
+{O \left({{y \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Fraction Integer,y,0)}
+
+\spadcommand{cos(y + y**5) }
+$$
+1 -
+{{1 \over 2} \  {y \sp 2}}+
+{{1 \over {24}} \  {y \sp 4}} -
+{{{721} \over {720}} \  {y \sp 6}}+
+{{{6721} \over {40320}} \  {y \sp 8}} -
+{{{1844641} \over {3628800}} \  {y \sp {10}}}+
+{O \left({{y \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Fraction Integer,y,0)}
+
+Similarly, you can compute the logarithm of a power series with rational
+coefficients if the constant coefficient is $1.$
+
+\spadcommand{log(1 + sin(y)) }
+$$
+\begin{array}{@{}l}
+y -
+{{1 \over 2} \  {y \sp 2}}+
+{{1 \over 6} \  {y \sp 3}} -
+{{1 \over {12}} \  {y \sp 4}}+
+{{1 \over {24}} \  {y \sp 5}} -
+{{1 \over {45}} \  {y \sp 6}}+
+{{{61} \over {5040}} \  {y \sp 7}} -
+{{{17} \over {2520}} \  {y \sp 8}}+
+{{{277} \over {72576}} \  {y \sp 9}} -
+\\
+\\
+\displaystyle
+{{{31} \over {14175}} \  {y \sp {10}}}+
+{O \left({{y \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Fraction Integer,y,0)}
+
+If you wanted to apply, say, the operation {\bf exp} to a power series
+with a nonzero constant coefficient $a_0$, then the constant
+coefficient of the result would be $e^{a_0}$, which is {\it not} a
+rational number.  Therefore, evaluating $exp(2 + tan(y))$ would
+generate an error message.
+
+If you want to compute the Taylor expansion of $exp(2 + tan(y))$, you
+must ensure that the coefficient domain has an operation {\bf exp}
+defined for it.  An example of such a domain is {\tt Expression
+Integer}, the type of formal functional expressions over the integers.
+
+When working with coefficients of this type,
+
+\spadcommand{z : UTS(EXPR INT,z,0) := z }
+$$
+z 
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,z,0)}
+
+this presents no problems.
+
+\spadcommand{exp(2 + tan(z)) }
+$$
+\begin{array}{@{}l}
+{e \sp 2}+
+{{e \sp 2} \  z}+
+{{{e \sp 2} \over 2} \  {z \sp 2}}+
+{{{e \sp 2} \over 2} \  {z \sp 3}}+
+{{{3 \  {e \sp 2}} \over 8} \  {z \sp 4}}+
+{{{{37} \  {e \sp 2}} \over {120}} \  {z \sp 5}}+
+{{{{59} \  {e \sp 2}} \over {240}} \  {z \sp 6}}+
+{{{{137} \  {e \sp 2}} \over {720}} \  {z \sp 7}}+
+\\
+\\
+\displaystyle
+{{{{871} \  {e \sp 2}} \over {5760}} \  {z \sp 8}}+
+{{{{41641} \  {e \sp 2}} \over {362880}} \  {z \sp 9}}+
+{{{{325249} \  {e \sp 2}} \over {3628800}} \  {z \sp {10}}}+
+{O \left({{z \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,z,0)}
+
+Another way to create Taylor series whose coefficients are expressions
+over the integers is to use {\bf taylor} which works similarly to
+\index{series!Taylor} {\bf series}.
+
+This is equivalent to the previous computation, except that now we
+are using the variable $w$ instead of $z$.
+
+\spadcommand{w := taylor 'w }
+$$
+w 
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,w,0)}
+
+\spadcommand{exp(2 + tan(w)) }
+$$
+\begin{array}{@{}l}
+{e \sp 2}+
+{{e \sp 2} \  w}+
+{{{e \sp 2} \over 2} \  {w \sp 2}}+
+{{{e \sp 2} \over 2} \  {w \sp 3}}+
+{{{3 \  {e \sp 2}} \over 8} \  {w \sp 4}}+
+{{{{37} \  {e \sp 2}} \over {120}} \  {w \sp 5}}+
+{{{{59} \  {e \sp 2}} \over {240}} \  {w \sp 6}}+
+{{{{137} \  {e \sp 2}} \over {720}} \  {w \sp 7}}+
+\\
+\\
+\displaystyle
+{{{{871} \  {e \sp 2}} \over {5760}} \  {w \sp 8}}+
+{{{{41641} \  {e \sp 2}} \over {362880}} \  {w \sp 9}}+
+{{{{325249} \  {e \sp 2}} \over {3628800}} \  {w \sp {10}}}+
+{O \left({{w \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,w,0)}
+
+\subsection{Converting to Power Series}
+\label{ugxProblemSeriesConversions}
+
+The {\tt ExpressionToUnivariatePowerSeries} package provides
+operations for computing series expansions of functions.
+\index{ExpressionToUnivariatePowerSeries}
+
+Evaluate this to compute the Taylor expansion of $sin x$ about
+\index{series!Taylor} $x = 0$.  The first argument, $sin(x)$,
+specifies the function whose series expansion is to be computed and
+the second argument, $x = 0$, specifies that the series is to be
+expanded in power of $(x - 0)$, that is, in power of $x$.
+
+\spadcommand{taylor(sin(x),x = 0)}
+$$
+x -
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {120}} \  {x \sp 5}} -
+{{1 \over {5040}} \  {x \sp 7}}+
+{{1 \over {362880}} \  {x \sp 9}}+
+{O \left({{x \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,0)}
+
+Here is the Taylor expansion of $sin x$ about $x = \frac{\pi}{6}$:
+
+\spadcommand{taylor(sin(x),x = \%pi/6)}
+$$
+\begin{array}{@{}l}
+{1 \over 2}+
+{{{\sqrt {3}} \over 2} \  {\left( x -{\pi \over 6} \right)}}
+-{{1 \over 4} \  {{\left( x -{\pi \over 6} \right)}\sp 2}} -
+{{{\sqrt {3}} \over {12}} \  {{\left( x -{\pi \over 6} \right)}\sp 3}}+
+{{1 \over {48}} \  {{\left( x -{\pi \over 6} \right)}\sp 4}}+
+\\
+\\
+\displaystyle
+{{{\sqrt {3}} \over {240}} \  {{\left( x -{\pi \over 6} \right)}\sp 5}} -
+{{1 \over {1440}} \  {{\left( x -{\pi \over 6} \right)}\sp 6}} -
+{{{\sqrt {3}} \over {10080}} \  {{\left( x -{\pi \over 6} \right)}\sp 7}}+
+{{1 \over {80640}} \  {{\left( x -{\pi \over 6} \right)}\sp 8}}+
+\\
+\\
+\displaystyle
+{{{\sqrt {3}} \over {725760}} \  {{\left( x -{\pi \over 6} \right)}\sp 9}} -
+{{1 \over {7257600}} \  {{\left( x -{\pi \over 6} \right)}\sp {10}}}+
+{O \left({{{\left( x -{\pi \over 6} \right)}\sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,pi/6)}
+
+
+The function to be expanded into a series may have variables other
+than \index{series!multiple variables} the series variable.
+
+For example, we may expand $tan(x*y)$ as a Taylor series in $x$
+
+\spadcommand{taylor(tan(x*y),x = 0)}
+$$
+{y \  x}+
+{{{y \sp 3} \over 3} \  {x \sp 3}}+
+{{{2 \  {y \sp 5}} \over {15}} \  {x \sp 5}}+
+{{{{17} \  {y \sp 7}} \over {315}} \  {x \sp 7}}+
+{{{{62} \  {y \sp 9}} \over {2835}} \  {x \sp 9}}+
+{O \left({{x \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,0)}
+
+or as a Taylor series in $y$.
+
+\spadcommand{taylor(tan(x*y),y = 0)}
+$$
+{x \  y}+
+{{{x \sp 3} \over 3} \  {y \sp 3}}+
+{{{2 \  {x \sp 5}} \over {15}} \  {y \sp 5}}+
+{{{{17} \  {x \sp 7}} \over {315}} \  {y \sp 7}}+
+{{{{62} \  {x \sp 9}} \over {2835}} \  {y \sp 9}}+
+{O \left({{y \sp {11}}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,y,0)}
+
+A more interesting function is 
+$${\displaystyle t e^{x t}} \over{\displaystyle e^t - 1}$$ 
+When we expand this function as a Taylor
+series in $t$ the $n$-th order coefficient is the $n$-th Bernoulli
+\index{Bernoulli!polynomial} polynomial \index{polynomial!Bernoulli}
+divided by $n!$.
+
+\spadcommand{bern := taylor(t*exp(x*t)/(exp(t) - 1),t = 0) }
+$$
+\begin{array}{@{}l}
+1+
+{{{{2 \  x} -1} \over 2} \  t}+
+{{{{6 \  {x \sp 2}} -{6 \  x}+1} \over {12}} \  {t \sp 2}}+
+{{{{2 \  {x \sp 3}} -{3 \  {x \sp 2}}+x} \over {12}} \  {t \sp 3}}+
+\\
+\\
+\displaystyle
+{{{{{30} \  {x \sp 4}} -{{60} \  {x \sp 3}}+{{30} \  {x \sp 2}} -1} \over 
+{720}} \  {t \sp 4}}+
+{{{{6 \  {x \sp 5}} -{{15} \  {x \sp 4}}+{{10} \  {x \sp 
+3}} -x} \over {720}} \  {t \sp 5}}+
+\\
+\\
+\displaystyle
+{{{{{42} \  {x \sp 6}} -{{126} \  {x \sp 5}}+{{105} \  {x \sp 4}} -{{21} 
+\  {x \sp 2}}+1} \over {30240}} \  {t \sp 6}}+
+{{{{6 \  {x \sp 7}} -{{21} \  {x \sp 6}}+{{21} \  {x \sp 5}} -{7 \  {x 
+\sp 3}}+x} \over {30240}} \  {t \sp 7}}+
+\\
+\\
+\displaystyle
+{{{{{30} \  {x \sp 8}} -{{120} \  {x \sp 7}}+{{140} \  {x \sp 6}} -
+{{70} \  {x \sp 4}}+{{20} \  {x \sp 2}} -1} \over {1209600}} \  {t \sp 8}}+
+\\
+\\
+\displaystyle
+{{{{{10} \  {x \sp 9}} -{{45} \  {x \sp 8}}+{{60} \  {x \sp 7}} -
+{{42} \  {x \sp 5}}+{{20} \  {x \sp 3}} -{3 \  x}} 
+\over {3628800}} \  {t \sp 9}}+
+\\
+\\
+\displaystyle
+{{{{{66} \  {x \sp {10}}} -{{330} \  {x \sp 9}}+{{495} \  {x \sp 8}} -
+{{462} \  {x \sp 6}}+{{330} \  {x \sp 4}} -{{99} \  {x \sp 2}}+5} 
+\over {239500800}} \  {t \sp {10}}}+
+{O \left({{t \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,t,0)}
+
+Therefore, this and the next expression produce the same result.
+
+\spadcommand{factorial(6) * coefficient(bern,6) }
+$$
+{{{42} \  {x \sp 6}} -
+{{126} \  {x \sp 5}}+
+{{105} \  {x \sp 4}} -
+{{21} \  {x \sp 2}}+1}
+\over {42} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{bernoulliB(6,x)}
+$$
+{x \sp 6} -
+{3 \  {x \sp 5}}+
+{{5 \over 2} \  {x \sp 4}} -
+{{1 \over 2} \  {x \sp 2}}+
+{1 \over {42}} 
+$$
+\returnType{Type: Polynomial Fraction Integer}
+
+Technically, a series with terms of negative degree is not considered
+to be a Taylor series, but, rather, a \index{series!Laurent} 
+{\it Laurent series}.  \index{Laurent series} If you try to compute a
+Taylor series expansion of $\frac{x}{\log x}$ at $x = 1$ via
+$taylor(x/log(x),x = 1)$ you get an error message.  The reason is that
+the function has a {\it pole} at $x = 1$, meaning that its series
+expansion about this point has terms of negative degree.  A series
+with finitely many terms of negative degree is called a Laurent
+series.
+
+You get the desired series expansion by issuing this.
+
+\spadcommand{laurent(x/log(x),x = 1)}
+$$
+\begin{array}{@{}l}
+{{\left( x -1 \right)}\sp {\left( -1\right)}}+
+{3\over 2}+
+{{5 \over {12}} \  {\left( x -1 \right)}}
+-{{1 \over {24}} \  {{\left( x -1 \right)}\sp 2}}+
+{{{11} \over {720}} \  {{\left( x -1 \right)}\sp 3}} -
+{{{11} \over {1440}} \  {{\left( x -1 \right)}\sp 4}}+
+\\
+\\
+\displaystyle
+{{{271} \over {60480}} \  {{\left( x -1 \right)}\sp 5}} -
+{{{13} \over {4480}} \  {{\left( x -1 \right)}\sp 6}}+
+{{{7297} \over {3628800}} \  {{\left( x -1 \right)}\sp 7}} -
+{{{425} \over {290304}} \  {{\left( x -1 \right)}\sp 8}}+
+\\
+\\
+\displaystyle
+{{{530113} \over {479001600}} \  {{\left( x -1 \right)}\sp 9}}+
+{O \left({{{\left( x -1 \right)}\sp {10}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateLaurentSeries(Expression Integer,x,1)}
+
+Similarly, a series with terms of fractional degree is neither a
+Taylor series nor a Laurent series.  Such a series is called a
+\index{series!Puiseux} {\it Puiseux series}.  \index{Puiseux series}
+The expression $laurent(sqrt(sec(x)),x = 3 * \%pi/2)$ results in an
+error message because the series expansion about this point has terms
+of fractional degree.
+
+However, this command produces what you want.
+
+\spadcommand{puiseux(sqrt(sec(x)),x = 3 * \%pi/2)}
+$$
+{{\left( x -{{3 \  \pi} \over 2} \right)}\sp {\left( -{1 \over 2} \right)}}+
+{{1\over {12}} \  {{\left( x -{{3 \  \pi} \over 2} \right)}\sp {3 \over 2}}}+
+{{1 \over {160}} \  {{\left( x -{{3 \  \pi} \over 2} \right)}\sp {7 \over 2}}}+
+{O \left({{{\left( x -{{3 \  \pi} \over 2} \right)}\sp 5}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,(3*pi)/2)}
+
+Finally, consider the case of functions that do not have Puiseux
+expansions about certain points.  An example of this is $x^x$ about $x
+= 0$.  $puiseux(x**x,x=0)$ produces an error message because of the
+type of singularity of the function at $x = 0$.
+
+The general function {\bf series} can be used in this case.
+Notice that the series returned is not, strictly speaking, a power series
+because of the $log(x)$ in the expansion.
+
+\spadcommand{series(x**x,x=0)}
+$$
+\begin{array}{@{}l}
+1+
+{{\log \left({x} \right)}\  x}+
+{{{{\log \left({x} \right)}\sp 2} \over 2} \  {x \sp 2}}+
+{{{{\log \left({x} \right)}\sp 3} \over 6} \  {x \sp 3}}+
+{{{{\log \left({x} \right)}\sp 4} \over {24}} \  {x \sp 4}}+
+{{{{\log \left({x} \right)}\sp 5} \over {120}} \  {x \sp 5}}+
+{{{{\log \left({x} \right)}\sp 6} \over {720}} \  {x \sp 6}}+
+\\
+\\
+\displaystyle
+{{{{\log \left({x} \right)}\sp 7} \over {5040}} \  {x \sp 7}}+
+{{{{\log \left({x} \right)}\sp 8} \over {40320}} \  {x \sp 8}}+
+{{{{\log \left({x} \right)}\sp 9} \over {362880}} \  {x \sp 9}}+
+{{{{\log \left({x} \right)}\sp {10}} \over {3628800}} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: GeneralUnivariatePowerSeries(Expression Integer,x,0)}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+The operation {\bf series} returns the most general type of
+infinite series.
+The user who is not interested in distinguishing
+between various types of infinite series may wish to use this operation
+exclusively.\\
+}
+
+\subsection{Power Series from Formulas}
+\label{ugxProblemSeriesFormula}
+
+The {\tt GenerateUnivariatePowerSeries} package enables you to
+\index{series!giving formula for coefficients} create power series
+from explicit formulas for their $n$-th coefficients.  In what
+follows, we construct series expansions for certain transcendental
+functions by giving formulas for their coefficients.  You can also
+compute such series expansions directly simply by specifying the
+function and the point about which the series is to be expanded.
+\index{GenerateUnivariatePowerSeries} See
+\ref{ugxProblemSeriesConversions} on 
+page~\pageref{ugxProblemSeriesConversions} for more information.
+
+Consider the Taylor expansion of $e^x$ \index{series!Taylor}
+about $x = 0$:
+
+$$
+\begin{array}{ccl}
+e^x &=& \displaystyle 1 + x + \frac{x^2}{2} + \frac{x^3}{6} + \cdots \\ \\
+    &=& \displaystyle\sum_{n=0}^\infty \frac{x^n}{n!}
+\end{array}
+$$
+
+The $n$-th Taylor coefficient is $1/n!$.
+
+This is how you create this series in Axiom.
+
+\spadcommand{series(n +-> 1/factorial(n),x = 0)}
+$$
+\begin{array}{@{}l}
+1+x+
+{{1 \over 2} \  {x \sp 2}}+
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {24}} \  {x \sp 4}}+
+{{1 \over {120}} \  {x \sp 5}}+
+{{1 \over {720}} \  {x \sp 6}}+
+{{1 \over {5040}} \  {x \sp 7}}+
+{{1 \over {40320}} \  {x \sp 8}}+
+\\
+\\
+\displaystyle
+{{1 \over {362880}} \  {x \sp 9}}+
+{{1 \over {3628800}} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+The first argument specifies a formula for the $n$-th coefficient by
+giving a function that maps $n$ to $1/n!$.  The second argument
+specifies that the series is to be expanded in powers of $(x - 0)$,
+that is, in powers of $x$.  Since we did not specify an initial
+degree, the first term in the series was the term of degree 0 (the
+constant term).  Note that the formula was given as an anonymous
+function.  These are discussed in \ref{ugUserAnon} on 
+page~\pageref{ugUserAnon}.
+
+Consider the Taylor expansion of $log x$ about $x = 1$:
+
+$$
+\begin{array}{ccl}
+\log(x) &=& \displaystyle (x - 1) - \frac{(x - 1)^2}{2} + \frac{(x - 1)^3}{3} - \cdots \\ \\
+        &=& \displaystyle\sum_{n = 1}^\infty (-1)^{n-1} \frac{(x - 1)^n}{n}
+\end{array}$$
+
+If you were to evaluate the expression 
+$series(n +-> (-1)**(n-1) / n, x = 1)$ 
+you would get an error message because Axiom would try to
+calculate a term of degree $0$ and therefore divide by $0.$
+
+Instead, evaluate this.
+The third argument, $1..$, indicates that only terms of degree
+$n = 1, ...$ are to be computed.
+
+\spadcommand{series(n +-> (-1)**(n-1)/n,x = 1,1..)}
+$$
+\begin{array}{@{}l}
+{\left( x -1 \right)}
+-{{1 \over 2} \  {{\left( x -1 \right)}\sp 2}}+
+{{1 \over 3} \  {{\left( x -1 \right)}\sp 3}} -
+{{1 \over 4} \  {{\left( x -1 \right)}\sp 4}}+
+{{1 \over 5} \  {{\left( x -1 \right)}\sp 5}} -
+{{1 \over 6} \  {{\left( x -1 \right)}\sp 6}}+
+\\
+\\
+\displaystyle
+{{1 \over 7} \  {{\left( x -1 \right)}\sp 7}} -
+{{1 \over 8} \  {{\left( x -1 \right)}\sp 8}}+
+{{1 \over 9} \  {{\left( x -1 \right)}\sp 9}} -
+{{1 \over {10}} \  {{\left( x -1 \right)}\sp {10}}}+
+{{1 \over {11}} \  {{\left( x -1 \right)}\sp {11}}}+
+\\
+\\
+\displaystyle
+{O \left({{{\left( x -1 \right)}\sp {12}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,1)}
+
+Next consider the Taylor expansion of an odd function, say, $sin(x)$:
+
+$$\sin(x) = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \cdots$$
+
+Here every other coefficient is zero and we would like to give an
+explicit formula only for the odd Taylor coefficients.
+
+This is one way to do it.  The third argument, $1..$, specifies that
+the first term to be computed is the term of degree 1.  The fourth
+argument, $2$, specifies that we increment by $2$ to find the degrees
+of subsequent terms, that is, the next term is of degree $1 + 2$, the
+next of degree $1 + 2 + 2$, etc.
+
+\spadcommand{series(n +-> (-1)**((n-1)/2)/factorial(n),x = 0,1..,2)}
+$$
+x -
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {120}} \  {x \sp 5}} -
+{{1 \over {5040}} \  {x \sp 7}}+
+{{1 \over {362880}} \  {x \sp 9}} -
+{{1 \over {39916800}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+The initial degree and the increment do not have to be integers.
+For example, this expression produces a series expansion of
+$\sin(x^{\frac{1}{3}})$.
+
+\spadcommand{series(n +-> (-1)**((3*n-1)/2)/factorial(3*n),x = 0,1/3..,2/3)}
+$$
+{x \sp {1 \over 3}} -
+{{1 \over 6} \  x}+
+{{1 \over {120}} \  {x \sp {5 \over 3}}} -
+{{1 \over {5040}} \  {x \sp {7 \over 3}}}+
+{{1 \over {362880}} \  {x \sp 3}} -
+{{1 \over {39916800}} \  {x \sp {{11} \over 3}}}+
+{O \left({{x \sp 4}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+While the increment must be positive, the initial degree may be
+negative.  This yields the Laurent expansion of $csc(x)$ at $x = 0$.
+(bernoulli(numer(n+1)) is necessary because bernoulli takes integer
+arguments.)
+
+\spadcommand{cscx := series(n +-> (-1)**((n-1)/2) * 2 * (2**n-1) * bernoulli(numer(n+1)) / factorial(n+1), x=0, -1..,2) }
+$$
+{x \sp {\left( -1 \right)}}+
+{{1\over 6} \  x}+
+{{7 \over {360}} \  {x \sp 3}}+
+{{{31} \over {15120}} \  {x \sp 5}}+
+{{{127} \over {604800}} \  {x \sp 7}}+
+{{{73} \over {3421440}} \  {x \sp 9}}+
+{O \left({{x \sp {10}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+Of course, the reciprocal of this power series is the Taylor expansion
+of $sin(x)$.
+
+\spadcommand{1/cscx }
+$$
+x -
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {120}} \  {x \sp 5}} -
+{{1 \over {5040}} \  {x \sp 7}}+
+{{1 \over {362880}} \  {x \sp 9}} -
+{{1 \over {39916800}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+As a final example,here is the Taylor expansion of $asin(x)$ about $x = 0$.
+
+\spadcommand{asinx := series(n +-> binomial(n-1,(n-1)/2)/(n*2**(n-1)),x=0,1..,2) }
+$$
+x+
+{{1 \over 6} \  {x \sp 3}}+
+{{3 \over {40}} \  {x \sp 5}}+
+{{5 \over {112}} \  {x \sp 7}}+
+{{{35} \over {1152}} \  {x \sp 9}}+
+{{{63} \over {2816}} \  {x \sp {11}}}+
+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+When we compute the $sin$ of this series, we get $x$
+(in the sense that all higher terms computed so far are zero).
+
+\spadcommand{sin(asinx) }
+$$
+x+{O \left({{x \sp {12}}} \right)}
+$$
+\returnType{Type: UnivariatePuiseuxSeries(Expression Integer,x,0)}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Axiom isn't sufficiently ``symbolic'' in the sense we might wish. It
+is an open problem to decide that ``x'' is the only surviving
+term. Two attacks on the problem might be:
+
+(1) Notice that all of the higher terms are identically zero but
+Axiom can't decide that from the information it knows. Presumably
+we could attack this problem by looking at the sin function as
+a taylor series around x=0 and seeing the term cancellation occur.
+This uses a term-difference mechanism.
+
+(2) Notice that there is no way to decide that the stream for asinx
+is actually the definition of asin(x). But we could recognize that
+the stream for asin(x) has a generator term and so will a taylor
+series expansion of sin(x). From these two generators it may be
+possible in certain cases to decide that the application of one
+generator to the other will yield only ``x''. This trick involves
+finding the correct inverse for the stream functions. If we can
+find an inverse for the ``remaining tail'' of the stream we could
+conclude cancellation and thus turn an infinite stream into a
+finite object.
+
+In general this is the zero-equivalence problem and is undecidable.\\
+}
+
+As we discussed in \ref{ugxProblemSeriesConversions} on 
+page~\pageref{ugxProblemSeriesConversions}, you can also use
+the operations {\bf taylor}, {\bf laurent} and {\bf puiseux} instead
+of {\bf series} if you know ahead of time what kind of exponents a
+series has.  You can't go wrong using {\bf series}, though.
+
+\subsection{Substituting Numerical Values in Power Series}
+\label{ugxProblemSeriesSubstitute}
+
+Use \spadfunFrom{eval}{UnivariatePowerSeriesCategory}
+\index{approximation} to substitute a numerical value for a variable
+in \index{series!numerical approximation} a power series.  For
+example, here's a way to obtain numerical approximations of $\%e$ from
+the Taylor series expansion of $exp(x)$.
+
+First you create the desired Taylor expansion.
+
+\spadcommand{f := taylor(exp(x)) }
+$$
+\begin{array}{@{}l}
+1+x+
+{{1 \over 2} \  {x \sp 2}}+
+{{1 \over 6} \  {x \sp 3}}+
+{{1 \over {24}} \  {x \sp 4}}+
+{{1 \over {120}} \  {x \sp 5}}+
+{{1 \over {720}} \  {x \sp 6}}+
+{{1 \over {5040}} \  {x \sp 7}}+
+\\
+\\
+\displaystyle
+{{1 \over {40320}} \  {x \sp 8}}+
+{{1 \over {362880}} \  {x \sp 9}}+
+{{1 \over {3628800}} \  {x \sp {10}}}+
+{O \left({{x \sp {11}}} \right)}
+\end{array}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,0)}
+
+
+Then you evaluate the series at the value $1.0$.
+The result is a sequence of the partial sums.
+
+\spadcommand{eval(f,1.0)}
+$$
+\begin{array}{@{}l}
+\left[
+{1.0}, 
+{2.0}, 
+{2.5}, 
+{2.6666666666\ 666666667}, 
+{2.7083333333\ 333333333},
+\right.
+\\
+\\
+\displaystyle
+{2.7166666666\ 666666667},
+{2.7180555555\ 555555556},
+{2.7182539682\ 53968254},
+\\
+\\
+\displaystyle
+\left.
+{2.7182787698\ 412698413},
+{2.7182815255\ 731922399},
+\ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream Expression Float}
+
+\subsection{Example: Bernoulli Polynomials and Sums of Powers}
+\label{ugxProblemSeriesBernoulli}
+
+Axiom provides operations for computing definite and
+\index{summation!definite} indefinite sums.
+\index{summation!indefinite}
+
+You can compute the sum of the first ten fourth powers by evaluating
+this.  This creates a list whose entries are $m^4$ as $m$ ranges from
+1 to 10, and then computes the sum of the entries of that list.
+
+\spadcommand{reduce(+,[m**4 for m in 1..10])}
+$$
+25333 
+$$
+\returnType{Type: PositiveInteger}
+
+You can also compute a formula for the sum of the first $k$ fourth
+powers, where $k$ is an unspecified positive integer.
+
+\spadcommand{sum4 := sum(m**4, m = 1..k) }
+$$
+{{6 \  {k \sp 5}}+{{15} \  {k \sp 4}}+{{10} \  {k \sp 3}} -k} \over {30} 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+This formula is valid for any positive integer $k$.  For instance, if
+we replace $k$ by 10, \index{summation!definite} we obtain the number
+we computed earlier.
+
+\spadcommand{eval(sum4, k = 10) }
+$$
+25333 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+You can compute a formula for the sum of the first $k$ $n$-th powers
+in a similar fashion.  Just replace the $4$ in the definition of 
+{\bf sum4} by any expression not involving $k$.  Axiom computes these
+formulas using Bernoulli polynomials; \index{Bernoulli!polynomial} we
+\index{polynomial!Bernoulli} use the rest of this section to describe
+this method.
+
+First consider this function of $t$ and $x$.
+
+\spadcommand{f := t*exp(x*t) / (exp(t) - 1) }
+$$
+{t \  {e \sp {\left( t \  x \right)}}}\over {{e \sp t} -1} 
+$$
+\returnType{Type: Expression Integer}
+
+Since the expressions involved get quite large, we tell
+Axiom to show us only terms of degree up to $5.$
+
+\spadcommand{)set streams calculate 5 }
+
+\index{set streams calculate}
+
+If we look at the Taylor expansion of $f(x, t)$ about $t = 0,$
+we see that the coefficients of the powers of $t$ are polynomials
+in $x$.
+
+\spadcommand{ff := taylor(f,t = 0)  }
+$$
+\begin{array}{@{}l}
+1+
+{{{{2 \  x} -1} \over 2} \  t}+
+{{{{6 \  {x \sp 2}} -{6 \  x}+1} \over {12}} \  {t \sp 2}}+
+{{{{2 \  {x \sp 3}} -{3 \  {x \sp 2}}+x} \over {12}} \  {t \sp 3}}+
+\\
+\\
+\displaystyle
+{{{{{30} \  {x \sp 4}} -{{60} \  {x \sp 3}}+{{30} \  {x \sp 2}} -1} \over 
+{720}} \  {t \sp 4}}+
+{{{{6 \  {x \sp 5}} -{{15} \  {x \sp 4}}+{{10} \  {x \sp 
+3}} -x} \over {720}} \  {t \sp 5}}+
+{O \left({{t \sp 6}} \right)}
+\end{array}
+$$
+
+                         Type: UnivariateTaylorSeries(Expression Integer,t,0)
+
+
+In fact, the $n$-th coefficient in this series is essentially the
+$n$-th Bernoulli polynomial: the $n$-th coefficient of the series is
+${1 \over {n!}} B_n(x)$, where $B_n(x)$ is the $n$-th Bernoulli
+polynomial.  Thus, to obtain the $n$-th Bernoulli polynomial, we
+multiply the $n$-th coefficient of the series $ff$ by $n!$.
+
+For example, the sixth Bernoulli polynomial is this.
+
+\spadcommand{factorial(6) * coefficient(ff,6) }
+$$
+{{{42} \  {x \sp 6}} -{{126} \  {x \sp 5}}+{{105} \  {x \sp 4}} -
+{{21} \  {x \sp 2}}+1} \over {42} 
+$$
+\returnType{Type: Expression Integer}
+
+We derive some properties of the function $f(x,t)$.
+First we compute $f(x + 1,t) - f(x,t)$.
+
+\spadcommand{g := eval(f, x = x + 1) - f  }
+$$
+{{t \  {e \sp {\left( {t \  x}+t \right)}}}
+-{t \  {e \sp {\left( t \  x \right)}}}}
+\over {{e \sp t} -1} 
+$$
+\returnType{Type: Expression Integer}
+
+If we normalize $g$, we see that it has a particularly simple form.
+
+\spadcommand{normalize(g) }
+$$
+t \  {e \sp {\left( t \  x \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+From this it follows that the $n$-th coefficient in the Taylor
+expansion of $g(x,t)$ at $t = 0$ is $${1\over{(n-1)!}}x^{n-1}$$.
+
+If you want to check this, evaluate the next expression.
+
+\spadcommand{taylor(g,t = 0) }
+$$
+t+
+{x \  {t \sp 2}}+
+{{{x \sp 2} \over 2} \  {t \sp 3}}+
+{{{x \sp 3} \over 6} \  {t \sp 4}}+
+{{{x \sp 4} \over {24}} \  {t \sp 5}}+
+{O \left({{t \sp 6}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,t,0)}
+
+However, since 
+$$g(x,t) = f(x+1,t)-f(x,t)$$
+it follows that the $n$-th coefficient is 
+$${1 \over {n!}}(B_n(x+1)-B_n(x))$$ Equating
+coefficients, we see that 
+$${1\over{(n-1)!}}x^{n-1} = {1\over{n!}}(B_n(x + 1) - B_n(x))$$ 
+and, therefore, 
+$$x^{n-1} = {1\over{n}}(B_n(x + 1) - B_n(x))$$
+
+Let's apply this formula repeatedly, letting $x$ vary between two
+integers $a$ and $b$, with $a < b$:
+
+$$
+\begin{array}{lcl}
+  a^{n-1}       & = & {1 \over n}   (B_n(a + 1) - B_n(a))       \\
+  (a + 1)^{n-1} & = & {1 \over n}   (B_n(a + 2) - B_n(a + 1))   \\
+  (a + 2)^{n-1} & = & {1 \over n}   (B_n(a + 3) - B_n(a + 2))   \\
+  & \vdots &                                                    \\
+  (b - 1)^{n-1} & = & {1 \over n}   (B_n(b) - B_n(b - 1))       \\
+  b^{n-1}       & = & {1 \over n}   (B_n(b + 1) - B_n(b))
+\end{array}
+$$
+
+When we add these equations we find that the sum of the left-hand
+sides is 
+$$\sum_{m=a}^{b} m^{n-1},$$ 
+the sum of the
+$$(n-1)^{\hbox{\small\rm st}}$$ 
+powers from $a$ to $b$.  The sum of the right-hand sides is a 
+``telescoping series.''  After cancellation, the sum is simply 
+$${1\over{n}}(B_n(b + 1) - B_n(a))$$
+
+Replacing $n$ by $n + 1$, we have shown that
+$$
+\sum_{m = a}^{b} m^n = {1 \over {\displaystyle n + 1}} 
+(B_{n+1}(b + 1) - B_{n+1}(a))
+$$
+
+Let's use this to obtain the formula for the sum of fourth powers.
+
+First we obtain the Bernoulli polynomial $B_5$.
+
+\spadcommand{B5 := factorial(5) * coefficient(ff,5)  }
+$$
+{{6 \  {x \sp 5}} -{{15} \  {x \sp 4}}+{{10} \  {x \sp 3}} -x} \over 6 
+$$
+\returnType{Type: Expression Integer}
+
+To find the sum of the first $k$ 4th powers,
+we multiply $1/5$ by $B_5(k+1) - B_5(1)$.
+
+\spadcommand{1/5 * (eval(B5, x = k + 1) - eval(B5, x = 1)) }
+$$
+{{6 \  {k \sp 5}}+{{15} \  {k \sp 4}}+{{10} \  {k \sp 3}} -k} \over {30} 
+$$
+\returnType{Type: Expression Integer}
+
+This is the same formula that we obtained via $sum(m**4, m = 1..k)$.
+
+\spadcommand{sum4 }
+$$
+{{6 \  {k \sp 5}}+{{15} \  {k \sp 4}}+{{10} \  {k \sp 3}} -k} \over {30} 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+At this point you may want to do the same computation, but with an
+exponent other than $4.$ For example, you might try to find a formula
+for the sum of the first $k$ 20th powers.
+
+\section{Solution of Differential Equations}
+\label{ugProblemDEQ}
+
+In this section we discuss Axiom's facilities for
+\index{equation!differential!solving} solving \index{differential
+equation} differential equations in closed-form and in series.
+
+Axiom provides facilities for closed-form solution of
+\index{equation!differential!solving in closed-form} single
+differential equations of the following kinds:
+\begin{itemize}
+\item linear ordinary differential equations, and
+\item non-linear first order ordinary differential equations
+when integrating factors can be found just by integration.
+\end{itemize}
+
+For a discussion of the solution of systems of linear and polynomial
+equations, see \ref{ugProblemLinPolEqn} on page~\pageref{ugProblemLinPolEqn}.
+
+\subsection{Closed-Form Solutions of Linear Differential Equations}
+\label{ugxProblemLDEQClosed}
+
+A {\it differential equation} is an equation involving an unknown 
+{\it function} and one or more of its derivatives.  
+\index{differential equation} The equation is called {\it ordinary} 
+if derivatives with respect to \index{equation!differential} only 
+one dependent variable appear in the equation (it is called 
+{\it partial} otherwise).  The package {\tt ElementaryFunctionODESolver} 
+provides the top-level operation {\bf solve} for finding closed-form 
+solutions of ordinary differential equations.  
+\index{ElementaryFunctionODESolver}
+
+To solve a differential equation, you must first create an operator
+for \index{operator} the unknown function.
+
+We let $y$ be the unknown function in terms of $x$.
+
+\spadcommand{y := operator 'y }
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+You then type the equation using {\tt D} to create the
+derivatives of the unknown function $y(x)$ where $x$ is any
+symbol you choose (the so-called {\it dependent variable}).
+
+This is how you enter
+the equation $y'' + y' + y = 0$.
+
+\spadcommand{deq := D(y x, x, 2) + D(y x, x) + y x = 0}
+$$
+{{{y \sb {{\ }} \sp {,,}} \left({x} \right)}+
+{{y \sb {{\ }} \sp {,}} \left({x} \right)}+
+{y \left({x} \right)}}=0
+$$
+\returnType{Type: Equation Expression Integer}
+
+The simplest way to invoke the {\bf solve} command is with three
+arguments.
+\begin{itemize}
+\item the differential equation,
+\item the operator representing the unknown function,
+\item the dependent variable.
+\end{itemize}
+
+So, to solve the above equation, we enter this.
+
+\spadcommand{solve(deq, y, x) }
+$$
+\left[
+{particular=0},  {basis={\left[ 
+{{\cos \left({{{x \  {\sqrt {3}}} \over 2}} \right)}
+\  {e \sp {\left( -{x \over 2} \right)}}},
+{{e \sp {\left( -{x \over 2} \right)}}
+\  {\sin \left({{{x \  {\sqrt {3}}} \over 2}} \right)}}\right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+Since linear ordinary differential equations have infinitely many
+solutions, {\bf solve} returns a {\it particular solution} $f_p$ and a
+basis $f_1,\dots,f_n$ for the solutions of the corresponding
+homogenuous equation.  Any expression of the form 
+$$f_p + c_1 f_1 + \dots c_n f_n$$ 
+where the $c_i$ do not involve the dependent variable
+is also a solution.  This is similar to what you get when you solve
+systems of linear algebraic equations.
+
+A way to select a unique solution is to specify {\it initial
+conditions}: choose a value $a$ for the dependent variable and specify
+the values of the unknown function and its derivatives at $a$.  If the
+number of initial conditions is equal to the order of the equation,
+then the solution is unique (if it exists in closed form!) and {\bf
+solve} tries to find it.  To specify initial conditions to {\bf
+solve}, use an {\tt Equation} of the form $x = a$ for the third
+parameter instead of the dependent variable, and add a fourth
+parameter consisting of the list of values $y(a), y'(a), ...$.
+
+To find the solution of $y'' + y = 0$ satisfying $y(0) = y'(0) = 1$,
+do this.
+
+\spadcommand{deq := D(y x, x, 2) + y x }
+$$
+{{y \sb {{\ }} \sp {,,}} \left({x} \right)}+{y\left({x} \right)}
+$$
+\returnType{Type: Expression Integer}
+
+You can omit the $= 0$ when you enter the equation to be solved.
+
+\spadcommand{solve(deq, y, x = 0, [1, 1]) }
+$$
+{\sin \left({x} \right)}+{\cos\left({x} \right)}
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+Axiom is not limited to linear differential equations with constant
+coefficients.  It can also find solutions when the coefficients are
+rational or algebraic functions of the dependent variable.
+Furthermore, Axiom is not limited by the order of the equation.
+
+Axiom can solve the following third order equations with
+polynomial coefficients.
+
+\spadcommand{deq := x**3 * D(y x, x, 3) + x**2 * D(y x, x, 2) - 2 * x * D(y x, x) + 2 * y x = 2 * x**4 }
+$$
+{{{x \sp 3} \  {{y \sb {{\ }} \sp {,,,}} \left({x} \right)}}+
+{{x\sp 2} \  {{y \sb {{\ }} \sp {,,}} \left({x} \right)}}-
+{2 \  x \  {{y \sb {{\ }} \sp {,}} \left({x} \right)}}+
+{2\  {y \left({x} \right)}}}=
+{2\  {x \sp 4}} 
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{solve(deq, y, x) }
+$$
+\begin{array}{@{}l}
+\left[
+{particular={{{x \sp 5} -{{10} \  {x \sp 3}}+{{20} \  {x \sp 2}}+4} \over 
+{{15} \  x}}}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{basis={\left[ 
+{{{2 \  {x \sp 3}} -{3 \  {x \sp 2}}+1} \over x},  
+{{{x \sp 3} -1} \over x},  
+{{{x \sp 3} -{3 \  {x \sp 2}} -1} \over x} 
+\right]}}
+\right]
+\end{array}
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+Here we are solving a homogeneous equation.
+
+\spadcommand{deq := (x**9+x**3) * D(y x, x, 3) + 18 * x**8 * D(y x, x, 2) - 90 * x * D(y x, x) - 30 * (11 * x**6 - 3) * y x }
+$$
+{{\left( {x \sp 9}+{x \sp 3} \right)}\  {{y \sb {{\ }} \sp {,,,}} 
+\left({x} \right)}}+
+{{18}\  {x \sp 8} \  {{y \sb {{\ }} \sp {,,}} \left({x} \right)}}-
+{{90} \  x \  {{y \sb {{\ }} \sp {,}} \left({x} \right)}}+
+{{\left(-{{330} \  {x \sp 6}}+{90} \right)}\  {y \left({x} \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{solve(deq, y, x) }
+$$
+\left[
+{particular=0}, 
+{basis={\left[ 
+{x \over {{x \sp 6}+1}}, 
+{{x \  {e \sp {\left( -{{\sqrt {{91}}} \  {\log \left({x} \right)}}\right)}}}
+\over {{x \sp 6}+1}}, 
+{{x \  {e \sp {\left( {\sqrt {{91}}} \  {\log \left({x} \right)}\right)}}}
+\over {{x \sp 6}+1}} 
+\right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+On the other hand, and in contrast with the operation {\bf integrate},
+it can happen that Axiom finds no solution and that some closed-form
+solution still exists.  While it is mathematically complicated to
+describe exactly when the solutions are guaranteed to be found, the
+following statements are correct and form good guidelines for linear
+ordinary differential equations:
+\begin{itemize}
+\item If the coefficients are constants, Axiom finds a complete basis
+of solutions (i,e, all solutions).
+\item If the coefficients are rational functions in the dependent variable,
+Axiom at least finds all solutions that do not involve algebraic
+functions.
+\end{itemize}
+
+Note that this last statement does not mean that Axiom does not find
+the solutions that are algebraic functions.  It means that it is not
+guaranteed that the algebraic function solutions will be found.
+
+This is an example where all the algebraic solutions are found.
+
+\spadcommand{deq := (x**2 + 1) * D(y x, x, 2) + 3 * x * D(y x, x) + y x = 0 }
+$$
+{{{\left( {x \sp 2}+1 \right)}\  {{y \sb {{\ }} \sp {,,}} \left({x} \right)}}+
+{3\  x \  {{y \sb {{\ }} \sp {,}} \left({x} \right)}}+
+{y\left({x} \right)}}=0
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{solve(deq, y, x) }
+$$
+\left[
+{particular=0}, 
+{basis={\left[ {1 \over {\sqrt {{{x \sp 2}+1}}}}, 
+{{\log \left({{{\sqrt {{{x \sp 2}+1}}} -x}} \right)}
+\over {\sqrt {{{x \sp 2}+1}}}} \right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+\subsection{Closed-Form Solutions of Non-Linear Differential Equations}
+\label{ugxProblemNLDEQClosed}
+
+This is an example that shows how to solve a non-linear first order
+ordinary differential equation manually when an integrating factor can
+be found just by integration.  At the end, we show you how to solve it
+directly.
+
+Let's solve the differential equation $y' = y / (x + y log y)$.
+
+Using the notation $m(x, y) + n(x, y) y' = 0$, we have $m = -y$ and 
+$n = x + y log y$.
+
+\spadcommand{m := -y }
+$$
+-y 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{n := x + y * log y }
+$$
+{y \  {\log \left({y} \right)}}+x
+$$
+\returnType{Type: Expression Integer}
+
+We first check for exactness, that is, does $dm/dy = dn/dx$?
+
+\spadcommand{D(m, y) - D(n, x) }
+$$
+-2 
+$$
+\returnType{Type: Expression Integer}
+
+This is not zero, so the equation is not exact.  Therefore we must
+look for an integrating factor: a function $mu(x,y)$ such that 
+$d(mu m)/dy = d(mu n)/dx$.  Normally, we first search for $mu(x,y)$
+depending only on $x$ or only on $y$.
+
+Let's search for such a $mu(x)$ first.
+
+\spadcommand{mu := operator 'mu }
+$$
+mu 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{a := D(mu(x) * m, y) - D(mu(x) * n, x) }
+$$
+{{\left( -{y \  {\log \left({y} \right)}}-x \right)}
+\  {{mu \sb {{\ }} \sp {,}} \left({x} \right)}}-
+{2 \  {mu \left({x} \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+If the above is zero for a function $mu$ that does {\it not} depend on
+$y$, then $mu(x)$ is an integrating factor.
+
+\spadcommand{solve(a = 0, mu, x) }
+$$
+\left[
+{particular=0}, 
+{basis={\left[ 
+{1 \over 
+{{{y \sp 2} \  {{\log \left({y} \right)}\sp 2}}+
+{2 \  x \  y \  {\log \left({y} \right)}}+
+{x\sp 2}}} \right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+The solution depends on $y$, so there is no integrating factor that
+depends on $x$ only.
+
+Let's look for one that depends on $y$ only.
+
+\spadcommand{b := D(mu(y) * m, y) - D(mu(y) * n, x) }
+$$
+-{y \  {{mu \sb {{\ }} \sp {,}} \left({y} \right)}}-
+{2 \  {mu \left({y} \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{sb := solve(b = 0, mu, y) }
+$$
+\left[
+{particular=0}, 
+{basis={\left[ {1 \over {y \sp 2}} \right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: List Expression Integer),...)}
+
+\noindent
+We've found one!
+
+The above $mu(y)$ is an integrating factor.  We must multiply our
+initial equation (that is, $m$ and $n$) by the integrating factor.
+
+\spadcommand{intFactor := sb.basis.1 }
+$$
+1 \over {y \sp 2} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{m := intFactor * m }
+$$
+-{1 \over y} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{n := intFactor * n }
+$$
+{{y \  {\log \left({y} \right)}}+x}\over {y \sp 2} 
+$$
+\returnType{Type: Expression Integer}
+
+Let's check for exactness.
+
+\spadcommand{D(m, y) - D(n, x) }
+$$
+0 
+$$
+\returnType{Type: Expression Integer}
+
+We must solve the exact equation, that is, find a function $s(x,y)$
+such that $ds/dx = m$ and $ds/dy = n$.
+
+We start by writing $s(x, y) = h(y) + integrate(m, x)$ where $h(y)$ is
+an unknown function of $y$.  This guarantees that $ds/dx = m$.
+
+\spadcommand{h := operator 'h }
+$$
+h 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{sol := h y + integrate(m, x) }
+$$
+{{y \  {h \left({y} \right)}}-x} \over y 
+$$
+\returnType{Type: Expression Integer}
+
+All we want is to find $h(y)$ such that $ds/dy = n$.
+
+\spadcommand{dsol := D(sol, y) }
+$$
+{{{y \sp 2} \  {{h \sb {{\ }} \sp {,}} 
+\left({y} \right)}}+x}\over {y \sp 2} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{nsol := solve(dsol = n, h, y) }
+$$
+\left[
+{particular={{{\log \left({y} \right)}\sp 2} \over 2}}, 
+{basis={\left[ 1 \right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,basis: 
+List Expression Integer),...)}
+
+The above particular solution is the $h(y)$ we want, so we just replace
+$h(y)$ by it in the implicit solution.
+
+\spadcommand{eval(sol, h y = nsol.particular) }
+$$
+{{y \  {{\log \left({y} \right)}\sp 2}} -{2 \  x}} \over {2 \  y} 
+$$
+\returnType{Type: Expression Integer}
+
+A first integral of the initial equation is obtained by setting this
+result equal to an arbitrary constant.
+
+Now that we've seen how to solve the equation ``by hand,'' we show you
+how to do it with the {\bf solve} operation.
+
+First define $y$ to be an operator.
+
+\spadcommand{y := operator 'y }
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+Next we create the differential equation.
+
+\spadcommand{deq := D(y x, x) = y(x) / (x + y(x) * log y x) }
+$$
+{{y \sb {{\ }} \sp {,}} \left({x} \right)}=
+{{y\left({x} \right)}\over 
+{{{y \left({x} \right)}\  {\log \left({{y \left({x} \right)}}\right)}}+x}}
+$$
+\returnType{Type: Equation Expression Integer}
+
+Finally, we solve it.
+
+\spadcommand{solve(deq, y, x) }
+$$
+{{{y \left({x} \right)}\  {{\log \left({{y \left({x} \right)}}\right)}\sp 2}}-
+{2 \  x}} \over {2 \  {y \left({x} \right)}}
+$$
+\returnType{Type: Union(Expression Integer,...)}
+
+\subsection{Power Series Solutions of Differential Equations}
+\label{ugxProblemDEQSeries}
+
+The command to solve differential equations in power
+\index{equation!differential!solving in power series} series
+\index{power series} around \index{series!power} a particular initial
+point with specific initial conditions is called {\bf seriesSolve}.
+It can take a variety of parameters, so we illustrate its use with
+some examples.
+
+Since the coefficients of some solutions are quite large, we reset the
+default to compute only seven terms.
+
+\spadcommand{)set streams calculate 7 }
+
+You can solve a single nonlinear equation of any order. For example,
+we solve 
+$$y''' = sin(y'') * exp(y) + cos(x)$$ subject to 
+$$y(0) = 1, y'(0) = 0, y''(0) = 0$$
+
+We first tell Axiom that the symbol $'y$ denotes a new operator.
+
+\spadcommand{y := operator 'y }
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+Enter the differential equation using $y$ like any system function.
+
+\spadcommand{eq := D(y(x), x, 3) - sin(D(y(x), x, 2))*exp(y(x)) = cos(x)}
+$$
+{{{y \sb {{\ }} \sp {,,,}} \left({x} \right)}-
+{{e \sp {y \left({x} \right)}}\  
+{\sin \left({{{y \sb {{\ }} \sp {,,}} \left({x} \right)}}\right)}}}=
+{\cos\left({x} \right)}
+$$
+\returnType{Type: Equation Expression Integer}
+
+Solve it around $x = 0$ with the initial conditions
+$y(0) = 1, y'(0) = y''(0) = 0$.
+
+\spadcommand{seriesSolve(eq, y, x = 0, [1, 0, 0])}
+$$
+1+
+{{1 \over 6} \  {x \sp 3}}+
+{{e \over {24}} \  {x \sp 4}}+
+{{{{e \sp 2} -1} \over {120}} \  {x \sp 5}}+
+{{{{e \sp 3} -{2 \  e}} \over {720}} \  {x \sp 6}}+
+{{{{e \sp 4} -{8 \  {e \sp 2}}+{4 \  e}+1} \over {5040}} \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateTaylorSeries(Expression Integer,x,0)}
+
+You can also solve a system of nonlinear first order equations.  For
+example, we solve a system that has $tan(t)$ and $sec(t)$ as
+solutions.
+
+We tell Axiom that $x$ is also an operator.
+
+\spadcommand{x := operator 'x}
+$$
+x 
+$$
+\returnType{Type: BasicOperator}
+
+Enter the two equations forming our system.
+
+\spadcommand{eq1 := D(x(t), t) = 1 + x(t)**2}
+$$
+{{x \sb {{\ }} \sp {,}} \left({t} \right)}=
+{{{x\left({t} \right)}\sp 2}+1} 
+$$
+\returnType{Type: Equation Expression Integer}
+
+\spadcommand{eq2 := D(y(t), t) = x(t) * y(t)}
+$$
+{{y \sb {{\ }} \sp {,}} \left({t} \right)}=
+{{x\left({t} \right)}\  {y \left({t} \right)}}
+$$
+\returnType{Type: Equation Expression Integer}
+
+Solve the system around $t = 0$ with the initial conditions $x(0) = 0$
+and $y(0) = 1$.  Notice that since we give the unknowns in the order
+$[x, y]$, the answer is a list of two series in the order 
+$$[{\rm series\ for\ } x(t), {\rm \ series\ for\ }y(t)]$$
+
+\spadcommand{seriesSolve([eq2, eq1], [x, y], t = 0, [y(0) = 1, x(0) = 0])}
+\begin{verbatim}
+   Compiling function %BZ with type List UnivariateTaylorSeries(
+      Expression Integer,t,0) -> UnivariateTaylorSeries(Expression 
+      Integer,t,0) 
+   Compiling function %CA with type List UnivariateTaylorSeries(
+      Expression Integer,t,0) -> UnivariateTaylorSeries(Expression 
+      Integer,t,0) 
+\end{verbatim}
+$$
+\left[
+{t+
+{{1 \over 3} \  {t \sp 3}}+
+{{2 \over {15}} \  {t \sp 5}}+
+{{{17} \over {315}} \  {t \sp 7}}+
+{O \left({{t \sp 8}} \right)}},
+{1+{{1 \over 2} \  {t \sp 2}}+
+{{5 \over {24}} \  {t \sp 4}}+
+{{{61} \over {720}} \  {t \sp 6}}+
+{O \left({{t \sp 8}} \right)}}
+\right]
+$$
+\returnType{Type: List UnivariateTaylorSeries(Expression Integer,t,0)}
+
+\noindent
+The order in which we give the equations and the initial conditions
+has no effect on the order of the solution.
+
+\section{Finite Fields}
+\label{ugProblemFinite}
+
+A {\it finite field} (also called a {\it Galois field}) is a finite
+algebraic structure where one can add, multiply and divide under the
+same laws (for example, commutativity, associativity or
+distributivity) as apply to the rational, real or complex numbers.
+Unlike those three fields, for any finite field there exists a
+positive prime integer $p$, called the {\bf characteristic}, such that
+$p x = 0$ for any element $x$ in the finite field.  In fact, the
+number of elements in a finite field is a power of the characteristic
+and for each prime $p$ and positive integer $n$ there exists exactly
+one finite field with $p^n$ elements, up to isomorphism.\footnote{For
+more information about the algebraic structure and properties of
+finite fields, see, for example, S.  Lang, {\it Algebra}, Second
+Edition, New York: Addison-Wesley Publishing Company, Inc., 1984, ISBN
+0 201 05487 6; or R.  Lidl, H.  Niederreiter, {\it Finite Fields},
+Encyclopedia of Mathematics and Its Applications, Vol.  20, Cambridge:
+Cambridge Univ.  Press, 1983, ISBN 0 521 30240 4.}
+
+When $n = 1,$ the field has $p$ elements and is called a {\it prime
+field}, discussed in the next section.  There are several ways of
+implementing extensions of finite fields, and Axiom provides quite a
+bit of freedom to allow you to choose the one that is best for your
+application.  Moreover, we provide operations for converting among the
+different representations of extensions and different extensions of a
+single field.  Finally, note that you usually need to package-call
+operations from finite fields if the operations do not take as an
+argument an object of the field.  See 
+\ref{ugTypesPkgCall} on page~\pageref{ugTypesPkgCall} for more
+information on package-calling.
+
+\subsection{Modular Arithmetic and Prime Fields}
+\label{ugxProblemFinitePrime}
+\index{finite field}
+\index{Galois!field}
+\index{field!finite!prime}
+\index{field!prime}
+\index{field!Galois}
+\index{prime field}
+\index{modular arithmetic}
+\index{arithmetic!modular}
+
+Let $n$ be a positive integer.  It is well known that you can get the
+same result if you perform addition, subtraction or multiplication of
+integers and then take the remainder on dividing by $n$ as if you had
+first done such remaindering on the operands, performed the arithmetic
+and then (if necessary) done remaindering again.  This allows us to
+speak of arithmetic {\it modulo} $n$ or, more simply {\it mod} $n$.
+
+In Axiom, you use {\tt IntegerMod} to do such arithmetic.
+
+\spadcommand{(a,b) : IntegerMod 12 }
+\returnType{Type: Void}
+
+\spadcommand{(a, b) := (16, 7) }
+$$
+7 
+$$
+\returnType{Type: IntegerMod 12}
+
+\spadcommand{[a - b, a * b] }
+$$
+\left[
+9, 4 
+\right]
+$$
+\returnType{Type: List IntegerMod 12}
+
+If $n$ is not prime, there is only a limited notion of reciprocals and
+division.
+
+\spadcommand{a / b }
+\begin{verbatim}
+   There are 12 exposed and 13 unexposed library operations named / 
+      having 2 argument(s) but none was determined to be applicable. 
+      Use HyperDoc Browse, or issue
+                                )display op /
+      to learn more about the available operations. Perhaps 
+      package-calling the operation or using coercions on the arguments
+      will allow you to apply the operation.
+ 
+   Cannot find a definition or applicable library operation named / 
+      with argument type(s) 
+                                IntegerMod 12
+                                IntegerMod 12
+      
+      Perhaps you should use "@" to indicate the required return type, 
+      or "$" to specify which version of the function you need.
+\end{verbatim}
+
+\spadcommand{recip a }
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+Here $7$ and $12$ are relatively prime, so $7$ has a multiplicative
+inverse modulo $12$.
+
+\spadcommand{recip b }
+$$
+7 
+$$
+\returnType{Type: Union(IntegerMod 12,...)}
+
+If we take $n$ to be a prime number $p$, then taking inverses and,
+therefore, division are generally defined.
+
+Use {\tt PrimeField} instead of {\tt IntegerMod} for $n$ prime.
+
+\spadcommand{c : PrimeField 11 := 8 }
+$$
+8 
+$$
+\returnType{Type: PrimeField 11}
+
+\spadcommand{inv c }
+$$
+7 
+$$
+\returnType{Type: PrimeField 11}
+
+You can also use $1/c$ and $c**(-1)$ for the inverse of $c$.
+
+\spadcommand{9/c }
+$$
+8 
+$$
+\returnType{Type: PrimeField 11}
+
+{\tt PrimeField} (abbreviation {\tt PF}) checks if its argument is
+prime when you try to use an operation from it.  If you know the
+argument is prime (particularly if it is large), {\tt InnerPrimeField}
+(abbreviation {\tt IPF}) assumes the argument has already been
+verified to be prime.  If you do use a number that is not prime, you
+will eventually get an error message, most likely a division by zero
+message.  For computer science applications, the most important finite
+fields are {\tt PrimeField 2} and its extensions.
+
+In the following examples, we work with the finite field with 
+$p = 101$ elements.
+
+\spadcommand{GF101 := PF 101  }
+$$
+\mbox{\rm PrimeField 101} 
+$$
+\returnType{Type: Domain}
+
+Like many domains in Axiom, finite fields provide an operation for
+returning a random element of the domain.
+
+\spadcommand{x := random()\$GF101 }
+$$
+8 
+$$
+\returnType{Type: PrimeField 101}
+
+\spadcommand{y : GF101 := 37 }
+$$
+37 
+$$
+\returnType{Type: PrimeField 101}
+
+\spadcommand{z := x/y }
+$$
+63 
+$$
+\returnType{Type: PrimeField 101}
+
+\spadcommand{z * y - x }
+$$
+0 
+$$
+\returnType{Type: PrimeField 101}
+
+The element $2$ is a {\it primitive element} of this field,
+\index{primitive element}
+\index{element!primitive}
+
+\spadcommand{pe := primitiveElement()\$GF101 }
+$$
+2 
+$$
+\returnType{Type: PrimeField 101}
+
+in the sense that its powers enumerate all nonzero elements.
+
+\spadcommand{[pe**i for i in 0..99] }
+$$
+\begin{array}{@{}l}
+\left[
+1, 2, 4, 8, {16}, {32}, {64}, {27}, {54}, 7, {14}, {28}, {56}, 
+{11}, {22}, {44}, {88}, {75}, {49}, {98}, 
+\right.
+\\
+\displaystyle
+{95}, {89}, {77}, {53}, 5, {10}, {20}, {40}, {80}, {59}, {17}, 
+{34}, {68}, {35}, {70}, {39}, {78}, {55}, 9, 
+\\
+\displaystyle
+{18}, {36}, {72}, {43}, {86}, {71}, {41}, {82}, {63}, {25}, 
+{50}, {100}, {99}, {97}, {93}, {85}, {69}, {37}, 
+\\
+\displaystyle
+{74}, {47}, {94}, {87}, {73}, {45}, {90}, {79}, {57}, {13}, 
+{26}, {52}, 3, 6, {12}, {24}, {48}, {96}, {91}, 
+\\
+\displaystyle
+{81}, {61}, {21}, {42}, {84}, {67}, {33}, {66}, {31}, {62}, 
+{23}, {46}, {92}, {83}, {65}, {29}, {58}, {15}, {30}, 
+\\
+\displaystyle
+\left.
+{60}, {19}, {38}, {76}, {51} 
+\right]
+\end{array}
+$$
+\returnType{Type: List PrimeField 101}
+
+If every nonzero element is a power of a primitive element, how do you
+determine what the exponent is?  Use \index{discrete logarithm} 
+{\bf discreteLog}.  \index{logarithm!discrete}
+
+\spadcommand{ex := discreteLog(y) }
+$$
+56 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{pe ** ex }
+$$
+37 
+$$
+\returnType{Type: PrimeField 101}
+
+The {\bf order} of a nonzero element $x$ is the smallest positive
+integer $t$ such $x^t = 1$.
+
+\spadcommand{order y }
+$$
+25 
+$$
+\returnType{Type: PositiveInteger}
+
+The order of a primitive element is the defining $p-1$.
+
+\spadcommand{order pe }
+$$
+100 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Extensions of Finite Fields}
+\label{ugxProblemFiniteExtensionFinite}
+\index{finite field}
+\index{field!finite!extension of}
+
+When you want to work with an extension of a finite field in Axiom,
+you have three choices to make:
+\begin{enumerate}
+\item Do you want to generate an extension of the prime field
+(for example, {\tt PrimeField 2}) or an extension of a given field?
+\item Do you want to use a representation that is particularly
+efficient for multiplication, exponentiation and addition but uses a
+lot of computer memory (a representation that models the cyclic group
+structure of the multiplicative group of the field extension and uses
+a Zech logarithm table), one that \index{Zech logarithm} uses a normal
+basis for the vector space structure of the field extension, or one
+that performs arithmetic modulo an irreducible polynomial?  The cyclic
+group representation is only usable up to ``medium'' (relative to your
+machine's performance) sized fields.  If the field is large and the
+normal basis is relatively simple, the normal basis representation is
+more efficient for exponentiation than the irreducible polynomial
+representation.
+\item Do you want to provide a polynomial explicitly, a root of which
+``generates'' the extension in one of the three senses in (2), or do
+you wish to have the polynomial generated for you?
+\end{enumerate}
+
+This illustrates one of the most important features of Axiom: you can
+choose exactly the right data-type and representation to suit your
+application best.
+
+We first tell you what domain constructors to use for each case above,
+and then give some examples.
+
+\hangafter=1\hangindent=2pc
+Constructors that automatically generate extensions of the prime field:
+\newline
+{\tt FiniteField} \newline
+{\tt FiniteFieldCyclicGroup} \newline
+{\tt FiniteFieldNormalBasis}
+
+\hangafter=1\hangindent=2pc
+Constructors that generate extensions of an arbitrary field:
+\newline
+{\tt FiniteFieldExtension} \newline
+{\tt FiniteFieldExtensionByPolynomial} \newline
+{\tt FiniteFieldCyclicGroupExtension} \newline
+{\tt FiniteFieldCyclicGroupExtensionByPolynomial} \newline
+{\tt FiniteFieldNormalBasisExtension} \newline
+{\tt FiniteFieldNormalBasisExtensionByPolynomial}
+
+\hangafter=1\hangindent=2pc
+Constructors that use a cyclic group representation:
+\newline
+{\tt FiniteFieldCyclicGroup} \newline
+{\tt FiniteFieldCyclicGroupExtension} \newline
+{\tt FiniteFieldCyclicGroupExtensionByPolynomial}
+
+\hangafter=1\hangindent=2pc
+Constructors that use a normal basis representation:
+\newline
+{\tt FiniteFieldNormalBasis} \newline
+{\tt FiniteFieldNormalBasisExtension} \newline
+{\tt FiniteFieldNormalBasisExtensionByPolynomial}
+
+\hangafter=1\hangindent=2pc
+Constructors that use an irreducible modulus polynomial representation:
+\newline
+{\tt FiniteField} \newline
+{\tt FiniteFieldExtension} \newline
+{\tt FiniteFieldExtensionByPolynomial}
+
+\hangafter=1\hangindent=2pc
+Constructors that generate a polynomial for you:
+\newline
+{\tt FiniteField} \newline
+{\tt FiniteFieldExtension} \newline
+{\tt FiniteFieldCyclicGroup} \newline
+{\tt FiniteFieldCyclicGroupExtension} \newline
+{\tt FiniteFieldNormalBasis} \newline
+{\tt FiniteFieldNormalBasisExtension}
+
+\hangafter=1\hangindent=2pc
+Constructors for which you provide a polynomial:
+\newline
+{\tt FiniteFieldExtensionByPolynomial} \newline
+{\tt FiniteFieldCyclicGroupExtensionByPolynomial} \newline
+{\tt FiniteFieldNormalBasisExtensionByPolynomial}
+
+These constructors are discussed in the following sections where we
+collect together descriptions of extension fields that have the same
+underlying representation.\footnote{For more information on the
+implementation aspects of finite fields, see J. Grabmeier,
+A. Scheerhorn, {\it Finite Fields in AXIOM,} Technical Report, IBM
+Heidelberg Scientific Center, 1992.}
+
+If you don't really care about all this detail, just use {\tt
+FiniteField}.  As your knowledge of your application and its Axiom
+implementation grows, you can come back and choose an alternative
+constructor that may improve the efficiency of your code.  Note that
+the exported operations are almost the same for all constructors of
+finite field extensions and include the operations exported by {\tt
+PrimeField}.
+
+\subsection{Irreducible Modulus Polynomial Representations}
+\label{ugxProblemFiniteModulus}
+
+All finite field extension constructors discussed in this
+\index{finite field} section \index{field!finite!extension of} use a
+representation that performs arithmetic with univariate (one-variable)
+polynomials modulo an irreducible polynomial.  This polynomial may be
+given explicitly by you or automatically generated.  The ground field
+may be the prime field or one you specify.  See
+\ref{ugxProblemFiniteExtensionFinite} on 
+page~\pageref{ugxProblemFiniteExtensionFinite} for general information about
+finite field extensions.
+
+For {\tt FiniteField} (abbreviation {\tt FF}) you provide a prime
+number $p$ and an extension degree $n$.  This degree can be 1.
+
+Axiom uses the prime field {\tt PrimeField(p)}, here {\tt PrimeField 2}, 
+and it chooses an irreducible polynomial of degree $n$, here 12,
+over the ground field.
+
+\spadcommand{GF4096 := FF(2,12); }
+\returnType{Type: Domain}
+
+The objects in the generated field extension are polynomials of degree
+at most $n-1$ with coefficients in the prime field.  The polynomial
+indeterminate is automatically chosen by Axiom and is typically
+something like $\%A$ or $\%D$.  These (strange) variables are 
+{\it only} for output display; there are several ways to construct 
+elements of this field.
+
+The operation {\bf index} enumerates the elements of the field
+extension and accepts as argument the integers from 1 to $p ^ n$.
+
+The expression $index(p)$ always gives the indeterminate.
+
+\spadcommand{a := index(2)\$GF4096 }
+$$
+\%A 
+$$
+\returnType{Type: FiniteField(2,12)}
+
+You can build polynomials in $a$ and calculate in $GF4096$.
+
+\spadcommand{b := a**12 - a**5 + a }
+$$
+{ \%A \sp 5}+{ \%A \sp 3}+ \%A+1 
+$$
+\returnType{Type: FiniteField(2,12)}
+
+\spadcommand{b ** 1000 }
+$$
+{ \%A \sp {10}}+
+{ \%A \sp 9}+
+{ \%A \sp 7}+
+{ \%A \sp 5}+
+{ \%A \sp 4}+
+{  \%A \sp 3}+ 
+\%A 
+$$
+\returnType{Type: FiniteField(2,12)}
+
+\spadcommand{c := a/b }
+$$
+{ \%A \sp {11}}+
+{ \%A \sp 8}+
+{ \%A \sp 7}+
+{ \%A \sp 5}+
+{ \%A \sp 4}+
+{  \%A \sp 3}+
+{ \%A \sp 2} 
+$$
+\returnType{Type: FiniteField(2,12)}
+
+Among the available operations are {\bf norm} and {\bf trace}.
+
+\spadcommand{norm c }
+$$
+1 
+$$
+\returnType{Type: PrimeField 2}
+
+\spadcommand{trace c }
+$$
+0 
+$$
+\returnType{Type: PrimeField 2}
+
+Since any nonzero element is a power of a primitive element, how do we
+discover what the exponent is?
+
+The operation {\bf discreteLog} calculates \index{discrete logarithm}
+the exponent and, \index{logarithm!discrete} if it is called with only
+one argument, always refers to the primitive element returned by {\bf
+primitiveElement}.
+
+\spadcommand{dL := discreteLog a }
+$$
+1729 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{g ** dL }
+$$
+g \sp {1729} 
+$$
+\returnType{Type: Polynomial Integer}
+
+{\tt FiniteFieldExtension} (abbreviation {\tt FFX}) is similar to {\tt
+FiniteField} except that the ground-field for {\tt FiniteFieldExtension} 
+is arbitrary and chosen by you.
+
+In case you select the prime field as ground field, there is
+essentially no difference between the constructed two finite field
+extensions.
+
+\spadcommand{GF16 := FF(2,4); }
+\returnType{Type: Domain}
+
+\spadcommand{GF4096 := FFX(GF16,3); }
+\returnType{Type: Domain}
+
+\spadcommand{r := (random()\$GF4096) ** 20 }
+$$
+{{\left( { \%B \sp 2}+1 \right)}\  { \%C \sp 2}}+
+{{\left( { \%B \sp 3}+{ \%B \sp 2}+1 \right)}\  \%C}+
+{ \%B \sp 3}+
+{ \%B \sp 2}+ 
+\%B+1 
+$$
+\returnType{Type: FiniteFieldExtension(FiniteField(2,4),3)}
+
+\spadcommand{norm(r) }
+$$
+{ \%B \sp 2}+ \%B 
+$$
+\returnType{Type: FiniteField(2,4)}
+
+{\tt FiniteFieldExtensionByPolynomial} (abbreviation {\tt FFP})
+is similar to {\tt FiniteField} and {\tt FiniteFieldExtension}
+but is more general.
+
+\spadcommand{GF4 := FF(2,2); }
+\returnType{Type: Domain}
+
+\spadcommand{f := nextIrreduciblePoly(random(6)\$FFPOLY(GF4))\$FFPOLY(GF4) }
+$$
+{? \sp 6}+
+{{\left( \%D+1 \right)}\  {? \sp 5}}+
+{{\left( \%D+1 \right)}\  {? \sp 4}}+
+{{\left( \%D+1 \right)}\  ?}+1 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial FiniteField(2,2),...)}
+
+For {\tt FFP} you choose both the ground field and the irreducible
+polynomial used in the representation.  The degree of the extension is
+the degree of the polynomial.
+
+\spadcommand{GF4096 := FFP(GF4,f); }
+\returnType{Type: Domain}
+
+\spadcommand{discreteLog random()\$GF4096 }
+$$
+582 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Cyclic Group Representations}
+\label{ugxProblemFiniteCyclic}
+\index{finite field}
+\index{field!finite!extension of}
+
+In every finite field there exist elements whose powers are all the
+nonzero elements of the field.  Such an element is called a 
+{\it primitive element}.
+
+In {\tt FiniteFieldCyclicGroup} (abbreviation {\tt FFCG})
+\index{group!cyclic} the nonzero elements are represented by the
+powers of a fixed primitive \index{element!primitive} element
+\index{primitive element} of the field (that is, a generator of its
+cyclic multiplicative group).  Multiplication (and hence
+exponentiation) using this representation is easy.  To do addition, we
+consider our primitive element as the root of a primitive polynomial
+(an irreducible polynomial whose roots are all primitive).  See
+\ref{ugxProblemFiniteUtility} on page~\pageref{ugxProblemFiniteUtility} 
+for examples of how to compute such a polynomial.
+
+To use {\tt FiniteFieldCyclicGroup} you provide a prime number and an
+extension degree.
+\spadcommand{GF81 := FFCG(3,4); }
+\returnType{Type: Domain}
+
+Axiom uses the prime field, here {\tt PrimeField 3}, as the ground
+field and it chooses a primitive polynomial of degree $n$, here 4,
+over the prime field.
+
+\spadcommand{a := primitiveElement()\$GF81 }
+$$
+ \%F \sp 1 
+$$
+\returnType{Type: FiniteFieldCyclicGroup(3,4)}
+
+You can calculate in $GF81$.
+
+\spadcommand{b  := a**12 - a**5 + a }
+$$
+ \%F \sp {72} 
+$$
+\returnType{Type: FiniteFieldCyclicGroup(3,4)}
+
+In this representation of finite fields the discrete logarithm of an
+element can be seen directly in its output form.
+
+\spadcommand{b }
+$$
+ \%F \sp {72} 
+$$
+\returnType{Type: FiniteFieldCyclicGroup(3,4)}
+
+\spadcommand{discreteLog b }
+$$
+72 
+$$
+\returnType{Type: PositiveInteger}
+
+{\tt FiniteFieldCyclicGroupExtension} (abbreviation {\tt FFCGX}) is
+similar to {\tt FiniteFieldCyclicGroup} except that the ground field
+for {\tt FiniteFieldCyclicGroupExtension} is arbitrary and chosen by
+you.  In case you select the prime field as ground field, there is
+essentially no difference between the constructed two finite field
+extensions.
+
+\spadcommand{GF9 := FF(3,2); }
+\returnType{Type: Domain}
+
+\spadcommand{GF729 := FFCGX(GF9,3); }
+\returnType{Type: Domain}
+
+\spadcommand{r := (random()\$GF729) ** 20 }
+$$
+ \%H \sp {420} 
+$$
+\returnType{Type: FiniteFieldCyclicGroupExtension(FiniteField(3,2),3)}
+
+\spadcommand{trace(r) }
+$$
+0 
+$$
+\returnType{Type: FiniteField(3,2)}
+
+{\tt FiniteFieldCyclicGroupExtensionByPolynomial} (abbreviation 
+{\tt FFCGP}) is similar to {\tt FiniteFieldCyclicGroup} and 
+{\tt FiniteFieldCyclicGroupExtension} but is more general.  For 
+{\tt FiniteFieldCyclicGroupExtensionByPolynomial} you choose both the
+ground field and the irreducible polynomial used in the
+representation.  The degree of the extension is the degree of the
+polynomial.
+
+\spadcommand{GF3  := PrimeField 3; }
+\returnType{Type: Domain}
+
+We use a utility operation to generate an irreducible primitive
+polynomial (see 
+\ref{ugxProblemFiniteUtility} on page~\pageref{ugxProblemFiniteUtility}).  
+The polynomial has one variable that is ``anonymous'': 
+it displays as a question mark.
+
+\spadcommand{f := createPrimitivePoly(4)\$FFPOLY(GF3) }
+$$
+{? \sp 4}+?+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 3}
+
+\spadcommand{GF81 := FFCGP(GF3,f); }
+\returnType{Type: Domain}
+
+Let's look at a random element from this field.
+
+\spadcommand{random()\$GF81 }
+$$
+ \%K \sp {13} 
+$$
+\returnType{Type: 
+FiniteFieldCyclicGroupExtensionByPolynomial(PrimeField 3,?**4+?+2)}
+
+\subsection{Normal Basis Representations}
+\label{ugxProblemFiniteNormal}
+\index{finite field}
+\index{field!finite!extension of}
+\index{basis!normal}
+\index{normal basis}
+
+Let $K$ be a finite extension of degree $n$ of the finite field $F$
+and let $F$ have $q$ elements.  An element $x$ of $K$ is said to be
+{\it normal} over $F$ if the elements
+
+$$1, x^q, x^{q^2}, \ldots, x^{q^{n-1}}$$
+
+form a basis of $K$ as a vector space over $F$.  Such a basis is
+called a {\it normal basis}.\footnote{This agrees with the general
+definition of a normal basis because the $n$ distinct powers of the
+automorphism $x \mapsto x^q$ constitute the Galois group of $K/F$.}
+
+If $x$ is normal over $F$, its minimal \index{polynomial!minimal}
+polynomial is also said to be {\it normal} over $F$.  
+\index{minimal polynomial} 
+There exist normal bases for all finite extensions of arbitrary 
+finite fields.
+
+In {\tt FiniteFieldNormalBasis} (abbreviation {\tt FFNB}), the
+elements of the finite field are represented by coordinate vectors
+with respect to a normal basis.
+
+You provide a prime $p$ and an extension degree $n$.
+
+\spadcommand{K := FFNB(3,8) }
+$$
+FiniteFieldNormalBasis(3,8) 
+$$
+\returnType{Type: Domain}
+
+Axiom uses the prime field {\tt PrimeField(p)}, here {\tt PrimeField
+3}, and it chooses a normal polynomial of degree $n$, here 8, over the
+ground field.  The remainder class of the indeterminate is used as the
+normal element.  The polynomial indeterminate is automatically chosen
+by Axiom and is typically something like $\%A$ or $\%D$.  These
+(strange) variables are only for output display; there are several
+ways to construct elements of this field.  The output of the basis
+elements is something like $\%A^{q^i}.$
+
+\spadcommand{a := normalElement()\$K }
+$$
+ \%I 
+$$
+\returnType{Type: FiniteFieldNormalBasis(3,8)}
+
+You can calculate in $K$ using $a$.
+
+\spadcommand{b  := a**12 - a**5 + a }
+$$
+{2 \  { \%I \sp {q \sp 7}}}+{ \%I \sp {q \sp 5}}+{ \%I \sp q} 
+$$
+\returnType{Type: FiniteFieldNormalBasis(3,8)}
+
+{\tt FiniteFieldNormalBasisExtension} (abbreviation {\tt FFNBX}) is
+similar to {\tt FiniteFieldNormalBasis} except that the groundfield
+for {\tt FiniteFieldNormalBasisExtension} is arbitrary and chosen by
+you.  In case you select the prime field as ground field, there is
+essentially no difference between the constructed two finite field
+extensions.
+
+\spadcommand{GF9 := FFNB(3,2); }
+\returnType{Type: Domain}
+
+\spadcommand{GF729 := FFNBX(GF9,3); }
+\returnType{Type: Domain}
+
+\spadcommand{r := random()\$GF729 }
+$$
+2 \  \%K \  { \%L \sp q} 
+$$
+\returnType{Type: 
+FiniteFieldNormalBasisExtension(FiniteFieldNormalBasis(3,2),3)}
+
+\spadcommand{r + r**3 + r**9 + r**27 }
+$$
+{2 \  \%K \  { \%L \sp {q \sp 2}}}+
+{{\left( {2 \  { \%K \sp q}}+{2 \   \%K} \right)}\  { \%L \sp q}}+
+{2 \  { \%K \sp q} \  \%L} 
+$$
+\returnType{Type: 
+FiniteFieldNormalBasisExtension(FiniteFieldNormalBasis(3,2),3)}
+
+{\tt FiniteFieldNormalBasisExtensionByPolynomial} (abbreviation 
+{\tt FFNBP}) is similar to {\tt FiniteFieldNormalBasis} and 
+{\tt FiniteFieldNormalBasisExtension} but is more general.  For 
+{\tt FiniteFieldNormalBasisExtensionByPolynomial} you choose both the
+ground field and the irreducible polynomial used in the representation.  
+The degree of the extension is the degree of the polynomial.
+
+\spadcommand{GF3 := PrimeField 3; }
+\returnType{Type: Domain}
+
+We use a utility operation to generate an irreducible normal
+polynomial (see 
+\ref{ugxProblemFiniteUtility} on page~\pageref{ugxProblemFiniteUtility}).  
+The polynomial has
+one variable that is ``anonymous'': it displays as a question mark.
+
+\spadcommand{f := createNormalPoly(4)\$FFPOLY(GF3) }
+$$
+{? \sp 4}+{2 \  {? \sp 3}}+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 3}
+
+\spadcommand{GF81 := FFNBP(GF3,f); }
+\returnType{Type: Domain}
+
+Let's look at a random element from this field.
+
+\spadcommand{r := random()\$GF81 }
+$$
+{ \%M \sp {q \sp 2}}+{2 \  { \%M \sp q}}+{2 \  \%M} 
+$$
+\returnType{Type: 
+FiniteFieldNormalBasisExtensionByPolynomial(PrimeField 3,?**4+2*?**3+2)}
+
+\spadcommand{r * r**3 * r**9 * r**27 }
+$$
+{2 \  { \%M \sp {q \sp 3}}}+
+{2 \  { \%M \sp {q \sp 2}}}+
+{2 \  { \%M \sp q}}+
+{2 \  \%M} 
+$$
+\returnType{Type: 
+FiniteFieldNormalBasisExtensionByPolynomial(PrimeField 3,?**4+2*?**3+2)}
+
+\spadcommand{norm r }
+$$
+2 
+$$
+\returnType{Type: PrimeField 3}
+
+\subsection{Conversion Operations for Finite Fields}
+\label{ugxProblemFiniteConversion}
+\index{field!finite!conversions}
+
+Let $K$ be a finite field.
+
+\spadcommand{K := PrimeField 3 }
+$$
+\mbox{\rm PrimeField 3} 
+$$
+\returnType{Type: Domain}
+
+An extension field $K_m$ of degree $m$ over $K$ is a subfield of an
+extension field $K_n$ of degree $n$ over $K$ if and only if $m$
+divides $n$.
+
+\begin{center}
+\begin{tabular}{ccc}
+$K_n$ \\
+$|$ \\
+$K_m$ & $\Longleftrightarrow$ & $m | n$ \\
+$|$ \\
+K
+\end{tabular}
+\end{center}
+
+{\tt FiniteFieldHomomorphisms} provides conversion operations between
+different extensions of one fixed finite ground field and between
+different representations of these finite fields.
+
+Let's choose $m$ and $n$,
+
+\spadcommand{(m,n) := (4,8) }
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+build the field extensions,
+
+\spadcommand{Km := FiniteFieldExtension(K,m) }
+$$
+\mbox{\rm FiniteFieldExtension(PrimeField 3,4)} 
+$$
+\returnType{Type: Domain}
+
+and pick two random elements from the smaller field.
+
+\spadcommand{Kn := FiniteFieldExtension(K,n) }
+$$
+\mbox{\rm FiniteFieldExtension(PrimeField 3,8)} 
+$$
+\returnType{Type: Domain}
+
+\spadcommand{a1 := random()\$Km }
+$$
+{2 \  { \%A \sp 3}}+{ \%A \sp 2} 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,4)}
+
+\spadcommand{b1 := random()\$Km }
+$$
+{ \%A \sp 3}+{ \%A \sp 2}+{2 \  \%A}+1 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,4)}
+
+Since $m$ divides $n$,
+$K_m$ is a subfield of $K_n$.
+
+\spadcommand{a2 := a1 :: Kn }
+$$
+ \%B \sp 4 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,8)}
+
+Therefore we can convert the elements of $K_m$
+into elements of $K_n$.
+
+\spadcommand{b2 := b1 :: Kn }
+$$
+{2 \  { \%B \sp 6}}+{2 \  { \%B \sp 4}}+{ \%B \sp 2}+1 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,8)}
+
+To check this, let's do some arithmetic.
+
+\spadcommand{a1+b1 - ((a2+b2) :: Km) }
+$$
+0 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,4)}
+
+\spadcommand{a1*b1 - ((a2*b2) :: Km) }
+$$
+0 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 3,4)}
+
+There are also conversions available for the situation, when $K_m$ and
+$K_n$ are represented in different ways (see
+\ref{ugxProblemFiniteExtensionFinite} on 
+page~\pageref{ugxProblemFiniteExtensionFinite}).  For example let's choose
+$K_m$ where the representation is 0 plus the cyclic multiplicative
+group and $K_n$ with a normal basis representation.
+
+\spadcommand{Km := FFCGX(K,m) }
+$$
+\mbox{\rm FiniteFieldCyclicGroupExtension(PrimeField 3,4)} 
+$$
+\returnType{Type: Domain}
+
+\spadcommand{Kn := FFNBX(K,n) }
+$$
+\mbox{\rm FiniteFieldNormalBasisExtension(PrimeField 3,8)} 
+$$
+\returnType{Type: Domain}
+
+\spadcommand{(a1,b1) := (random()\$Km,random()\$Km) }
+$$
+ \%C \sp {13} 
+$$
+\returnType{Type: FiniteFieldCyclicGroupExtension(PrimeField 3,4)}
+
+\spadcommand{a2 := a1 :: Kn }
+$$
+{2 \  { \%D \sp {q \sp 6}}}+
+{2 \  { \%D \sp {q \sp 5}}}+
+{2 \  { \%D \sp {q \sp 4}}}+
+{2 \  { \%D \sp {q \sp 2}}}+
+{2 \  { \%D \sp q}}+
+{2 \  \%D} 
+$$
+\returnType{Type: FiniteFieldNormalBasisExtension(PrimeField 3,8)}
+
+\spadcommand{b2 := b1 :: Kn }
+$$
+{2 \  { \%D \sp {q \sp 7}}}+
+{ \%D \sp {q \sp 6}}+
+{ \%D \sp {q \sp 5}}+
+{ \%D \sp {q \sp 4}}+
+{2 \  { \%D \sp {q \sp 3}}}+
+{ \%D \sp {q \sp 2}}+
+{ \%D \sp q}+ 
+\%D 
+$$
+\returnType{Type: FiniteFieldNormalBasisExtension(PrimeField 3,8)}
+
+Check the arithmetic again.
+
+\spadcommand{a1+b1 - ((a2+b2) :: Km) }
+$$
+0 
+$$
+\returnType{Type: FiniteFieldCyclicGroupExtension(PrimeField 3,4)}
+
+\spadcommand{a1*b1 - ((a2*b2) :: Km) }
+$$
+0 
+$$
+\returnType{Type: FiniteFieldCyclicGroupExtension(PrimeField 3,4)}
+
+\subsection{Utility Operations for Finite Fields}
+\label{ugxProblemFiniteUtility}
+
+{\tt FiniteFieldPolynomialPackage} (abbreviation {\tt FFPOLY})
+provides operations for generating, counting and testing polynomials
+over finite fields. Let's start with a couple of definitions:
+\begin{itemize}
+\item A polynomial is {\it primitive} if its roots are primitive
+\index{polynomial!primitive}
+elements in an extension of the coefficient field of degree equal
+to the degree of the polynomial.
+\item A polynomial is {\it normal} over its coefficient field
+\index{polynomial!normal}
+if its roots are linearly independent
+elements in an extension of the coefficient field of degree equal
+to the degree of the polynomial.
+\end{itemize}
+
+In what follows, many of the generated polynomials have one
+``anonymous'' variable.  This indeterminate is displayed as a question
+mark ({\tt ``?''}).
+
+To fix ideas, let's use the field with five elements for the first
+few examples.
+
+\spadcommand{GF5 := PF 5; }
+\returnType{Type: Domain}
+
+You can generate irreducible polynomials of any (positive) degree
+\index{polynomial!irreducible} (within the storage capabilities of the
+computer and your ability to wait) by using
+\spadfunFrom{createIrreduciblePoly}{FiniteFieldPolynomialPackage}.
+
+\spadcommand{f := createIrreduciblePoly(8)\$FFPOLY(GF5) }
+$$
+{? \sp 8}+{? \sp 4}+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+Does this polynomial have other important properties? Use
+{\bf primitive?} to test whether it is a primitive polynomial.
+
+\spadcommand{primitive?(f)\$FFPOLY(GF5) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Use {\bf normal?} to test whether it is a normal polynomial.
+
+\spadcommand{normal?(f)\$FFPOLY(GF5) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\noindent
+Note that this is actually a trivial case, because a normal polynomial
+of degree $n$ must have a nonzero term of degree $n-1$.  We will refer
+back to this later.
+
+To get a primitive polynomial of degree 8 just issue this.
+
+\spadcommand{p := createPrimitivePoly(8)\$FFPOLY(GF5) }
+$$
+{? \sp 8}+{? \sp 3}+{? \sp 2}+?+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+\spadcommand{primitive?(p)\$FFPOLY(GF5) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+This polynomial is not normal,
+
+\spadcommand{normal?(p)\$FFPOLY(GF5) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+but if you want a normal one simply write this.
+
+\spadcommand{n := createNormalPoly(8)\$FFPOLY(GF5)  }
+$$
+{? \sp 8}+{4 \  {? \sp 7}}+{? \sp 3}+1 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+This polynomial is not primitive!
+
+\spadcommand{primitive?(n)\$FFPOLY(GF5) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+This could have been seen directly, as the constant term is 1 here,
+which is not a primitive element up to the factor ($-1$) raised to the
+degree of the polynomial.\footnote{Cf. Lidl, R. \& Niederreiter, H.,
+{\it Finite Fields,} Encycl. of Math. 20, (Addison-Wesley, 1983),
+p.90, Th. 3.18.}
+
+What about polynomials that are both primitive and normal?  The
+existence of such a polynomial is by no means obvious.
+\footnote{The existence of such polynomials is proved in
+Lenstra, H. W. \& Schoof, R. J., {\it Primitive
+Normal Bases for Finite Fields,} Math. Comp. 48, 1987, pp. 217-231.}
+%
+
+If you really need one use either
+\spadfunFrom{createPrimitiveNormalPoly}{FiniteFieldPolynomialPackage} or
+\spadfunFrom{createNormalPrimitivePoly}{FiniteFieldPolynomialPackage}.
+
+\spadcommand{createPrimitiveNormalPoly(8)\$FFPOLY(GF5) }
+$$
+{? \sp 8}+{4 \  {? \sp 7}}+{2 \  {? \sp 5}}+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+If you want to obtain additional polynomials of the various types
+above as given by the {\bf create...} operations above, you can use
+the {\bf next...} operations.  For instance,
+\spadfunFrom{nextIrreduciblePoly}{FiniteFieldPolynomialPackage} yields
+the next monic irreducible polynomial with the same degree as the
+input polynomial.  By ``next'' we mean ``next in a natural order using
+the terms and coefficients.''  This will become more clear in the
+following examples.
+
+This is the field with five elements.
+
+\spadcommand{GF5 := PF 5; }
+\returnType{Type: Domain}
+
+Our first example irreducible polynomial, say of degree 3, must be
+``greater'' than this.
+
+\spadcommand{h := monomial(1,8)\$SUP(GF5) }
+$$
+? \sp 8 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+You can generate it by doing this.
+
+\spadcommand{nh := nextIrreduciblePoly(h)\$FFPOLY(GF5) }
+$$
+{? \sp 8}+2 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+Notice that this polynomial is not the same as the one
+\spadfunFrom{createIrreduciblePoly}{FiniteFieldPolynomialPackage}.
+
+\spadcommand{createIrreduciblePoly(3)\$FFPOLY(GF5) }
+$$
+{? \sp 3}+?+1 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+You can step through all irreducible polynomials of degree 8 over
+the field with 5 elements by repeatedly issuing this.
+
+\spadcommand{nh := nextIrreduciblePoly(nh)\$FFPOLY(GF5) }
+$$
+{? \sp 8}+3 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+You could also ask for the total number of these.
+
+\spadcommand{numberOfIrreduciblePoly(5)\$FFPOLY(GF5) }
+$$
+624 
+$$
+\returnType{Type: PositiveInteger}
+
+We hope that ``natural order'' on polynomials is now clear: first we
+compare the number of monomials of two polynomials (``more'' is
+``greater''); then, if necessary, the degrees of these monomials
+(lexicographically), and lastly their coefficients (also
+lexicographically, and using the operation {\bf lookup} if our field
+is not a prime field).  Also note that we make both polynomials monic
+before looking at the coefficients: multiplying either polynomial by a
+nonzero constant produces the same result.
+
+The package {\tt FiniteFieldPolynomialPackage} also provides similar
+operations for primitive and normal polynomials. With the exception of
+the number of primitive normal polynomials; we're not aware of any
+known formula for this.
+
+\spadcommand{numberOfPrimitivePoly(3)\$FFPOLY(GF5) }
+$$
+20 
+$$
+\returnType{Type: PositiveInteger}
+
+Take these,
+
+\spadcommand{m := monomial(1,1)\$SUP(GF5) }
+$$
+? 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+\spadcommand{f := m**3 + 4*m**2 + m + 2 }
+$$
+{? \sp 3}+{4 \  {? \sp 2}}+?+2 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+and then we have:
+
+\spadcommand{f1 := nextPrimitivePoly(f)\$FFPOLY(GF5) }
+$$
+{? \sp 3}+{4 \  {? \sp 2}}+{4 \  ?}+2 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+What happened?
+
+\spadcommand{nextPrimitivePoly(f1)\$FFPOLY(GF5) }
+$$
+{? \sp 3}+{2 \  {? \sp 2}}+3 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+Well, for the ordering used in
+\spadfunFrom{nextPrimitivePoly}{FiniteFieldPolynomialPackage} we use
+as first criterion a comparison of the constant terms of the
+polynomials.  Analogously, in
+\spadfunFrom{nextNormalPoly}{FiniteFieldPolynomialPackage} we first
+compare the monomials of degree 1 less than the degree of the
+polynomials (which is nonzero, by an earlier remark).
+
+\spadcommand{f := m**3 + m**2 + 4*m + 1  }
+$$
+{? \sp 3}+{? \sp 2}+{4 \  ?}+1 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 5}
+
+\spadcommand{f1 := nextNormalPoly(f)\$FFPOLY(GF5) }
+$$
+{? \sp 3}+{? \sp 2}+{4 \  ?}+3 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+\spadcommand{nextNormalPoly(f1)\$FFPOLY(GF5) }
+$$
+{? \sp 3}+{2 \  {? \sp 2}}+1 
+$$
+\returnType{Type: Union(SparseUnivariatePolynomial PrimeField 5,...)}
+
+\noindent
+We don't have to restrict ourselves to prime fields.
+
+Let's consider, say, a field with 16 elements.
+
+\spadcommand{GF16 := FFX(FFX(PF 2,2),2);  }
+\returnType{Type: Domain}
+
+We can apply any of the operations described above.
+
+\spadcommand{createIrreduciblePoly(5)\$FFPOLY(GF16) }
+$$
+{? \sp 5}+ \%G 
+$$
+\returnType{Type: SparseUnivariatePolynomial 
+FiniteFieldExtension(FiniteFieldExtension(PrimeField 2,2),2)}
+
+Axiom also provides operations for producing random polynomials of a
+given degree
+
+\spadcommand{random(5)\$FFPOLY(GF16) }
+$$
+\begin{array}{@{}l}
+{? \sp 5}+
+{{\left( { \%F \  \%G}+1 \right)}\  {? \sp 4}}+
+{ \%F \  \%G \  {? \sp 3}}+
+{{\left( \%G+ \%F+1 \right)}\  {? \sp 2}}+
+\\
+\\
+\displaystyle
+{{\left( {{\left( \%F+1 \right)}\  \%G}+ \%F \right)}\  ?}+1 
+\end{array}
+$$
+\returnType{Type: SparseUnivariatePolynomial 
+FiniteFieldExtension(FiniteFieldExtension(PrimeField 2,2),2)}
+
+or with degree between two given bounds.
+
+\spadcommand{random(3,9)\$FFPOLY(GF16) }
+$$
+{? \sp 3}+
+{{\left( { \%F \  \%G}+1 \right)}\  {? \sp 2}}+
+{{\left( \%G+ \%F+1 \right)}\  ?}+1 
+$$
+\returnType{Type: SparseUnivariatePolynomial 
+FiniteFieldExtension(FiniteFieldExtension(PrimeField 2,2),2)}
+
+{\tt FiniteFieldPolynomialPackage2} (abbreviation {\tt FFPOLY2})
+exports an operation {\bf rootOfIrreduciblePoly} for finding one root
+of an irreducible polynomial $f$ \index{polynomial!root of} in an
+extension field of the coefficient field.  The degree of the extension
+has to be a multiple of the degree of $f$.  It is not checked whether
+$f$ actually is irreducible.
+
+To illustrate this operation, we fix a ground field $GF$
+
+\spadcommand{GF2 := PrimeField 2; }
+\returnType{Type: Domain}
+
+and then an extension field.
+
+\spadcommand{F := FFX(GF2,12) }
+$$
+\mbox{\rm FiniteFieldExtension(PrimeField 2,12)} 
+$$
+\returnType{Type: Domain}
+
+We construct an irreducible polynomial over $GF2$.
+
+\spadcommand{f := createIrreduciblePoly(6)\$FFPOLY(GF2) }
+$$
+{? \sp 6}+?+1 
+$$
+\returnType{Type: SparseUnivariatePolynomial PrimeField 2}
+
+We compute a root of $f$.
+
+\spadcommand{root := rootOfIrreduciblePoly(f)\$FFPOLY2(F,GF2) }
+$$
+{ \%H \sp {11}}+{ \%H \sp 8}+{ \%H \sp 7}+{ \%H \sp 5}+ \%H+1 
+$$
+\returnType{Type: FiniteFieldExtension(PrimeField 2,12)}
+
+and check the result
+\spadcommand{eval(f, monomial(1,1)\$SUP(F) = root) }
+$$
+0 
+$$
+\returnType{Type: SparseUnivariatePolynomial 
+FiniteFieldExtension(PrimeField 2,12)}
+
+\section{Primary Decomposition of Ideals}
+\label{ugProblemIdeal}
+
+Axiom provides a facility for the primary decomposition
+\index{ideal!primary decomposition} of \index{primary decomposition of
+ideal} polynomial ideals over fields of characteristic zero.  The
+algorithm
+%is discussed in \cite{gtz:gbpdpi} and
+works in essentially two steps:
+\begin{enumerate}
+\item the problem is solved for 0-dimensional ideals by ``generic''
+projection on the last coordinate
+\item a ``reduction process'' uses localization and ideal quotients
+to reduce the general case to the 0-dimensional one.
+\end{enumerate}
+The Axiom constructor {\tt PolynomialIdeals} represents ideals with
+coefficients in any field and supports the basic ideal operations,
+including intersection, sum and quotient.  {\tt IdealDecompositionPackage} 
+contains the specific operations for the
+primary decomposition and the computation of the radical of an ideal
+with polynomial coefficients in a field of characteristic 0 with an
+effective algorithm for factoring polynomials.
+
+The following examples illustrate the capabilities of this facility.
+
+First consider the ideal generated by
+$x^2 + y^2 - 1$
+(which defines a circle in the $(x,y)$-plane) and the ideal
+generated by $x^2 - y^2$ (corresponding to the
+straight lines $x = y$ and $x = -y$.
+
+\spadcommand{(n,m) : List DMP([x,y],FRAC INT) }
+\returnType{Type: Void}
+
+\spadcommand{m := [x**2+y**2-1]  }
+$$
+\left[
+{{x \sp 2}+{y \sp 2} -1} 
+\right]
+$$
+\returnType{Type: List 
+DistributedMultivariatePolynomial([x,y],Fraction Integer)}
+
+\spadcommand{n := [x**2-y**2]  }
+$$
+\left[
+{{x \sp 2} -{y \sp 2}} 
+\right]
+$$
+\returnType{Type: List 
+DistributedMultivariatePolynomial([x,y],Fraction Integer)}
+
+We find the equations defining the intersection of the two loci.
+This correspond to the sum of the associated ideals.
+
+\spadcommand{id := ideal m  + ideal n  }
+$$
+\left[
+{{x \sp 2} -{1 \over 2}}, {{y \sp 2} -{1 \over 2}} 
+\right]
+$$
+\returnType{Type: PolynomialIdeals(Fraction Integer,
+DirectProduct(2,NonNegativeInteger),OrderedVariableList [x,y],
+DistributedMultivariatePolynomial([x,y],Fraction Integer))}
+
+We can check if the locus contains only a finite number of points,
+that is, if the ideal is zero-dimensional.
+
+\spadcommand{zeroDim? id }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{zeroDim?(ideal m) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{dimension ideal m }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+We can find polynomial relations among the generators ($f$ and $g$ are
+the parametric equations of the knot).
+
+\spadcommand{(f,g):DMP([x,y],FRAC INT) }
+\returnType{Type: Void}
+
+\spadcommand{f := x**2-1  }
+$$
+{x \sp 2} -1 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([x,y],Fraction Integer)}
+
+\spadcommand{g := x*(x**2-1)  }
+$$
+{x \sp 3} -x 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([x,y],Fraction Integer)}
+
+\spadcommand{relationsIdeal [f,g] }
+$$
+{\left[ {-{ \%B \sp 2}+{ \%A \sp 3}+{ \%A \sp 2}} \right]}
+\mid 
+{\left[ { \%A={{x \sp 2} -1}}, { \%B={{x \sp 3} -x}} \right]}
+$$
+\returnType{Type: SuchThat(List Polynomial Fraction Integer,
+List Equation Polynomial Fraction Integer)}
+
+We can compute the primary decomposition of an ideal.
+
+\spadcommand{l: List DMP([x,y,z],FRAC INT) }
+\returnType{Type: Void}
+
+\spadcommand{l:=[x**2+2*y**2,x*z**2-y*z,z**2-4]  }
+$$
+\left[
+{{x \sp 2}+{2 \  {y \sp 2}}}, {{x \  {z \sp 2}} -{y \  z}}, {{z \sp 2} -4} 
+\right]
+$$
+\returnType{Type: List 
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer)}
+
+\spadcommand{ld:=primaryDecomp ideal l  }
+$$
+\left[
+{\left[ {x+{{1 \over 2} \  y}}, {y \sp 2}, {z+2} \right]},
+{\left[ {x -{{1 \over 2} \  y}}, {y \sp 2}, {z -2} \right]}
+\right]
+$$
+\returnType{Type: List PolynomialIdeals(Fraction Integer,
+DirectProduct(3,NonNegativeInteger),
+OrderedVariableList [x,y,z],
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer))}
+
+We can intersect back.
+
+\spadcommand{reduce(intersect,ld) }
+$$
+\left[
+{x -{{1 \over 4} \  y \  z}}, {y \sp 2}, {{z \sp 2} -4} 
+\right]
+$$
+\returnType{Type: PolynomialIdeals(Fraction Integer,
+DirectProduct(3,NonNegativeInteger),
+OrderedVariableList [x,y,z],
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer))}
+
+We can compute the radical of every primary component.
+
+\spadcommand{reduce(intersect,[radical ld.i for i in 1..2]) }
+$$
+\left[
+x, y, {{z \sp 2} -4} 
+\right]
+$$
+\returnType{Type: PolynomialIdeals(Fraction Integer,
+DirectProduct(3,NonNegativeInteger),
+OrderedVariableList [x,y,z],
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer))}
+
+Their intersection is equal to the radical of the ideal of $l$.
+
+\spadcommand{radical ideal l }
+$$
+\left[x, y, {{z \sp 2} -4} \right]
+$$
+\returnType{Type: PolynomialIdeals(Fraction Integer,
+DirectProduct(3,NonNegativeInteger),
+OrderedVariableList [x,y,z],
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer))}
+
+\section{Computation of Galois Groups}
+\label{ugProblemGalois}
+
+As a sample use of Axiom's algebraic number facilities,
+\index{group!Galois}
+we compute
+\index{Galois!group}
+the Galois group of the polynomial
+$p(x) = x^5 - 5 x + 12$.
+
+\spadcommand{p := x**5 - 5*x + 12 }
+$$
+{x \sp 5} -{5 \  x}+{12} 
+$$
+\returnType{Type: Polynomial Integer}
+
+We would like to construct a polynomial $f(x)$ such that the splitting
+\index{field!splitting} field \index{splitting field} of $p(x)$ is
+generated by one root of $f(x)$.  First we construct a polynomial 
+$r = r(x)$ such that one root of $r(x)$ generates the field generated by
+two roots of the polynomial $p(x)$.  (As it will turn out, the field
+generated by two roots of $p(x)$ is, in fact, the splitting field of
+$p(x)$.)
+
+From the proof of the primitive element theorem we know that if $a$
+and $b$ are algebraic numbers, then the field ${\bf Q}(a,b)$ is equal
+to ${\bf Q}(a+kb)$ for an appropriately chosen integer $k$.  In our
+case, we construct the minimal polynomial of $a_i - a_j$, where $a_i$
+and $a_j$ are two roots of $p(x)$.  We construct this polynomial using
+{\bf resultant}.  The main result we need is the following: If $f(x)$
+is a polynomial with roots $a_i \ldots a_m$ and $g(x)$ is a polynomial
+with roots $b_i \ldots b_n$, then the polynomial $h(x) =
+resultant(f(y), g(x-y), y)$ is a polynomial of degree $m*n$ with roots
+$a_i + b_j, i = 1 \ldots m, j = 1 \ldots n$.
+
+For $f(x)$ we use the polynomial $p(x)$.  For $g(x)$ we use the
+polynomial $-p(-x)$.  Thus, the polynomial we first construct is
+$resultant(p(y), -p(y-x), y)$.
+
+\spadcommand{q := resultant(eval(p,x,y),-eval(p,x,y-x),y)  }
+$$
+\begin{array}{@{}l}
+{x \sp {25}} -
+{{50} \  {x \sp {21}}} -
+{{2375} \  {x \sp {17}}}+
+{{90000} \  {x \sp {15}}} -
+{{5000} \  {x \sp {13}}}+
+{{2700000} \  {x \sp {11}}}+
+{{250000} \  {x \sp 9}}+
+\\
+\\
+\displaystyle
+{{18000000} \  {x \sp 7}}+
+{{64000000} \  {x \sp 5}} 
+\end{array}
+$$
+\returnType{Type: Polynomial Integer}
+
+The roots of $q(x)$ are $a_i - a_j, i \leq 1, j \leq 5$.  Of course,
+there are five pairs $(i,j)$ with $i = j$, so $0$ is a 5-fold root of
+$q(x)$.
+
+Let's get rid of this factor.
+
+\spadcommand{q1 := exquo(q, x**5)  }
+$$
+\begin{array}{@{}l}
+{x \sp {20}} -
+{{50} \  {x \sp {16}}} -
+{{2375} \  {x \sp {12}}}+
+{{90000} \  {x \sp {10}}} -
+{{5000} \  {x \sp 8}}+
+{{2700000} \  {x \sp 6}}+
+\\
+\\
+\displaystyle
+{{250000} \  {x \sp 4}}+
+{{18000000} \  {x \sp 2}}+
+{64000000} 
+\end{array}
+$$
+\returnType{Type: Union(Polynomial Integer,...)}
+
+Factor the polynomial $q1$.
+
+\spadcommand{factoredQ := factor q1  }
+$$
+\begin{array}{@{}l}
+{\left( 
+{x \sp {10}} -
+{{10} \  {x \sp 8}} -
+{{75} \  {x \sp 6}}+
+{{1500} \  {x \sp 4}} -
+{{5500} \  {x \sp 2}}+
+{16000} 
+\right)} *
+\\
+\\
+\displaystyle
+{\left( 
+{x \sp {10}}+
+{{10} \  {x \sp 8}}+
+{{125} \  {x \sp 6}}+
+{{500} \  {x \sp 4}}+
+{{2500} \  {x \sp 2}}+
+{4000} 
+\right)}
+\end{array}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+We see that $q1$ has two irreducible factors, each of degree $10$.
+(The fact that the polynomial $q1$ has two factors of degree $10$ is
+enough to show that the Galois group of $p(x)$ is the dihedral group
+of order $10$.\footnote{See McKay, Soicher, Computing Galois Groups
+over the Rationals, Journal of Number Theory 20, 273-281 (1983).  We
+do not assume the results of this paper, however, and we continue with
+the computation.}  Note that the type of $factoredQ$ is {\tt FR POLY
+INT}, that is, {\tt Factored Polynomial Integer}.  \index{Factored}
+This is a special data type for recording factorizations of
+polynomials with integer coefficients.
+
+We can access the individual factors using the operation
+\spadfunFrom{nthFactor}{Factored}.
+
+\spadcommand{r := nthFactor(factoredQ,1)  }
+$$
+{x \sp {10}} -{{10} \  {x \sp 8}} -{{75} \  {x \sp 6}}+{{1500} \  {x \sp 4}} 
+-{{5500} \  {x \sp 2}}+{16000} 
+$$
+\returnType{Type: Polynomial Integer}
+
+Consider the polynomial $r = r(x)$.  This is the minimal polynomial of
+the difference of two roots of $p(x)$.  Thus, the splitting field of
+$p(x)$ contains a subfield of degree $10$.  We show that this subfield
+is, in fact, the splitting field of $p(x)$ by showing that $p(x)$
+factors completely over this field.
+
+First we create a symbolic root of the polynomial $r(x)$.  (We
+replaced $x$ by $b$ in the polynomial $r$ so that our symbolic root
+would be printed as $b$.)
+
+\spadcommand{beta:AN := rootOf(eval(r,x,b))  }
+$$
+b 
+$$
+\returnType{Type: AlgebraicNumber}
+
+We next tell Axiom to view $p(x)$ as a univariate polynomial in $x$
+with algebraic number coefficients.  This is accomplished with this
+type declaration.
+
+\spadcommand{p := p::UP(x,INT)::UP(x,AN)  }
+$$
+{x \sp 5} -{5 \  x}+{12} 
+$$
+\returnType{Type: UnivariatePolynomial(x,AlgebraicNumber)}
+
+Factor $p(x)$ over the field ${\bf Q}(\beta)$.
+(This computation will take some time!)
+
+\spadcommand{algFactors := factor(p,[beta])  }
+$$
+\begin{array}{@{}l}
+{\left( 
+x+
+{\left(
+\begin{array}{@{}l}
+-{{85} \  {b \sp 9}} -
+{{116} \  {b \sp 8}}+
+{{780} \  {b \sp 7}}+
+{{2640} \  {b \sp 6}}+
+{{14895} \  {b \sp 5}} -
+\\
+\\
+\displaystyle
+{{8820} \  {b \sp 4}} -
+{{127050} \  {b \sp 3}} -
+{{327000} \  {b \sp 2}} -
+{{405200} \  b}+
+{2062400}
+\end{array}
+\right)
+\over {1339200}}
+\right)}
+\\
+\\
+\displaystyle
+{\left( 
+x+
+{{-{{17} \  {b \sp 8}}+
+{{156} \  {b \sp 6}}+
+{{2979} \  {b \sp 4}} -
+{{25410} \  {b \sp 2}} -
+{14080}} \over {66960}} 
+\right)}
+\\
+\\
+\displaystyle
+\  {\left( 
+x+
+{{{{143} \  {b \sp 8}} -
+{{2100} \  {b \sp 6}} -
+{{10485} \  {b \sp 4}}+
+{{290550} \  {b \sp 2}} -
+{{334800} \  b} -
+{960800}} 
+\over {669600}} 
+\right)}
+\\
+\\
+\displaystyle
+\  {\left( 
+x+
+{{{{143} \  {b \sp 8}} -
+{{2100} \  {b \sp 6}} -
+{{10485} \  {b \sp 4}}+
+{{290550} \  {b \sp 2}}+
+{{334800} \  b} -
+{960800}} 
+\over {669600}} 
+\right)}
+\\
+\\
+\displaystyle
+{\left( 
+x+
+{\left(
+\begin{array}{@{}l}
+{{85} \  {b \sp 9}} -
+{{116} \  {b \sp 8}} -
+{{780} \  {b \sp 7}}+
+{{2640} \  {b \sp 6}} -
+{{14895} \  {b \sp 5}} -
+\\
+\\
+\displaystyle
+{{8820} \  {b \sp 4}}+
+{{127050} \  {b \sp 3}} -
+{{327000} \  {b \sp 2}}+
+{{405200} \  b}+
+{2062400}
+\end{array}
+\right)
+\over {1339200}}
+\right)}
+\end{array}
+$$
+\returnType{Type: Factored UnivariatePolynomial(x,AlgebraicNumber)}
+
+When factoring over number fields, it is important to specify the
+field over which the polynomial is to be factored, as polynomials have
+different factorizations over different fields.  When you use the
+operation {\bf factor}, the field over which the polynomial is
+factored is the field generated by
+\begin{enumerate}
+\item the algebraic numbers that appear
+in the coefficients of the polynomial, and
+\item the algebraic numbers that
+appear in a list passed as an optional second argument of the operation.
+\end{enumerate}
+In our case, the coefficients of $p$
+are all rational integers and only $beta$
+appears in the list, so the field is simply
+${\bf Q}(\beta)$.
+
+It was necessary to give the list $[beta]$ as a second argument of the
+operation because otherwise the polynomial would have been factored
+over the field generated by its coefficients, namely the rational
+numbers.
+
+\spadcommand{factor(p) }
+$$
+{x \sp 5} -{5 \  x}+{12} 
+$$
+\returnType{Type: Factored UnivariatePolynomial(x,AlgebraicNumber)}
+
+We have shown that the splitting field of $p(x)$ has degree $10$.
+Since the symmetric group of degree 5 has only one transitive subgroup
+of order $10$, we know that the Galois group of $p(x)$ must be this
+group, the dihedral group \index{group!dihedral} of order $10$.
+Rather than stop here, we explicitly compute the action of the Galois
+group on the roots of $p(x)$.
+
+First we assign the roots of $p(x)$ as the values of five \index{root}
+variables.
+
+We can obtain an individual root by negating the constant coefficient of
+one of the factors of $p(x)$.
+
+\spadcommand{factor1 := nthFactor(algFactors,1)  }
+$$
+x+
+{
+\left(
+\begin{array}{@{}l}
+-{{85} \  {b \sp 9}} -
+{{116} \  {b \sp 8}}+
+{{780} \  {b \sp 7}}+
+{{2640} \  {b \sp 6}}+
+{{14895} \  {b \sp 5}} -
+\\
+\\
+\displaystyle
+{{8820} \  {b \sp 4}} -
+{{127050} \  {b \sp 3}} -
+{{327000} \  {b \sp 2}} -
+{{405200} \  b}+
+{2062400}
+\end{array}
+\right)
+\over {1339200}} 
+$$
+\returnType{Type: UnivariatePolynomial(x,AlgebraicNumber)}
+
+\spadcommand{root1 := -coefficient(factor1,0)  }
+$$
+\left(
+\begin{array}{@{}l}
+{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}} -
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}} -
+{{14895} \  {b \sp 5}}+
+\\
+\\
+\displaystyle
+{{8820} \  {b \sp 4}}+
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}}+
+{{405200} \  b} -
+{2062400}
+\end{array}
+\right)
+\over {1339200} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+We can obtain a list of all the roots in this way.
+
+\spadcommand{roots := [-coefficient(nthFactor(algFactors,i),0) for i in 1..5]  }
+$$
+\begin{array}{@{}l}
+\left[
+\left(
+\begin{array}{@{}l}
+{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}} -
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}} -
+{{14895} \  {b \sp 5}}+
+{{8820} \  {b \sp 4}}+
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}}+
+{{405200} \  b} -
+{2062400}
+\end{array}
+\right)
+\over {1339200},
+\right.
+\\
+\\
+\displaystyle
+{{{{17} \  {b \sp 8}} -
+{{156} \  {b \sp 6}} -
+{{2979} \  {b \sp 4}}+
+{{25410} \  {b \sp 2}}+
+{14080}} 
+\over {66960}},
+\\
+\\
+\displaystyle
+{{-{{143} \  {b \sp 8}}+
+{{2100} \  {b \sp 6}}+
+{{10485} \  {b \sp 4}} -
+{{290550} \  {b \sp 2}}+
+{{334800} \  b}+
+{960800}} 
+\over {669600}}, 
+\\
+\\
+\displaystyle
+{{-{{143} \  {b \sp 8}}+
+{{2100} \  {b \sp 6}}+
+{{10485} \  {b \sp 4}} -
+{{290550} \  {b \sp 2}} -
+{{334800} \  b}+{960800}} 
+\over {669600}}, 
+\\
+\\
+\displaystyle
+\left.
+\left(
+\begin{array}{@{}l}
+-{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}}+
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}}+
+{{14895} \  {b \sp 5}}+
+{{8820} \  {b \sp 4}} -
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}}-
+{{405200} \  b} -
+{2062400}
+\end{array}
+\right)
+\over {1339200}
+\right]
+\end{array}
+$$
+\returnType{Type: List AlgebraicNumber}
+
+The expression
+\begin{verbatim}
+- coefficient(nthFactor(algFactors, i), 0)}
+\end{verbatim}
+is the $i $-th root of $p(x)$ and the elements of $roots$ are the 
+$i$-th roots of $p(x)$ as $i$ ranges from $1$ to $5$.
+
+Assign the roots as the values of the variables $a1,...,a5$.
+
+\spadcommand{(a1,a2,a3,a4,a5) := (roots.1,roots.2,roots.3,roots.4,roots.5)  }
+$$
+\left(
+\begin{array}{@{}l}
+-{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}}+
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}}+
+{{14895} \  {b \sp 5}}+
+{{8820} \  {b \sp 4}} -
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}}-
+{{405200} \  b} -
+{2062400}
+\end{array}
+\right)
+\over {1339200}
+$$
+\returnType{Type: AlgebraicNumber}
+
+Next we express the roots of $r(x)$ as polynomials in $beta$.  We
+could obtain these roots by calling the operation {\bf factor}:
+$factor(r, [beta])$ factors $r(x)$ over ${\bf Q}(\beta)$.  However,
+this is a lengthy computation and we can obtain the roots of $r(x)$ as
+differences of the roots $a1,...,a5$ of $p(x)$.  Only ten of these
+differences are roots of $r(x)$ and the other ten are roots of the
+other irreducible factor of $q1$.  We can determine if a given value
+is a root of $r(x)$ by evaluating $r(x)$ at that particular value.
+(Of course, the order in which factors are returned by the operation
+{\bf factor} is unimportant and may change with different
+implementations of the operation.  Therefore, we cannot predict in
+advance which differences are roots of $r(x)$ and which are not.)
+
+Let's look at four examples (two are roots of $r(x)$ and
+two are not).
+
+\spadcommand{eval(r,x,a1 - a2) }
+$$
+0 
+$$
+\returnType{Type: Polynomial AlgebraicNumber}
+
+\spadcommand{eval(r,x,a1 - a3) }
+$$
+\left(
+\begin{array}{@{}l}
+{{47905} \  {b \sp 9}}+
+{{66920} \  {b \sp 8}} -
+{{536100} \  {b \sp 7}} -
+{{980400} \  {b \sp 6}} -
+{{3345075} \  {b \sp 5}} -
+{{5787000} \  {b \sp 4}}+
+\\
+\\
+\displaystyle
+{{75572250} \  {b \sp 3}}+
+{{161688000} \  {b \sp 2}} -
+{{184600000} \  b} -
+{710912000}
+\end{array}
+\right)
+\over {4464} 
+$$
+\returnType{Type: Polynomial AlgebraicNumber}
+
+\spadcommand{eval(r,x,a1 - a4) }
+$$
+0 
+$$
+\returnType{Type: Polynomial AlgebraicNumber}
+
+\spadcommand{eval(r,x,a1 - a5) }
+$$
+{{{405} \  {b \sp 8}}+
+{{3450} \  {b \sp 6}} -
+{{19875} \  {b \sp 4}} -
+{{198000} \  {b \sp 2}} -
+{588000}} 
+\over {31} 
+$$
+\returnType{Type: Polynomial AlgebraicNumber}
+
+Take one of the differences that was a root of $r(x)$ and assign it to
+the variable $bb$.
+
+For example, if $eval(r,x,a1 - a4)$ returned $0$, you would enter this.
+
+\spadcommand{bb := a1 - a4  }
+$$
+\left(
+\begin{array}{@{}l}
+{{85} \  {b \sp 9}}+
+{{402} \  {b \sp 8}} -
+{{780} \  {b \sp 7}} -
+{{6840} \  {b \sp 6}} -
+{{14895} \  {b \sp 5}} -
+{{12150} \  {b \sp 4}}+
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{908100} \  {b \sp 2}}+
+{{1074800} \  b} -
+{3984000}
+\end{array}
+\right)
+\over {1339200} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+Of course, if the difference is, in fact, equal to the root $beta$,
+you should choose another root of $r(x)$.
+
+Automorphisms of the splitting field are given by mapping a generator
+of the field, namely $beta$, to other roots of its minimal polynomial.
+Let's see what happens when $beta$ is mapped to $bb$.
+
+We compute the images of the roots $a1,...,a5$ under this automorphism:
+
+\spadcommand{aa1 := subst(a1,beta = bb)  }
+$$
+{-{{143} \  {b \sp 8}}+
+{{2100} \  {b \sp 6}}+
+{{10485} \  {b \sp 4}}-
+{{290550} \  {b \sp 2}}+
+{{334800} \  b}+
+{960800}} 
+\over {669600} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{aa2 := subst(a2,beta = bb)  }
+$$
+\left(
+\begin{array}{@{}l}
+-{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}}+
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}}+
+{{14895} \  {b \sp 5}}+
+{{8820} \  {b \sp 4}} -
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}} -
+{{405200} \  b} -
+{2062400}
+\end{array}
+\right)
+\over {1339200} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{aa3 := subst(a3,beta = bb)  }
+$$
+\left(
+\begin{array}{@{}l}
+{{85} \  {b \sp 9}}+
+{{116} \  {b \sp 8}} -
+{{780} \  {b \sp 7}} -
+{{2640} \  {b \sp 6}} -
+{{14895} \  {b \sp 5}}+
+{{8820} \  {b \sp 4}}+
+\\
+\\
+\displaystyle
+{{127050} \  {b \sp 3}}+
+{{327000} \  {b \sp 2}}+
+{{405200} \  b} -
+{2062400} 
+\end{array}
+\right)
+\over {1339200} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{aa4 := subst(a4,beta = bb)  }
+$$
+{-{{143} \  {b \sp 8}}+
+{{2100} \  {b \sp 6}}+
+{{10485} \  {b \sp 4}}-
+{{290550} \  {b \sp 2}} -
+{{334800} \  b}+
+{960800}} 
+\over {669600} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{aa5 := subst(a5,beta = bb)  }
+$$
+{{{17} \  {b \sp 8}} -
+{{156} \  {b \sp 6}} -
+{{2979} \  {b \sp 4}}+
+{{25410} \  {b \sp 2}}+
+{14080}} 
+\over {66960} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+Of course, the values $aa1,...,aa5$ are simply a permutation of the values
+$a1,...,a5$.
+
+Let's find the value of $aa1$ (execute as many of the following five commands
+as necessary).
+
+\spadcommand{(aa1 = a1) :: Boolean }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{(aa1 = a2) :: Boolean }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{(aa1 = a3) :: Boolean }
+$$
+{\tt true}
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{(aa1 = a4) :: Boolean }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{(aa1 = a5) :: Boolean }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Proceeding in this fashion, you can find the values of
+$aa2,...aa5$. You have represented the automorphism $beta -> bb$ as a
+permutation of the roots $a1,...,a5$.  If you wish, you can repeat
+this computation for all the roots of $r(x)$ and represent the Galois
+group of $p(x)$ as a subgroup of the symmetric group on five letters.
+
+Here are two other problems that you may attack in a similar fashion:
+\begin{enumerate}
+\item Show that the Galois group of
+$p(x) = x^4 + 2 x^3 - 2 x^2 - 3 x + 1$
+is the dihedral group of order eight. \index{group!dihedral}
+(The splitting field of this polynomial is the Hilbert class field
+\index{Hilbert class field} of \index{field!Hilbert class} the quadratic field
+${\bf Q}(\sqrt{145})$.)
+\item Show that the Galois group of
+$p(x) = x^6 + 108$
+has order 6 and is isomorphic to $S_3,$ the symmetric group on three letters.
+\index{group!symmetric} (The splitting field of this polynomial is the 
+splitting field of $x^3 - 2$.)
+\end{enumerate}
+
+\section{Non-Associative Algebras and Modelling Genetic Laws}
+\label{ugProblemGenetic}
+
+Many algebraic structures of mathematics and Axiom have a
+multiplication operation {\tt *} that satisfies the associativity law
+\index{associativity law} $a*(b*c) = (a*b)*c$ for all $a$, $b$ and
+$c$.  The octonions are a well known exception.  There are many other
+interesting non-associative structures, such as the class of
+\index{Lie algebra} Lie algebras.\footnote{Two Axiom implementations
+of Lie algebras are {\tt LieSquareMatrix} and {\tt FreeNilpotentLie}.}
+Lie algebras can be used, for example, to analyse Lie symmetry
+algebras of \index{symmetry} partial differential \index{differential
+equation!partial} equations.  \index{partial differential equation} In
+this section we show a different application of non-associative
+algebras, \index{non-associative algebra} the modelling of genetic
+laws.  \index{algebra!non-associative}
+
+The Axiom library contains several constructors for creating
+non-assoc\-i\-a\-tive structures, ranging from the categories 
+{\tt Monad}, {\tt NonAssociativeRng}, and {\tt FramedNonAssociativeAlgebra}, 
+to the domains {\tt AlgebraGivenByStructuralConstants} and 
+{\tt GenericNonAssociativeAlgebra}.  Furthermore, the package 
+{\tt AlgebraPackage} provides operations for analysing the structure of
+such algebras.\footnote{% The interested reader can learn more about
+these aspects of the Axiom library from the paper ``Computations in
+Algebras of Finite Rank,'' by Johannes Grabmeier and Robert Wisbauer,
+Technical Report, IBM Heidelberg Scientific Center, 1992.}
+
+Mendel's genetic laws are often written in a form like
+
+$$Aa \times Aa = {1\over 4}AA + {1\over 2}Aa + {1\over 4}aa$$
+
+The implementation of general algebras in Axiom allows us to
+\index{Mendel's genetic laws} use this as the definition for
+multiplication in an algebra.  \index{genetics} Hence, it is possible
+to study questions of genetic inheritance using Axiom.  To demonstrate
+this more precisely, we discuss one example from a monograph of
+A. W\"orz-Busekros, where you can also find a general setting of this
+theory.\footnote{% W\"{o}rz-Busekros, A., {\it Algebras in Genetics},
+Springer Lectures Notes in Biomathematics 36, Berlin e.a. (1980).  In
+particular, see example 1.3.}
+
+We assume that there is an infinitely large random mating population.
+Random mating of two gametes $a_i$ and $a_j$ gives zygotes
+\index{zygote} $a_ia_j$, which produce new gametes.  \index{gamete} In
+classical Mendelian segregation we have $a_ia_j = {1 \over 2}a_i+{1
+\over 2}a_j$.  In general, we have
+
+$$a_ia_j = \sum_{k=1}^n \gamma_{i,j}^k\ a_k.$$
+
+%{$ai aj = gammaij1 a1 + gammaij2 a2 + ... + gammaijn an$}
+
+The segregation rates $\gamma_{i,j}$ are the structural constants of
+an $n$-dimensional algebra.  This is provided in Axiom by the
+constructor {\tt AlgebraGivenByStructuralConstants} (abbreviation 
+{\tt ALGSC}).
+
+Consider two coupled autosomal loci with alleles $A$, $a$, $B$, and
+$b$, building four different gametes $a_1 = AB, a_2 = Ab, a_3 = aB,$
+and $a_4 = ab$ {$a1 := AB, a2 := Ab, a3 := aB,$ and $a4 := ab$}.  The
+zygotes $a_ia_j$ produce gametes $a_i$ and $a_j$ with classical
+Mendelian segregation.  Zygote $a_1a_4$ undergoes transition to
+$a_2a_3$ and vice versa with probability 
+$0 \le \theta \le {1\over2}$.
+
+Define a list $[(\gamma_{i,j}^k) 1 \le k \le 4]$ of four four-by-four
+matrices giving the segregation rates.  We use the value $1/10$ for
+$\theta$.
+
+\spadcommand{segregationRates : List SquareMatrix(4,FRAC INT) := [matrix [ [1, 1/2, 1/2, 9/20], [1/2, 0, 1/20, 0], [1/2, 1/20, 0, 0], [9/20, 0, 0, 0] ], matrix [ [0, 1/2, 0, 1/20], [1/2, 1, 9/20, 1/2], [0, 9/20, 0, 0], [1/20, 1/2, 0, 0] ], matrix [ [0, 0, 1/2, 1/20], [0, 0, 9/20, 0], [1/2, 9/20, 1, 1/2], [1/20, 0, 1/2, 0] ], matrix [ [0, 0, 0, 9/20], [0, 0, 1/20, 1/2], [0, 1/20, 0, 1/2], [9/20, 1/2, 1/2, 1] ] ] }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ 
+\begin{array}{cccc}
+1 & {1 \over 2} & {1 \over 2} & {9 \over {20}} \\ 
+{1 \over 2} & 0 & {1 \over {20}} & 0 \\ 
+{1 \over 2} & {1 \over {20}} & 0 & 0 \\ 
+{9 \over {20}} & 0 & 0 & 0 
+\end{array}
+\right]},
+{\left[ 
+\begin{array}{cccc}
+0 & {1 \over 2} & 0 & {1 \over {20}} \\ 
+{1 \over 2} & 1 & {9 \over {20}} & {1 \over 2} \\ 
+0 & {9 \over {20}} & 0 & 0 \\ 
+{1 \over {20}} & {1 \over 2} & 0 & 0 
+\end{array}
+\right]},
+\right.
+\\
+\\
+\displaystyle
+\left.
+{\left[ 
+\begin{array}{cccc}
+0 & 0 & {1 \over 2} & {1 \over {20}} \\ 
+0 & 0 & {9 \over {20}} & 0 \\ 
+{1 \over 2} & {9 \over {20}} & 1 & {1 \over 2} \\ 
+{1 \over {20}} & 0 & {1 \over 2} & 0 
+\end{array}
+\right]},
+{\left[ 
+\begin{array}{cccc}
+0 & 0 & 0 & {9 \over {20}} \\ 
+0 & 0 & {1 \over {20}} & {1 \over 2} \\ 
+0 & {1 \over {20}} & 0 & {1 \over 2} \\ 
+{9 \over {20}} & {1 \over 2} & {1 \over 2} & 1 
+\end{array}
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List SquareMatrix(4,Fraction Integer)}
+
+Choose the appropriate symbols for the basis of gametes,
+
+\spadcommand{gametes := ['AB,'Ab,'aB,'ab]  }
+$$
+\left[
+AB, Ab, aB, ab 
+\right]
+$$
+\returnType{Type: List OrderedVariableList [AB,Ab,aB,ab]}
+
+Define the algebra.
+
+\spadcommand{A := ALGSC(FRAC INT, 4, gametes, segregationRates)}
+$$
+\begin{array}{@{}l}
+{\rm AlgebraGivenByStructuralConstants(Fraction Integer, 4, }
+\\
+\displaystyle
+{\rm [AB,Ab,aB,ab], [MATRIX,MATRIX,MATRIX,MATRIX])}
+\end{array}
+$$
+\returnType{Type: Domain}
+
+What are the probabilities for zygote $a_1a_4$ to produce the
+different gametes?
+
+\spadcommand{a := basis()\$A}
+$$
+\left[
+AB, Ab, aB, ab 
+\right]
+$$
+\returnType{Type: Vector 
+AlgebraGivenByStructuralConstants(Fraction Integer,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+\spadcommand{a.1*a.4}
+$$
+{{9 \over {20}} \  ab}+
+{{1 \over {20}} \  aB}+
+{{1 \over {20}} \  Ab}+
+{{9 \over {20}} \  AB} 
+$$
+\returnType{Type: 
+AlgebraGivenByStructuralConstants(Fraction Integer,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+Elements in this algebra whose coefficients sum to one play a
+distinguished role.  They represent a population with the distribution
+of gametes reflected by the coefficients with respect to the basis of
+gametes.
+
+Random mating of different populations $x$ and $y$ is described by
+their product $x*y$.
+
+This product is commutative only if the gametes are not sex-dependent,
+as in our example.
+
+\spadcommand{commutative?()\$A }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+In general, it is not associative.
+
+\spadcommand{associative?()\$A }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Random mating within a population $x$ is described by $x*x$.  The next
+generation is $(x*x)*(x*x)$.
+
+Use decimal numbers to compare the distributions more easily.
+
+\spadcommand{x : ALGSC(DECIMAL, 4, gametes, segregationRates) :=  convert [3/10, 1/5, 1/10, 2/5]}
+$$
+{{0.4} \  ab}+{{0.1} \  aB}+{{0.2} \  Ab}+{{0.3} \  AB} 
+$$
+\returnType{Type: 
+AlgebraGivenByStructuralConstants(DecimalExpansion,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+To compute directly the gametic distribution in the fifth generation,
+we use {\bf plenaryPower}.
+
+\spadcommand{plenaryPower(x,5) }
+$$
+{{0.{36561}} \  ab}+{{0.{13439}} \  aB}+{{0.{23439}} \  Ab}+{{0.{26561}} \  
+AB} 
+$$
+\returnType{Type: 
+AlgebraGivenByStructuralConstants(DecimalExpansion,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+We now ask two questions: Does this distribution converge to an
+equilibrium state?  What are the distributions that are stable?
+
+This is an invariant of the algebra and it is used to answer the first
+question.  The new indeterminates describe a symbolic distribution.
+
+\spadcommand{q := leftRankPolynomial()\$GCNAALG(FRAC INT, 4, gametes, segregationRates) :: UP(Y, POLY FRAC INT)}
+$$
+\begin{array}{@{}l}
+{Y \sp 3}+
+{{\left( 
+-{{{29} \over {20}} \  \%x4} -
+{{{29} \over {20}} \  \%x3} -
+{{{29} \over {20}} \  \%x2} -
+{{{29} \over {20}} \  \%x1} 
+\right)}\  {Y \sp 2}}+
+\\
+\\
+\displaystyle
+{
+\left(
+\begin{array}{@{}l}
+\left( {{9 \over {20}} \  { \%x4 \sp 2}}+
+{{\left( 
+{{9 \over {10}} \  \%x3}+
+{{9 \over {10}} \  \%x2}+
+{{9 \over {10}} \  \%x1} 
+\right)}\  \%x4}+
+\right.
+\\
+\\
+\displaystyle
+{{9 \over {20}} \  { \%x3 \sp 2}}+
+{{\left( {{9 \over {10}} \   \%x2}+{{9 \over {10}} \  \%x1} \right)}\  \%x3}+
+{{9 \over {20}} \  { \%x2 \sp 2}}+
+\\
+\\
+\displaystyle
+\left.
+{{9 \over {10}} \  \%x1 \   \%x2}+
+{{9 \over {20}} \  { \%x1 \sp 2}} 
+\right)
+\end{array}
+\right)
+\  Y} 
+\end{array}
+$$
+\returnType{Type: UnivariatePolynomial(Y,Polynomial Fraction Integer)}
+
+
+Because the coefficient ${9 \over 20}$ has absolute value less than 1,
+all distributions do converge, by a theorem of this theory.
+
+\spadcommand{factor(q :: POLY FRAC INT) }
+$$
+\begin{array}{@{}l}
+{\left( Y - \%x4 - \%x3 - \%x2 - \%x1 \right)} *
+\\
+\\
+\displaystyle
+{\left( 
+Y -
+{{9 \over {20}} \  \%x4} -
+{{9 \over {20}} \  \%x3} -
+{{9 \over {20}} \  \%x2} -
+{{9 \over {20}} \  \%x1} 
+\right)}
+\  Y 
+\end{array}
+$$
+\returnType{Type: Factored Polynomial Fraction Integer}
+
+The second question is answered by searching for idempotents in the algebra.
+
+\spadcommand{cI := conditionsForIdempotents()\$GCNAALG(FRAC INT, 4, gametes, segregationRates) }
+$$
+\begin{array}{@{}l}
+\left[
+{{{9 \over {10}} \  \%x1 \  \%x4}+
+{{\left( {{1 \over {10}} \  \%x2}+ \%x1 \right)}\  \%x3}+
+{ \%x1 \  \%x2}+
+{ \%x1 \sp 2} -
+\%x1},
+\right.
+\\
+\\
+\displaystyle
+{{{\left( \%x2+{{1 \over {10}} \  \%x1} \right)}\  \%x4}+
+{{9 \over {10}} \  \%x2 \  \%x3}+
+{ \%x2 \sp 2}+
+{{\left( \%x1 -1 \right)}\  \%x2}},
+\\
+\\
+\displaystyle
+{{{\left( \%x3+{{1 \over {10}} \  \%x1} \right)}\  \%x4}+
+{ \%x3 \sp 2}+
+{{\left( {{9 \over {10}} \  \%x2}+ \%x1 -1 \right)}\  \%x3}},
+\\
+\\
+\displaystyle
+\left.
+{{ \%x4 \sp 2}+
+{{\left( \%x3+ \%x2+{{9 \over {10}} \  \%x1} -1 \right)}\  \%x4}+
+{{1 \over {10}} \  \%x2 \  \%x3}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List Polynomial Fraction Integer}
+
+Solve these equations and look at the first solution.
+
+\spadcommand{gbs:= groebnerFactorize cI}
+$$
+\begin{array}{@{}l}
+\left[
+\begin{array}{@{}l}
+\left[ { \%x4+ \%x3+ \%x2+ \%x1 -1}, 
+\right.
+\\
+\displaystyle
+\left.
+\ \ {{{\left( \%x2+ \%x1 \right)}\  \%x3}+
+{ \%x1 \  \%x2}+{ \%x1 \sp 2} - \%x1} 
+\right],
+\end{array}
+\right.
+\\
+\\
+\displaystyle
+{\left[ 1 \right]},
+{\left[ { \%x4+ \%x3 -1}, \%x2, \%x1 \right]},
+\\
+\\
+\displaystyle
+{\left[ { \%x4+ \%x2 -1}, \%x3, \%x1 \right]},
+{\left[ \%x4, \%x3, \%x2, \%x1 \right]},
+\\
+\\
+\displaystyle
+\left.
+{\left[ { \%x4 -1}, \%x3, \%x2, \%x1 \right]},
+{\left[ { \%x4 -{1 \over 2}}, { \%x3 -{1 \over 2}}, \%x2, \%x1 \right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List List Polynomial Fraction Integer}
+
+\spadcommand{gbs.1}
+$$
+\begin{array}{@{}l}
+\left[
+{ \%x4+ \%x3+ \%x2+ \%x1 -1}, 
+\right.
+\\
+\displaystyle
+\left.
+{{{\left( \%x2+ \%x1 \right)}\  \%x3}+{ \%x1 \  \%x2}+{ \%x1 \sp 2} - \%x1} 
+\right]
+\end{array}
+$$
+\returnType{Type: List Polynomial Fraction Integer}
+
+
+Further analysis using the package {\tt PolynomialIdeals} shows that
+there is a two-dimensional variety of equilibrium states and all other
+solutions are contained in it.
+
+Choose one equilibrium state by setting two indeterminates to concrete
+values.
+
+\spadcommand{sol := solve concat(gbs.1,[\%x1-1/10,\%x2-1/10]) }
+$$
+\left[
+{\left[ 
+{ \%x4={2 \over 5}}, 
+{ \%x3={2 \over 5}}, 
+{ \%x2={1 \over {10}}}, 
+{ \%x1={1 \over {10}}} 
+\right]}
+\right]
+$$
+\returnType{Type: List List Equation Fraction Polynomial Integer}
+
+\spadcommand{e : A := represents reverse (map(rhs, sol.1) :: List FRAC INT) }
+$$
+{{2 \over 5} \  ab}+
+{{2 \over 5} \  aB}+
+{{1 \over {10}} \  Ab}+
+{{1 \over {10}} \  AB} 
+$$
+\returnType{Type: 
+AlgebraGivenByStructuralConstants(Fraction Integer,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+Verify the result.
+
+\spadcommand{e*e-e }
+$$
+0 
+$$
+\returnType{Type: 
+AlgebraGivenByStructuralConstants(Fraction Integer,4,[AB,Ab,aB,ab],
+[MATRIX,MATRIX,MATRIX,MATRIX])}
+
+
+%\setcounter{chapter}{9} % Chapter 10
+\chapter{Some Examples of Domains and Packages}
+In this chapter we show examples of many of the most commonly used
+AXIOM domains and packages. The sections are organized by constructor
+names.
+
+\section{AssociationList}
+\label{AssociationListXmpPage}
+
+The {\tt AssociationList} constructor provides a general structure for
+associative storage.  This type provides association lists in which
+data objects can be saved according to keys of any type.  For a given
+association list, specific types must be chosen for the keys and
+entries.  You can think of the representation of an association list
+as a list of records with key and entry fields.
+
+Association lists are a form of table and so most of the operations
+available for {\tt Table} are also available for {\tt AssociationList}.  
+They can also be viewed as lists and can be manipulated accordingly.
+
+This is a {\tt Record} type with age and gender fields.
+
+\spadcommand{Data := Record(monthsOld : Integer, gender : String)}
+$$
+\mbox{\rm Record(monthsOld: Integer,gender: String)} 
+$$
+\returnType{Type: Domain}
+
+In this expression, {\tt al} is declared to be an association
+list whose keys are strings and whose entries are the above records.
+
+\spadcommand{al : AssociationList(String,Data)}
+\returnType{Type: Void}
+
+The \spadfunFrom{table}{AssociationList} operation is used to create
+an empty association list.
+
+\spadcommand{al := table()}
+$$
+table() 
+$$
+\returnType{Type: 
+AssociationList(String,Record(monthsOld: Integer,gender: String))}
+
+You can use assignment syntax to add things to the association list.
+
+\spadcommand{al."bob" := [407,"male"]\$Data}
+$$
+\left[
+{monthsOld={407}}, {gender= \mbox{\tt "male"} } 
+\right]
+$$
+\returnType{Type: Record(monthsOld: Integer,gender: String)}
+
+\spadcommand{al."judith" := [366,"female"]\$Data}
+$$
+\left[
+{monthsOld={366}}, {gender= \mbox{\tt "female"} } 
+\right]
+$$
+\returnType{Type: Record(monthsOld: Integer,gender: String)}
+
+\spadcommand{al."katie" := [24,"female"]\$Data}
+$$
+\left[
+{monthsOld={24}}, {gender= \mbox{\tt "female"} } 
+\right]
+$$
+\returnType{Type: Record(monthsOld: Integer,gender: String)}
+
+Perhaps we should have included a species field.
+
+\spadcommand{al."smokie" := [200,"female"]\$Data}
+$$
+\left[
+{monthsOld={200}}, {gender= \mbox{\tt "female"} } 
+\right]
+$$
+\returnType{Type: Record(monthsOld: Integer,gender: String)}
+
+Now look at what is in the association list.  Note that the last-added
+(key, entry) pair is at the beginning of the list.
+
+\spadcommand{al}
+$$
+\begin{array}{@{}l}
+table 
+\left(
+{ \mbox{\tt "smokie"} =
+{\left[ {monthsOld={200}}, {gender= \mbox{\tt "female"} } \right]}},
+\right.
+\\
+\\
+\displaystyle
+\ \ \ \ \ \ \ \ { \mbox{\tt "katie"} =
+{\left[ {monthsOld={24}}, {gender= \mbox{\tt "female"} } \right]}},
+\\
+\\
+\displaystyle
+\ \ \ \ \ \ \ \ { \mbox{\tt "judith"} =
+{\left[ {monthsOld={366}}, {gender= \mbox{\tt "female"} } \right]}},
+\\
+\\
+\displaystyle
+\left.
+\ \ \ \ \ \ \ \ { \mbox{\tt "bob"} =
+{\left[ {monthsOld={407}}, {gender= \mbox{\tt "male"} } \right]}}
+\right)
+\end{array}
+$$
+\returnType{Type: 
+AssociationList(String,Record(monthsOld: Integer,gender: String))}
+
+You can reset the entry for an existing key.
+
+\spadcommand{al."katie" := [23,"female"]\$Data}
+$$
+\left[
+{monthsOld={23}}, {gender= \mbox{\tt "female"} } 
+\right]
+$$
+\returnType{Type: Record(monthsOld: Integer,gender: String)}
+
+Use \spadfunFrom{delete!}{AssociationList} to destructively remove an
+element of the association list.  Use
+\spadfunFrom{delete}{AssociationList} to return a copy of the
+association list with the element deleted.  The second argument is the
+index of the element to delete.
+
+\spadcommand{delete!(al,1)}
+$$
+\begin{array}{@{}l}
+table 
+\left(
+{ \mbox{\tt "katie"} =
+{\left[ {monthsOld={23}}, {gender= \mbox{\tt "female"} } \right]}},
+\right.
+\\
+\\
+\displaystyle
+\ \ \ \ \ \ \ \ { \mbox{\tt "judith"} =
+{\left[ {monthsOld={366}}, {gender= \mbox{\tt "female"} } \right]}},
+\\
+\\
+\displaystyle
+\left.
+\ \ \ \ \ \ \ \ { \mbox{\tt "bob"} =
+{\left[ {monthsOld={407}}, {gender= \mbox{\tt "male"} } \right]}}
+\right)
+\end{array}
+$$
+\returnType{Type: 
+AssociationList(String,Record(monthsOld: Integer,gender: String))}
+
+For more information about tables, 
+see \ref{TableXmpPage} on page~\pageref{TableXmpPage}.
+For more information about lists, 
+see \ref{ListXmpPage} on page~\pageref{ListXmpPage}.
+
+\section{BalancedBinaryTree}
+\label{BalancedBinaryTreeXmpPage}
+
+{\tt BalancedBinaryTrees(S)} is the domain of balanced binary trees
+with elements of type {\tt S} at the nodes.  A binary tree is either
+{\tt empty} or else consists of a {\tt node} having a {\tt value} and
+two branches, each branch a binary tree.  A balanced binary tree is
+one that is balanced with respect its leaves.  One with $2^k$ leaves
+is perfectly ``balanced'': the tree has minimum depth, and the {\tt
+left} and {\tt right} branch of every interior node is identical in
+shape.
+
+Balanced binary trees are useful in algebraic computation for
+so-called ``divide-and-conquer'' algorithms.  Conceptually, the data
+for a problem is initially placed at the root of the tree.  The
+original data is then split into two subproblems, one for each
+subtree.  And so on.  Eventually, the problem is solved at the leaves
+of the tree.  A solution to the original problem is obtained by some
+mechanism that can reassemble the pieces.  In fact, an implementation
+of the Chinese Remainder Algorithm using balanced binary trees was
+first proposed by David Y. Y.  Yun at the IBM T. J.  Watson Research
+Center in Yorktown Heights, New York, in 1978.  It served as the
+prototype for polymorphic algorithms in Axiom.
+
+In what follows, rather than perform a series of computations with a
+single expression, the expression is reduced modulo a number of
+integer primes, a computation is done with modular arithmetic for each
+prime, and the Chinese Remainder Algorithm is used to obtain the
+answer to the original problem.  We illustrate this principle with the
+computation of $12^2 = 144$.
+
+A list of moduli.
+
+\spadcommand{lm := [3,5,7,11]}
+$$
+\left[
+3, 5, 7,  {11} 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The expression {\tt modTree(n, lm)} creates a balanced binary tree
+with leaf values {\tt n mod m} for each modulus {\tt m} in {\tt lm}.
+
+\spadcommand{modTree(12,lm)}
+$$
+\left[
+0, 2, 5, 1 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Operation {\tt modTree} does this using operations on balanced binary
+trees.  We trace its steps.  Create a balanced binary tree {\tt t} of
+zeros with four leaves.
+
+\spadcommand{t := balancedBinaryTree(\#lm, 0)}
+$$
+\left[
+{\left[ 0, 0, 0 \right]}, 0, {\left[ 0, 0, 0\right]}
+\right]
+$$
+\returnType{Type: BalancedBinaryTree NonNegativeInteger}
+
+The leaves of the tree are set to the individual moduli.
+
+\spadcommand{setleaves!(t,lm)}
+$$
+\left[
+{\left[ 3, 0, 5\right]}, 0, {\left[ 7, 0, {11} \right]}
+\right]
+$$
+\returnType{Type: BalancedBinaryTree NonNegativeInteger}
+
+Use {\tt mapUp!} to do a bottom-up traversal of {\tt t}, setting each
+interior node to the product of the values at the nodes of its
+children.
+
+\spadcommand{mapUp!(t,\_*)}
+$$
+1155 
+$$
+\returnType{Type: PositiveInteger}
+
+The value at the node of every subtree is the product of the moduli
+of the leaves of the subtree.
+
+\spadcommand{t}
+$$
+\left[
+{\left[ 3, {15}, 5\right]}, {1155}, {\left[ 7, {77}, {11} \right]}
+\right]
+$$
+\returnType{Type: BalancedBinaryTree NonNegativeInteger}
+
+Operation {\tt mapDown!}{\tt (t,a,fn)} replaces the value {\tt v} at
+each node of {\tt t} by {\tt fn(a,v)}.
+
+\spadcommand{mapDown!(t,12,\_rem)}
+$$
+\left[
+{\left[ 0, {12}, 2\right]}, {12}, {\left[ 5, {12}, 1 \right]}
+\right]
+$$
+\returnType{Type: BalancedBinaryTree NonNegativeInteger}
+
+The operation {\tt leaves} returns the leaves of the resulting tree.
+In this case, it returns the list of {\tt 12 mod m} for each modulus
+{\tt m}.
+
+\spadcommand{leaves \%}
+$$
+\left[
+0, 2, 5, 1 
+\right]
+$$
+\returnType{Type: List NonNegativeInteger}
+
+Compute the square of the images of {\tt 12} modulo each {\tt m}.
+
+\spadcommand{squares := [x**2 rem m for x in \% for m in lm]}
+$$
+\left[
+0, 4, 4, 1 
+\right]
+$$
+\returnType{Type: List NonNegativeInteger}
+
+Call the Chinese Remainder Algorithm to get the answer for $12^2$.
+
+\spadcommand{chineseRemainder(\%,lm)}
+$$
+144 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{BasicOperator}
+\label{BasicOperatorXmpPage}
+
+A basic operator is an object that can be symbolically applied to a
+list of arguments from a set, the result being a kernel over that set
+or an expression.  In addition to this section, please see
+\ref{ExpressionXmpPage} on page~\pageref{ExpressionXmpPage} and 
+\ref{KernelXmpPage} on page~\pageref{KernelXmpPage} for additional
+information and examples.
+
+You create an object of type {\tt BasicOperator} by using the
+\spadfunFrom{operator}{BasicOperator} operation.  This first form of
+this operation has one argument and it must be a symbol.  The symbol
+should be quoted in case the name has been used as an identifier to
+which a value has been assigned.
+
+A frequent application of {\tt BasicOperator} is the creation of an
+operator to represent the unknown function when solving a differential
+equation.
+
+Let {\tt y} be the unknown function in terms of {\tt x}.
+
+\spadcommand{y := operator 'y}
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+This is how you enter the equation {\tt y'' + y' + y = 0}.
+
+\spadcommand{deq := D(y x, x, 2) + D(y x, x) + y x = 0}
+$$
+{{{y \sb {{\ }} \sp {,,}} \left({x} \right)}+
+{{y\sb {{\ }} \sp {,}} \left({x} \right)}+
+{y\left({x} \right)}}=0
+$$
+\returnType{Type: Equation Expression Integer}
+
+To solve the above equation, enter this.
+
+\spadcommand{solve(deq, y, x)}
+$$
+\left[
+{particular=0}, 
+{basis={\left[ {{\cos \left({{{x \  {\sqrt {3}}} \over 2}} \right)}
+\  {e \sp {\left( -{x \over 2} \right)}}},
+{{e \sp {\left( -{x \over 2} \right)}}
+\  {\sin \left({{{x \  {\sqrt {3}}} \over 2}} \right)}}
+\right]}}
+\right]
+$$
+\returnType{Type: Union(Record(particular: Expression Integer,
+basis: List Expression Integer),...)}
+
+See \ref{ugProblemDEQPage} on page~\pageref{ugProblemDEQPage} 
+in Section \ref{ugProblemDEQNumber} on page~\pageref{ugProblemDEQNumber}
+for this kind of use of {\tt BasicOperator}.
+
+Use the single argument form of \spadfunFrom{operator}{BasicOperator}
+(as above) when you intend to use the operator to create functional
+expressions with an arbitrary number of arguments
+
+{\it Nary} means an arbitrary number of arguments can be used
+in the functional expressions.
+
+\spadcommand{nary? y}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{unary? y}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Use the two-argument form when you want to restrict the number of
+arguments in the functional expressions created with the operator.
+
+This operator can only be used to create functional expressions
+with one argument.
+
+\spadcommand{opOne := operator('opOne, 1)}
+$$
+opOne 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{nary? opOne}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{unary? opOne}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+Use \spadfunFrom{arity}{BasicOperator} to learn the number of arguments 
+that can be used.  It returns {\tt "false"} if the operator is nary.
+
+\spadcommand{arity opOne}
+$$
+1 
+$$
+\returnType{Type: Union(NonNegativeInteger,...)}
+
+Use \spadfunFrom{name}{BasicOperator} to learn the name of an operator.
+
+\spadcommand{name opOne}
+$$
+opOne 
+$$
+\returnType{Type: Symbol}
+
+Use \spadfunFrom{is?}{BasicOperator} to learn if an operator has a
+particular name.
+
+\spadcommand{is?(opOne, 'z2)}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+You can also use a string as the name to be tested against.
+
+\spadcommand{is?(opOne, "opOne")}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+You can attached named properties to an operator.  These are rarely
+used at the top-level of the Axiom interactive environment but are
+used with Axiom library source code.
+
+By default, an operator has no properties.
+
+\spadcommand{properties y}
+$$
+table() 
+$$
+\returnType{Type: AssociationList(String,None)}
+
+The interface for setting and getting properties is somewhat awkward
+because the property values are stored as values of type {\tt None}.
+
+Attach a property by using \spadfunFrom{setProperty}{BasicOperator}.
+
+\spadcommand{setProperty(y, "use", "unknown function" :: None )}
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{properties y}
+$$
+table 
+\left(
+{{ \mbox{\tt "use"} =NONE}} 
+\right)
+$$
+\returnType{Type: AssociationList(String,None)}
+
+We {\it know} the property value has type {\tt String}.
+
+\spadcommand{property(y, "use") :: None pretend String}
+$$
+\mbox{\tt "unknown function"} 
+$$
+\returnType{Type: String}
+
+Use \spadfunFrom{deleteProperty!}{BasicOperator} to destructively
+remove a property.
+
+\spadcommand{deleteProperty!(y, "use")}
+$$
+y 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{properties y}
+$$
+table() 
+$$
+\returnType{Type: AssociationList(String,None)}
+
+\section{BinaryExpansion}
+\label{BinaryExpansionXmpPage}
+
+All rational numbers have repeating binary expansions.  Operations to
+access the individual bits of a binary expansion can be obtained by
+converting the value to {\tt RadixExpansion(2)}.  More examples of
+expansions are available in 
+\ref{DecimalExpansionXmpPage} on page~\pageref{DecimalExpansionXmpPage},
+\ref{HexadecimalExpansionXmpPage} on 
+page~\pageref{HexadecimalExpansionXmpPage}, and 
+\ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}.
+
+The expansion (of type {\tt BinaryExpansion}) of a rational number
+is returned by the \spadfunFrom{binary}{BinaryExpansion} operation.
+
+\spadcommand{r := binary(22/7)}
+$$
+{11}.{\overline {001}} 
+$$
+\returnType{Type: BinaryExpansion}
+
+Arithmetic is exact.
+
+\spadcommand{r + binary(6/7)}
+$$
+100 
+$$
+\returnType{Type: BinaryExpansion}
+
+The period of the expansion can be short or long \ldots
+
+\spadcommand{[binary(1/i) for i in 102..106] }
+$$
+\begin{array}{@{}l}
+\left[
+{0.0{\overline {00000101}}}, 
+{0.{\overline {000000100111110001000101100101111001110010010101001}}},
+\right.
+\\
+\\
+\displaystyle
+{0.{000}{\overline {000100111011}}},
+{0.{\overline {000000100111}}},
+\\
+\\
+\displaystyle
+\left.
+{0.0{\overline {0000010011010100100001110011111011001010110111100011}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List BinaryExpansion}
+
+or very long.
+
+\spadcommand{binary(1/1007) }
+$$
+\begin{array}{@{}l}
+0.
+\overline 
+{000000000100000100010100100101111000001111110000101111110010110001111101}
+\\
+\displaystyle
+\ \ \overline 
+{000100111001001100110001100100101010111101101001100000000110000110011110}
+\\
+\displaystyle
+\ \ \overline 
+{111000110100010111101001000111101100001010111011100111010101110011001010}
+\\
+\displaystyle
+\ \ \overline 
+{010111000000011100011110010000001001001001101110010101001110100011011101}
+\\
+\displaystyle
+\ \ \overline 
+{101011100010010000011001011011000000101100101111100010100000101010101101}
+\\
+\displaystyle
+\ \ \overline 
+{011000001101101110100101011111110101110101001100100001010011011000100110}
+\\
+\displaystyle
+\ \ \overline 
+{001000100001000011000111010011110001}
+\end{array}
+$$
+\returnType{Type: BinaryExpansion}
+
+These numbers are bona fide algebraic objects.
+
+\spadcommand{p := binary(1/4)*x**2 + binary(2/3)*x + binary(4/9)}
+$$
+{{0.{01}} \  {x \sp 2}}+{{0.{\overline {10}}} \  x}+{0.{\overline {011100}}} 
+$$
+\returnType{Type: Polynomial BinaryExpansion}
+
+\spadcommand{q := D(p, x)}
+$$
+{{0.1} \  x}+{0.{\overline {10}}} 
+$$
+\returnType{Type: Polynomial BinaryExpansion}
+
+\spadcommand{g := gcd(p, q)}
+$$
+x+{1.{\overline {01}}} 
+$$
+\returnType{Type: Polynomial BinaryExpansion}
+
+\section{BinarySearchTree}
+\label{BinarySearchTreeXmpPage}
+
+{\tt BinarySearchTree(R)} is the domain of binary trees with elements
+of type {\tt R}, ordered across the nodes of the tree.  A non-empty
+binary search tree has a value of type {\tt R}, and {\tt right} and
+{\tt left} binary search subtrees.  If a subtree is empty, it is
+displayed as a period (``.'').
+
+Define a list of values to be placed across the tree.  The resulting
+tree has {\tt 8} at the root; all other elements are in the left
+subtree.
+
+\spadcommand{lv := [8,3,5,4,6,2,1,5,7]}
+$$
+\left[
+8, 3, 5, 4, 6, 2, 1, 5, 7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+A convenient way to create a binary search tree is to apply the
+operation {\tt binarySearchTree} to a list of elements.
+
+\spadcommand{t := binarySearchTree lv}
+$$
+\left[
+{\left[ {\left[ 1, 2, . \right]}, 3, 
+{\left[ 4, 5, {\left[ 5, 6, 7 \right]}\right]}
+\right]},
+8, . 
+\right]
+$$
+\returnType{Type: BinarySearchTree PositiveInteger}
+
+Another approach is to first create an empty binary search tree of integers.
+
+\spadcommand{emptybst := empty()\$BSTREE(INT)}
+$$
+[\ ] 
+$$
+\returnType{Type: BinarySearchTree Integer}
+
+Insert the value {\tt 8}.  This establishes {\tt 8} as the root of the
+binary search tree.  Values inserted later that are less than {\tt 8}
+get stored in the {\tt left} subtree, others in the {\tt right} subtree.
+
+\spadcommand{t1 := insert!(8,emptybst)}
+$$
+8 
+$$
+\returnType{Type: BinarySearchTree Integer}
+
+Insert the value {\tt 3}. This number becomes the root of the {\tt
+left} subtree of {\tt t1}.  For optimal retrieval, it is thus
+important to insert the middle elements first.
+
+\spadcommand{insert!(3,t1)}
+$$
+\left[3, 8, . \right]
+$$
+\returnType{Type: BinarySearchTree Integer}
+
+We go back to the original tree {\tt t}.  The leaves of the binary
+search tree are those which have empty {\tt left} and {\tt right} subtrees.
+
+\spadcommand{leaves t}
+$$
+\left[
+1, 4, 5, 7 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+The operation {\tt split}{\tt (k,t)} returns a \index{record}
+containing the two subtrees: one with all elements ``less'' than 
+{\tt k}, another with elements ``greater'' than {\tt k}.
+
+\spadcommand{split(3,t)}
+$$
+\left[
+{less={\left[ 1, 2, . \right]}},
+{greater={\left[ {\left[ ., 3, 
+{\left[ 4, 5, 
+{\left[ 5, 6, 7 \right]}
+\right]}
+\right]},
+8, . 
+\right]}}
+\right]
+$$
+\returnType{Type: 
+Record(less: BinarySearchTree PositiveInteger,greater: 
+BinarySearchTree PositiveInteger)}
+
+Define {\tt insertRoot} to insert new elements by creating a new node.
+
+\spadcommand{insertRoot: (INT,BSTREE INT) -> BSTREE INT}
+\returnType{Type: Void}
+
+The new node puts the inserted value between its ``less'' tree and
+``greater'' tree.
+
+\begin{verbatim}
+insertRoot(x, t) ==
+    a := split(x, t)
+    node(a.less, x, a.greater)
+\end{verbatim}
+
+Function {\tt buildFromRoot} builds a binary search tree from a list
+of elements {\tt ls} and the empty tree {\tt emptybst}.
+
+\spadcommand{buildFromRoot ls == reduce(insertRoot,ls,emptybst)}
+\returnType{Type: Void}
+
+Apply this to the reverse of the list {\tt lv}.
+
+\spadcommand{rt := buildFromRoot reverse lv}
+$$
+\left[
+{\left[ {\left[ 1, 2, . \right]}, 3, 
+{\left[ 4, 5, {\left[ 5, 6, 7\right]}\right]}
+\right]},
+8, . 
+\right]
+$$
+\returnType{Type: BinarySearchTree Integer}
+
+Have Axiom check that these are equal.
+
+\spadcommand{(t = rt)@Boolean}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\section{CardinalNumber}
+\label{CardinalNumberXmpPage}
+
+The {\tt CardinalNumber} domain can be used for values indicating the
+cardinality of sets, both finite and infinite.  For example, the
+\spadfunFrom{dimension}{VectorSpace} operation in the category 
+{\tt VectorSpace} returns a cardinal number.
+
+The non-negative integers have a natural construction as cardinals
+\begin{verbatim}
+0 = #{ }, 1 = {0}, 2 = {0, 1}, ..., n = {i | 0 <= i < n}.
+\end{verbatim}
+
+The fact that {\tt 0} acts as a zero for the multiplication of cardinals is
+equivalent to the axiom of choice.
+
+Cardinal numbers can be created by conversion from non-negative integers.
+
+\spadcommand{c0 := 0 :: CardinalNumber}
+$$
+0 
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{c1 := 1 :: CardinalNumber}
+$$
+1 
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{c2 := 2 :: CardinalNumber}
+$$
+2 
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{c3 := 3 :: CardinalNumber}
+$$
+3 
+$$
+\returnType{Type: CardinalNumber}
+
+They can also be obtained as the named cardinal {\tt Aleph(n)}.
+
+\spadcommand{A0 := Aleph 0}
+$$
+Aleph 
+\left(
+{0} 
+\right)
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{A1 := Aleph 1}
+$$
+Aleph 
+\left(
+{1} 
+\right)
+$$
+\returnType{Type: CardinalNumber}
+
+The \spadfunFrom{finite?}{CardinalNumber} operation tests whether a
+value is a finite cardinal, that is, a non-negative integer.
+
+\spadcommand{finite? c2}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{finite? A0}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Similarly, the \spadfunFrom{countable?}{CardinalNumber}
+operation determines whether a value is
+a countable cardinal, that is, finite or {\tt Aleph(0)}.
+
+\spadcommand{countable? c2}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{countable? A0}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{countable? A1}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Arithmetic operations are defined on cardinal numbers as follows:
+If {\tt x = \#X}  and  {\tt y = \#Y} then
+
+\noindent
+$
+\begin{array}{lr}
+{\tt x+y  = \#(X+Y)}  & cardinality of the disjoint union\\
+{\tt x-y  = \#(X-Y)}  & cardinality of the relative complement \\
+{\tt x*y  = \#(X*Y)}  & cardinality of the Cartesian product \\
+{\tt x**y = \#(X**Y)} & 
+cardinality of the set of maps from {\tt Y} to {\tt X} \\
+\end{array}
+$
+
+Here are some arithmetic examples.
+
+\spadcommand{[c2 + c2, c2 + A1]}
+$$
+\left[4, {Aleph \left({1} \right)}\right]
+$$
+\returnType{Type: List CardinalNumber}
+
+\spadcommand{[c0*c2, c1*c2, c2*c2, c0*A1, c1*A1, c2*A1, A0*A1]}
+$$
+\left[
+0, 2, 4, 0, {Aleph \left({1} \right)},
+{Aleph \left({1} \right)},
+{Aleph \left({1} \right)}
+\right]
+$$
+\returnType{Type: List CardinalNumber}
+
+\spadcommand{[c2**c0, c2**c1, c2**c2, A1**c0, A1**c1, A1**c2]}
+$$
+\left[
+1, 2, 4, 1, {Aleph \left({1} \right)},
+{Aleph \left({1} \right)}
+\right]
+$$
+\returnType{Type: List CardinalNumber}
+
+Subtraction is a partial operation: it is not defined
+when subtracting a larger cardinal from a smaller one, nor
+when subtracting two equal infinite cardinals.
+
+\spadcommand{[c2-c1, c2-c2, c2-c3, A1-c2, A1-A0, A1-A1]}
+$$
+\left[
+1, 0, \mbox{\tt "failed"} , {Aleph \left({1} \right)},
+{Aleph \left({1} \right)},
+\mbox{\tt "failed"} 
+\right]
+$$
+\returnType{Type: List Union(CardinalNumber,"failed")}
+
+The generalized continuum hypothesis asserts that
+\begin{verbatim}
+2**Aleph i = Aleph(i+1)
+\end{verbatim}
+and is independent of the axioms of set theory.\footnote{Goedel,
+{\it The consistency of the continuum hypothesis,}
+Ann. Math. Studies, Princeton Univ. Press, 1940.}
+
+The {\tt CardinalNumber} domain provides an operation to assert
+whether the hypothesis is to be assumed.
+
+\spadcommand{generalizedContinuumHypothesisAssumed true}
+
+When the generalized continuum hypothesis
+is assumed, exponentiation to a transfinite power is allowed.
+
+\spadcommand{[c0**A0, c1**A0, c2**A0, A0**A0, A0**A1, A1**A0, A1**A1]}
+$$
+\left[
+0, 1, {Aleph \left({1} \right)},
+{Aleph \left({1} \right)},
+{Aleph \left({2} \right)},
+{Aleph \left({1} \right)},
+{Aleph \left({2} \right)}
+\right]
+$$
+\returnType{Type: List CardinalNumber}
+
+Three commonly encountered cardinal numbers are
+
+\noindent
+$
+\begin{array}{lr}
+{\tt a = \#}{\bf Z} & countable infinity  \\
+{\tt c = \#}{\bf R} & the continuum       \\
+{\tt f = \#\{g| g: [0,1] -> {\bf R}\}}    \\
+\end{array}
+$
+
+In this domain, these values are obtained under the generalized
+continuum hypothesis in this way.
+
+\spadcommand{a := Aleph 0}
+$$
+Aleph \left({0} \right)
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{c := 2**a}
+$$
+Aleph \left({1} \right)
+$$
+\returnType{Type: CardinalNumber}
+
+\spadcommand{f := 2**c}
+$$
+Aleph \left({2} \right)
+$$
+\returnType{Type: CardinalNumber}
+
+\section{CartesianTensor}
+\label{CartesianTensorXmpPage}
+
+{\tt CartesianTensor(i0,dim,R)} provides Cartesian tensors with
+components belonging to a commutative ring {\tt R}.  Tensors can be
+described as a generalization of vectors and matrices.  This gives a
+concise {\it tensor algebra} for multilinear objects supported by the
+{\tt CartesianTensor} domain.  You can form the inner or outer product
+of any two tensors and you can add or subtract tensors with the same
+number of components.  Additionally, various forms of traces and
+transpositions are useful.
+
+The {\tt CartesianTensor} constructor allows you to specify the
+minimum index for subscripting.  In what follows we discuss in detail
+how to manipulate tensors.
+
+Here we construct the domain of Cartesian tensors of dimension 2 over the
+integers, with indices starting at 1.
+
+\spadcommand{CT := CARTEN(i0 := 1, 2, Integer)}
+$$
+CartesianTensor(1,2,Integer) 
+$$
+\returnType{Type: Domain}
+
+\subsubsection{Forming tensors}
+
+Scalars can be converted to tensors of rank zero.
+
+\spadcommand{t0: CT := 8}
+$$
+8 
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{rank t0}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Vectors (mathematical direct products, rather than one dimensional array
+structures) can be converted to tensors of rank one.
+
+\spadcommand{v: DirectProduct(2, Integer) := directProduct [3,4]}
+$$
+\left[
+3, 4 
+\right]
+$$
+\returnType{Type: DirectProduct(2,Integer)}
+
+\spadcommand{Tv: CT := v}
+$$
+\left[
+3, 4 
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+Matrices can be converted to tensors of rank two.
+
+\spadcommand{m: SquareMatrix(2, Integer) := matrix [ [1,2],[4,5] ]}
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+4 & 5 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+\spadcommand{Tm: CT := m}
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+4 & 5 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{n: SquareMatrix(2, Integer) := matrix [ [2,3],[0,1] ]}
+$$
+\left[
+\begin{array}{cc}
+2 & 3 \\ 
+0 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+\spadcommand{Tn: CT := n}
+$$
+\left[
+\begin{array}{cc}
+2 & 3 \\ 
+0 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+In general, a tensor of rank {\tt k} can be formed by making a list of
+rank {\tt k-1} tensors or, alternatively, a {\tt k}-deep nested list
+of lists.
+
+\spadcommand{t1: CT := [2, 3]}
+$$
+\left[
+2, 3 
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{rank t1}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t2: CT := [t1, t1]}
+$$
+\left[
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{t3: CT := [t2, t2]}
+$$
+\left[
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]},
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{tt: CT := [t3, t3]; tt := [tt, tt]}
+$$
+\left[
+{\left[ 
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+\end{array}
+\right]},
+{\left[ 
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+2 & 3 
+\end{array}
+\right]}
+\end{array}
+\right]}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{rank tt}
+$$
+5 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsubsection{Multiplication}
+
+Given two tensors of rank {\tt k1} and {\tt k2}, the outer
+\spadfunFrom{product}{CartesianTensor} forms a new tensor of rank 
+{\tt k1+k2}. Here
+
+$$T_{mn}(i,j,k,l) = T_m(i,j) \  T_n(k,l)$$
+
+\spadcommand{Tmn := product(Tm, Tn)}
+$$
+\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+0 & 1 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+4 & 6 \\ 
+0 & 2 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+8 & {12} \\ 
+0 & 4 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+{10} & {15} \\ 
+0 & 5 
+\end{array}
+\right]}
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+The inner product (\spadfunFrom{contract}{CartesianTensor}) forms a
+tensor of rank {\tt k1+k2-2}.  This product generalizes the vector dot
+product and matrix-vector product by summing component products along
+two indices.
+
+Here we sum along the second index of $T_m$ and the first index of
+$T_v$.  Here 
+
+$$T_{mv} = \sum_{j=1}^{\hbox{\tiny\rm dim}} T_m(i,j) \ T_v(j)$$
+
+\spadcommand{Tmv := contract(Tm,2,Tv,1)}
+$$
+\left[
+{11}, {32} 
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+The multiplication operator \spadopFrom{*}{CartesianTensor} is scalar
+multiplication or an inner product depending on the ranks of the arguments.
+
+If either argument is rank zero it is treated as scalar multiplication.
+Otherwise, {\tt a*b} is the inner product summing the last index of
+{\tt a} with the first index of {\tt b}.
+
+\spadcommand{Tm*Tv}
+$$
+\left[
+{11}, {32} 
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+This definition is consistent with the inner product on matrices
+and vectors.
+
+\spadcommand{Tmv = m * v}
+$$
+{\left[ {11}, {32} \right]}=
+{\left[{11}, {32} \right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\subsubsection{Selecting Components}
+
+For tensors of low rank (that is, four or less), components can be selected
+by applying the tensor to its indices.
+
+\spadcommand{t0()}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t1(1+1)}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t2(2,1)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t3(2,1,2)}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{Tmn(2,1,2,1)}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+A general indexing mechanism is provided for a list of indices.
+
+\spadcommand{t0[]}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t1[2]}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{t2[2,1]}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+The general mechanism works for tensors of arbitrary rank, but is
+somewhat less efficient since the intermediate index list must be created.
+
+\spadcommand{t3[2,1,2]}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{Tmn[2,1,2,1]}
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+\subsubsection{Contraction}
+
+A ``contraction'' between two tensors is an inner product, as we have
+seen above.  You can also contract a pair of indices of a single
+tensor.  This corresponds to a ``trace'' in linear algebra.  The
+expression {\tt contract(t,k1,k2)} forms a new tensor by summing the
+diagonal given by indices in position {\tt k1} and {\tt k2}.
+
+This is the tensor given by
+$$xT_{mn} = \sum_{k=1}^{\hbox{\tiny\rm dim}} T_{mn}(k,k,i,j)$$
+
+\spadcommand{cTmn := contract(Tmn,1,2)}
+$$
+\left[
+\begin{array}{cc}
+{12} & {18} \\ 
+0 & 6 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+Since {\tt Tmn} is the outer product of matrix {\tt m} and matrix {\tt n},
+the above is equivalent to this.
+
+\spadcommand{trace(m) * n}
+$$
+\left[
+\begin{array}{cc}
+{12} & {18} \\ 
+0 & 6 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+In this and the next few examples, we show all possible contractions
+of {\tt Tmn} and their matrix algebra equivalents.
+
+\spadcommand{contract(Tmn,1,2) = trace(m) * n}
+$$
+{\left[ 
+\begin{array}{cc}
+{12} & {18} \\ 
+0 & 6 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+{12} & {18} \\ 
+0 & 6 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\spadcommand{contract(Tmn,1,3) = transpose(m) * n}
+$$
+{\left[ 
+\begin{array}{cc}
+2 & 7 \\ 
+4 & {11} 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+2 & 7 \\ 
+4 & {11} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\spadcommand{contract(Tmn,1,4) = transpose(m) * transpose(n)}
+$$
+{\left[ 
+\begin{array}{cc}
+{14} & 4 \\ 
+{19} & 5 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+{14} & 4 \\ 
+{19} & 5 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\spadcommand{contract(Tmn,2,3) = m * n}
+$$
+{\left[ 
+\begin{array}{cc}
+2 & 5 \\ 
+8 & {17} 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+2 & 5 \\ 
+8 & {17} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\spadcommand{contract(Tmn,2,4) = m * transpose(n)}
+$$
+{\left[ 
+\begin{array}{cc}
+8 & 2 \\ 
+{23} & 5 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+8 & 2 \\ 
+{23} & 5 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\spadcommand{contract(Tmn,3,4) = trace(n) * m}
+$$
+{\left[ 
+\begin{array}{cc}
+3 & 6 \\ 
+{12} & {15} 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+3 & 6 \\ 
+{12} & {15} 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\subsubsection{Transpositions}
+
+You can exchange any desired pair of indices using the
+\spadfunFrom{transpose}{CartesianTensor} operation.
+
+Here the indices in positions one and three are exchanged, that is,
+$tT_{mn}(i,j,k,l) = T_{mn}(k,j,i,l).$
+
+\spadcommand{tTmn := transpose(Tmn,1,3)}
+$$
+\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 3 \\ 
+8 & {12} 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+4 & 6 \\ 
+{10} & {15} 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+0 & 1 \\ 
+0 & 4 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+0 & 2 \\ 
+0 & 5 
+\end{array}
+\right]}
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+If no indices are specified, the first and last index are exchanged.
+
+\spadcommand{transpose Tmn}
+$$
+\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 8 \\ 
+0 & 0 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+4 & {10} \\ 
+0 & 0 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+3 & {12} \\ 
+1 & 4 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+6 & {15} \\ 
+2 & 5 
+\end{array}
+\right]}
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+This is consistent with the matrix transpose.
+
+\spadcommand{transpose Tm = transpose m}
+$$
+{\left[ 
+\begin{array}{cc}
+1 & 4 \\ 
+2 & 5 
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+1 & 4 \\ 
+2 & 5 
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+If a more complicated reordering of the indices is required, then the
+\spadfunFrom{reindex}{CartesianTensor} operation can be used.
+This operation allows the indices to be arbitrarily permuted.
+
+This defines $rT_{mn}(i,j,k,l) = \allowbreak T_{mn}(i,l,j,k).$
+
+\spadcommand{rTmn := reindex(Tmn, [1,4,2,3])}
+$$
+\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 0 \\ 
+4 & 0 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+3 & 1 \\ 
+6 & 2 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+8 & 0 \\ 
+{10} & 0 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+{12} & 4 \\ 
+{15} & 5 
+\end{array}
+\right]}
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\subsubsection{Arithmetic}
+
+Tensors of equal rank can be added or subtracted so arithmetic
+expressions can be used to produce new tensors.
+
+\spadcommand{tt := transpose(Tm)*Tn - Tn*transpose(Tm)}
+$$
+\left[
+\begin{array}{cc}
+-6 & -{16} \\ 
+2 & 6 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{Tv*(tt+Tn)}
+$$
+\left[
+-4, -{11} 
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\spadcommand{reindex(product(Tn,Tn),[4,3,2,1])+3*Tn*product(Tm,Tm)}
+$$
+\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+{46} & {84} \\ 
+{174} & {212} 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+{57} & {114} \\ 
+{228} & {285} 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+{18} & {24} \\ 
+{57} & {63} 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+{17} & {30} \\ 
+{63} & {76} 
+\end{array}
+\right]}
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+\subsubsection{Specific Tensors}
+
+Two specific tensors have properties which depend only on the
+dimension.
+
+The Kronecker delta satisfies
+\begin{verbatim}
+             +-
+             |   1  if i  = j
+delta(i,j) = |
+             |   0  if i ^= j
+             +-
+\end{verbatim}
+
+\spadcommand{delta:  CT := kroneckerDelta()}
+$$
+\left[
+\begin{array}{cc}
+1 & 0 \\ 
+0 & 1 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+This can be used to reindex via contraction.
+
+\spadcommand{contract(Tmn, 2, delta, 1) = reindex(Tmn, [1,3,4,2])}
+$$
+{\left[ 
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 4 \\ 
+3 & 6 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+1 & 2 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+8 & {10} \\ 
+{12} & {15} 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+4 & 5 
+\end{array}
+\right]}
+\end{array}
+\right]}={\left[
+\begin{array}{cc}
+{\left[ 
+\begin{array}{cc}
+2 & 4 \\ 
+3 & 6 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+1 & 2 
+\end{array}
+\right]}
+\\ 
+{\left[ 
+\begin{array}{cc}
+8 & {10} \\ 
+{12} & {15} 
+\end{array}
+\right]}
+& {\left[ 
+\begin{array}{cc}
+0 & 0 \\ 
+4 & 5 
+\end{array}
+\right]}
+\end{array}
+\right]}
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+The Levi Civita symbol determines the sign of a permutation of indices.
+
+\spadcommand{epsilon:CT := leviCivitaSymbol()}
+$$
+\left[
+\begin{array}{cc}
+0 & 1 \\ 
+-1 & 0 
+\end{array}
+\right]
+$$
+\returnType{Type: CartesianTensor(1,2,Integer)}
+
+Here we have:
+\begin{verbatim}
+epsilon(i1,...,idim)
+     = +1  if i1,...,idim is an even permutation of i0,...,i0+dim-1
+     = -1  if i1,...,idim is an  odd permutation of i0,...,i0+dim-1
+     =  0  if i1,...,idim is not   a permutation of i0,...,i0+dim-1
+\end{verbatim}
+
+This property can be used to form determinants.
+
+\spadcommand{contract(epsilon*Tm*epsilon, 1,2) = 2 * determinant m}
+$$
+-6=-6 
+$$
+\returnType{Type: Equation CartesianTensor(1,2,Integer)}
+
+\subsubsection{Properties of the CartesianTensor domain}
+
+{\tt GradedModule(R,E)} denotes ``{\tt E}-graded {\tt R}-module'',
+that is, a collection of {\tt R}-modules indexed by an abelian monoid
+{\tt E.}  An element {\tt g} of {\tt G[s]} for some specific {\tt s}
+in {\tt E} is said to be an element of {\tt G} with
+\spadfunFrom{degree}{GradedModule} {\tt s}.  Sums are defined in each
+module {\tt G[s]} so two elements of {\tt G} can be added if they have
+the same degree.  Morphisms can be defined and composed by degree to
+give the mathematical category of graded modules.
+
+{\tt GradedAlgebra(R,E)} denotes ``{\tt E}-graded {\tt R}-algebra.''
+A graded algebra is a graded module together with a degree preserving
+{\tt R}-bilinear map, called the \spadfunFrom{product}{GradedAlgebra}.
+
+\begin{verbatim}
+degree(product(a,b))    = degree(a) + degree(b)
+
+product(r*a,b)          = product(a,r*b) = r*product(a,b)
+product(a1+a2,b)        = product(a1,b) + product(a2,b)
+product(a,b1+b2)        = product(a,b1) + product(a,b2)
+product(a,product(b,c)) = product(product(a,b),c)
+\end{verbatim}
+
+The domain {\tt CartesianTensor(i0, dim, R)} belongs to the category
+{\tt GradedAlgebra(R, NonNegativeInteger)}.  The non-negative integer
+\spadfunFrom{degree}{GradedAlgebra} is the tensor rank and the graded
+algebra \spadfunFrom{product}{GradedAlgebra} is the tensor outer
+product.  The graded module addition captures the notion that only
+tensors of equal rank can be added.
+
+If {\tt V} is a vector space of dimension {\tt dim} over {\tt R},
+then the tensor module {\tt T[k](V)} is defined as
+\begin{verbatim}
+T[0](V) = R
+T[k](V) = T[k-1](V) * V
+\end{verbatim}
+where {\tt *} denotes the {\tt R}-module tensor
+\spadfunFrom{product}{GradedAlgebra}.  {\tt CartesianTensor(i0,dim,R)}
+is the graded algebra in which the degree {\tt k} module is {\tt
+T[k](V)}.
+
+\subsubsection{Tensor Calculus}
+
+It should be noted here that often tensors are used in the context of
+tensor-valued manifold maps.  This leads to the notion of covariant
+and contravariant bases with tensor component functions transforming
+in specific ways under a change of coordinates on the manifold.  This
+is no more directly supported by the {\tt CartesianTensor} domain than
+it is by the {\tt Vector} domain.  However, it is possible to have the
+components implicitly represent component maps by choosing a
+polynomial or expression type for the components.  In this case, it is
+up to the user to satisfy any constraints which arise on the basis of
+this interpretation.
+
+\section{Character}
+\label{CharacterXmpPage}
+The members of the domain {\tt Character} are values
+representing letters, numerals and other text elements.
+For more information on related topics, see
+\ref{CharacterClassXmpPage} on page~\pageref{CharacterClassXmpPage} and 
+\ref{StringXmpPage} on page~\pageref{StringXmpPage}.
+
+Characters can be obtained using {\tt String} notation.
+
+\spadcommand{chars := [char "a", char "A", char "X", char "8", char "+"]}
+$$
+\left[
+a, A, X, 8, + 
+\right]
+$$
+\returnType{Type: List Character}
+
+Certain characters are available by name.
+This is the blank character.
+
+\spadcommand{space()}
+$$
+\  
+$$
+\returnType{Type: Character}
+
+This is the quote that is used in strings.
+
+\spadcommand{quote()}
+$$
+\mbox{\tt "} 
+$$
+\returnType{Type: Character}
+
+This is the escape character that allows quotes and other characters
+within strings.
+
+\spadcommand{escape()}
+$$
+\_ 
+$$
+\returnType{Type: Character}
+
+Characters are represented as integers in a machine-dependent way.
+The integer value can be obtained using the
+\spadfunFrom{ord}{Character} operation.  It is always true that {\tt
+char(ord c) = c} and {\tt ord(char i) = i}, provided that {\tt i} is
+in the range {\tt 0..size()\$Character-1}.
+
+\spadcommand{[ord c for c in chars]}
+$$
+\left[
+{97}, {65}, {88}, {56}, {43} 
+\right]
+$$
+\returnType{Type: List Integer}
+ 
+The \spadfunFrom{lowerCase}{Character} operation converts an upper
+case letter to the corresponding lower case letter.  If the argument
+is not an upper case letter, then it is returned unchanged.
+
+\spadcommand{[upperCase c for c in chars]}
+$$
+\left[
+A, A, X, 8, + 
+\right]
+$$
+\returnType{Type: List Character}
+
+Likewise, the \spadfunFrom{upperCase}{Character} operation converts lower
+case letters to upper case.
+
+\spadcommand{[lowerCase c for c in chars] }
+$$
+\left[
+a, a, x, 8, + 
+\right]
+$$
+\returnType{Type: List Character}
+
+A number of tests are available to determine whether characters
+belong to certain families.
+
+\spadcommand{[alphabetic? c for c in chars] }
+$$
+\left[
+{\tt true}, {\tt true}, {\tt true}, {\tt false}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\spadcommand{[upperCase? c for c in chars] }
+$$
+\left[
+{\tt false}, {\tt true}, {\tt true}, {\tt false}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\spadcommand{[lowerCase? c for c in chars] }
+$$
+\left[
+{\tt true}, {\tt false}, {\tt false}, {\tt false}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\spadcommand{[digit? c for c in chars] }
+$$
+\left[
+{\tt false}, {\tt false}, {\tt false}, {\tt true}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\spadcommand{[hexDigit? c for c in chars] }
+$$
+\left[
+{\tt true}, {\tt true}, {\tt false}, {\tt true}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\spadcommand{[alphanumeric? c for c in chars] }
+$$
+\left[
+{\tt true}, {\tt true}, {\tt true}, {\tt true}, {\tt false} 
+\right]
+$$
+\returnType{Type: List Boolean}
+
+\section{CharacterClass}
+\label{CharacterClassXmpPage}
+The {\tt CharacterClass} domain allows classes of characters to be
+defined and manipulated efficiently.
+ 
+Character classes can be created by giving either a string or a list
+of characters.
+
+\spadcommand{cl1 := charClass [char "a", char "e", char "i", char "o", char "u", char "y"] }
+$$
+\mbox{\tt "aeiouy"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{cl2 := charClass "bcdfghjklmnpqrstvwxyz" }
+$$
+\mbox{\tt "bcdfghjklmnpqrstvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+A number of character classes are predefined for convenience.
+
+\spadcommand{digit()}
+$$
+\mbox{\tt "0123456789"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{hexDigit()}
+$$
+\mbox{\tt "0123456789ABCDEFabcdef"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{upperCase()}
+$$
+\mbox{\tt "ABCDEFGHIJKLMNOPQRSTUVWXYZ"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{lowerCase()}
+$$
+\mbox{\tt "abcdefghijklmnopqrstuvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{alphabetic()}
+$$
+\mbox{\tt "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{alphanumeric()}
+$$
+\mbox{\tt "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+You can quickly test whether a character belongs to a class.
+
+\spadcommand{member?(char "a", cl1) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{member?(char "a", cl2) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Classes have the usual set operations because the {\tt CharacterClass}
+domain belongs to the category {\tt FiniteSetAggregate(Character)}.
+
+\spadcommand{intersect(cl1, cl2)  }
+$$
+\mbox{\tt "y"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{union(cl1,cl2)       }
+$$
+\mbox{\tt "abcdefghijklmnopqrstuvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{difference(cl1,cl2)  }
+$$
+\mbox{\tt "aeiou"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{intersect(complement(cl1),cl2)  }
+$$
+\mbox{\tt "bcdfghjklmnpqrstvwxz"} 
+$$
+\returnType{Type: CharacterClass}
+
+You can modify character classes by adding or removing characters.
+
+\spadcommand{insert!(char "a", cl2) }
+$$
+\mbox{\tt "abcdfghjklmnpqrstvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+
+\spadcommand{remove!(char "b", cl2) }
+$$
+\mbox{\tt "acdfghjklmnpqrstvwxyz"} 
+$$
+\returnType{Type: CharacterClass}
+ 
+For more information on related topics, see 
+\ref{CharacterXmpPage} on page~\pageref{CharacterXmpPage} and
+\ref{StringXmpPage} on page~\pageref{StringXmpPage}.
+
+\section{CliffordAlgebra}
+\label{CliffordAlgebraXmpPage}
+\noindent
+
+{\tt CliffordAlgebra(n,K,Q)} defines a vector space of dimension $2^n$
+over the field $K$ with a given quadratic form {\tt Q}.  If $\{e_1,
+\ldots, e_n\}$ is a basis for $K^n$ then
+\begin{verbatim}
+{ 1,
+  e(i) 1 <= i <= n,
+  e(i1)*e(i2) 1 <= i1 < i2 <=n,
+  ...,
+  e(1)*e(2)*...*e(n) }
+\end{verbatim}
+is a basis for the Clifford algebra. The algebra is defined by the relations
+\begin{verbatim}
+e(i)*e(i) = Q(e(i))
+e(i)*e(j) = -e(j)*e(i),  i ^= j
+\end{verbatim}
+Examples of Clifford Algebras are
+gaussians (complex numbers), quaternions,
+exterior algebras and spin algebras.
+
+\subsection{The Complex Numbers as a Clifford Algebra}
+
+This is the field over which we will work, rational functions with
+integer coefficients.
+
+\spadcommand{K := Fraction Polynomial Integer }
+$$
+\mbox{\rm Fraction Polynomial Integer} 
+$$
+\returnType{Type: Domain}
+
+We use this matrix for the quadratic form.
+
+\spadcommand{m := matrix [ [-1] ] }
+$$
+\left[
+\begin{array}{c}
+-1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+We get complex arithmetic by using this domain.
+
+\spadcommand{C := CliffordAlgebra(1, K, quadraticForm m) }
+$$
+\mbox{\rm CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} 
+$$
+\returnType{Type: Domain}
+
+Here is {\tt i}, the usual square root of {\tt -1.}
+
+\spadcommand{i: C := e(1)   }
+$$
+e \sb {1} 
+$$
+\returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)}
+
+Here are some examples of the arithmetic.
+
+\spadcommand{x := a + b * i }
+$$
+a+{b \  {e \sb {1}}} 
+$$
+\returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{y := c + d * i }
+$$
+c+{d \  {e \sb {1}}} 
+$$
+\returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)}
+
+See \ref{ComplexXmpPage} on page~\pageref{ComplexXmpPage} 
+for examples of Axiom's constructor implementing complex numbers.
+
+\spadcommand{x * y }
+$$
+-{b \  d}+{a \  c}+{{\left( {a \  d}+{b \  c} 
+\right)}
+\  {e \sb {1}}} 
+$$
+\returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)}
+
+\subsection{The Quaternion Numbers as a Clifford Algebra}
+
+This is the field over which we will work, rational functions with
+integer coefficients.
+
+\spadcommand{K := Fraction Polynomial Integer }
+$$
+\mbox{\rm Fraction Polynomial Integer} 
+$$
+\returnType{Type: Domain}
+
+We use this matrix for the quadratic form.
+
+\spadcommand{m := matrix [ [-1,0],[0,-1] ] }
+$$
+\left[
+\begin{array}{cc}
+-1 & 0 \\ 
+0 & -1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+The resulting domain is the quaternions.
+
+\spadcommand{H  := CliffordAlgebra(2, K, quadraticForm m) }
+$$
+\mbox{\rm CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} 
+$$
+\returnType{Type: Domain}
+
+We use Hamilton's notation for {\tt i},{\tt j},{\tt k}.
+
+\spadcommand{i: H  := e(1) }
+$$
+e \sb {1} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{j: H  := e(2) }
+$$
+e \sb {2} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{k: H  := i * j }
+$$
+{e \sb {1}} \  {e \sb {2}} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{x := a + b * i + c * j + d * k }
+$$
+a+{b \  {e \sb {1}}}+{c \  {e \sb {2}}}+{d \  {e \sb {1}} \  {e \sb {2}}} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{y := e + f * i + g * j + h * k }
+$$
+e+{f \  {e \sb {1}}}+{g \  {e \sb {2}}}+{h \  {e \sb {1}} \  {e \sb {2}}} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{x + y }
+$$
+e+a+{{\left( f+b 
+\right)}
+\  {e \sb {1}}}+{{\left( g+c 
+\right)}
+\  {e \sb {2}}}+{{\left( h+d 
+\right)}
+\  {e \sb {1}} \  {e \sb {2}}} 
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{x * y }
+$$
+\begin{array}{@{}l}
+-{d \  h} -
+{c \  g} -
+{b \  f}+
+{a \  e}+
+{{\left( {c \  h} -{d \  g}+{a \  f}+{b \  e} \right)}\  {e \sb {1}}}+
+\\
+\\
+\displaystyle
+{{\left( -{b \  h}+{a \  g}+{d \  f}+{c \  e} \right)}\  {e \sb {2}}}+
+{{\left( {a \  h}+{b \  g} -{c \  f}+{d \  e} \right)}
+\  {e \sb {1}} \  {e \sb {2}}} 
+\end{array}
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+See \ref{QuaternionXmpPage} on page~\pageref{QuaternionXmpPage} 
+for examples of Axiom's constructor implementing quaternions.
+
+\spadcommand{y * x }
+$$
+\begin{array}{@{}l}
+-{d \  h} -{c \  g} -{b \  f}+{a \  e}+
+{{\left( -{c \  h}+{d \  g}+{a \  f}+{b \  e} \right)}\  {e \sb {1}}}+
+\\
+\\
+\displaystyle
+{{\left( {b \  h}+{a \  g} -{d \  f}+{c \  e} \right)}\  {e \sb {2}}}+
+{{\left( {a \  h} -
+{b \  g}+{c \  f}+{d \  e} \right)}\  {e \sb {1}} \  {e \sb {2}}} 
+\end{array}
+$$
+\returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)}
+
+\subsection{The Exterior Algebra on a Three Space}
+
+This is the field over which we will work, rational functions with
+integer coefficients.
+
+\spadcommand{K := Fraction Polynomial Integer }
+$$
+\mbox{\rm Fraction Polynomial Integer} 
+$$
+\returnType{Type: Domain}
+
+If we chose the three by three zero quadratic form, we obtain
+the exterior algebra on {\tt e(1),e(2),e(3)}.
+
+\spadcommand{Ext := CliffordAlgebra(3, K, quadraticForm 0) }
+$$
+\mbox{\rm CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} 
+$$
+\returnType{Type: Domain}
+
+This is a three dimensional vector algebra.
+We define {\tt i}, {\tt j}, {\tt k} as the unit vectors.
+
+\spadcommand{i: Ext := e(1) }
+$$
+e \sb {1} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{j: Ext := e(2) }
+$$
+e \sb {2} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{k: Ext := e(3) }
+$$
+e \sb {3} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+Now it is possible to do arithmetic.
+
+\spadcommand{x := x1*i + x2*j + x3*k }
+$$
+{x1 \  {e \sb {1}}}+{x2 \  {e \sb {2}}}+{x3 \  {e \sb {3}}} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{y := y1*i + y2*j + y3*k }
+$$
+{y1 \  {e \sb {1}}}+{y2 \  {e \sb {2}}}+{y3 \  {e \sb {3}}} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{x + y         }
+$$
+{{\left( y1+x1 
+\right)}
+\  {e \sb {1}}}+{{\left( y2+x2 
+\right)}
+\  {e \sb {2}}}+{{\left( y3+x3 
+\right)}
+\  {e \sb {3}}} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\spadcommand{x * y + y * x }
+$$
+0 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+On an {\tt n} space, a grade {\tt p} form has a dual {\tt n-p} form.
+In particular, in three space the dual of a grade two element identifies
+{\tt e1*e2->e3, e2*e3->e1, e3*e1->e2}.
+
+\spadcommand{dual2 a == coefficient(a,[2,3]) * i + coefficient(a,[3,1]) * j + coefficient(a,[1,2]) * k }
+\returnType{Type: Void}
+
+The vector cross product is then given by this.
+
+\spadcommand{dual2(x*y) }
+\begin{verbatim}
+   Compiling function dual2 with type CliffordAlgebra(3,Fraction 
+      Polynomial Integer,MATRIX) -> CliffordAlgebra(3,Fraction 
+      Polynomial Integer,MATRIX) 
+\end{verbatim}
+$$
+{{\left( {x2 \  y3} -{x3 \  y2} 
+\right)}
+\  {e \sb {1}}}+{{\left( -{x1 \  y3}+{x3 \  y1} 
+\right)}
+\  {e \sb {2}}}+{{\left( {x1 \  y2} -{x2 \  y1} 
+\right)}
+\  {e \sb {3}}} 
+$$
+\returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)}
+
+\subsection{The Dirac Spin Algebra}
+
+In this section we will work over the field of rational numbers.
+
+\spadcommand{K := Fraction Integer }
+$$
+\mbox{\rm Fraction Integer} 
+$$
+\returnType{Type: Domain}
+
+We define the quadratic form to be the Minkowski space-time metric.
+
+\spadcommand{g := matrix [ [1,0,0,0], [0,-1,0,0], [0,0,-1,0], [0,0,0,-1] ] }
+$$
+\left[
+\begin{array}{cccc}
+1 & 0 & 0 & 0 \\ 
+0 & -1 & 0 & 0 \\ 
+0 & 0 & -1 & 0 \\ 
+0 & 0 & 0 & -1 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Integer}
+
+We obtain the Dirac spin algebra used in Relativistic Quantum Field Theory.
+
+\spadcommand{D := CliffordAlgebra(4,K, quadraticForm g) }
+$$
+\mbox{\rm CliffordAlgebra(4,Fraction Integer,MATRIX)} 
+$$
+\returnType{Type: Domain}
+
+The usual notation for the basis is $\gamma$ with a superscript.  For
+Axiom input we will use {\tt gam(i)}:
+
+\spadcommand{gam := [e(i)\$D for i in 1..4] }
+$$
+\left[
+{e \sb {1}}, {e \sb {2}}, {e \sb {3}}, {e \sb {4}} 
+\right]
+$$
+\returnType{Type: List CliffordAlgebra(4,Fraction Integer,MATRIX)}
+
+\noindent
+There are various contraction identities of the form
+\begin{verbatim}
+g(l,t)*gam(l)*gam(m)*gam(n)*gam(r)*gam(s)*gam(t) =
+      2*(gam(s)gam(m)gam(n)gam(r) + gam(r)*gam(n)*gam(m)*gam(s))
+\end{verbatim}
+where a sum over {\tt l} and {\tt t} is implied.
+
+Verify this identity for particular values of {\tt m,n,r,s}.
+
+\spadcommand{m := 1; n:= 2; r := 3; s := 4; }
+\returnType{Type: PositiveInteger}
+
+\spadcommand{lhs := reduce(+, [reduce(+, [ g(l,t)*gam(l)*gam(m)*gam(n)*gam(r)*gam(s)*gam(t) for l in 1..4]) for t in 1..4]) }
+$$
+-{4 \  {e \sb {1}} \  {e \sb {2}} \  {e \sb {3}} \  {e \sb {4}}} 
+$$
+\returnType{Type: CliffordAlgebra(4,Fraction Integer,MATRIX)}
+
+\spadcommand{rhs := 2*(gam s * gam m*gam n*gam r + gam r*gam n*gam m*gam s) }
+$$
+-{4 \  {e \sb {1}} \  {e \sb {2}} \  {e \sb {3}} \  {e \sb {4}}} 
+$$
+\returnType{Type: CliffordAlgebra(4,Fraction Integer,MATRIX)}
+
+\section{Complex}
+\label{ComplexXmpPage}
+
+The {\tt Complex} constructor implements complex objects over a
+commutative ring {\tt R}.  Typically, the ring {\tt R} is {\tt Integer}, 
+{\tt Fraction Integer}, {\tt Float} or {\tt DoubleFloat}.
+{\tt R} can also be a symbolic type, like {\tt Polynomial Integer}.
+For more information about the numerical and graphical aspects of
+complex numbers, see \ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}.
+
+Complex objects are created by the \spadfunFrom{complex}{Complex} operation.
+
+\spadcommand{a := complex(4/3,5/2) }
+$$
+{4 \over 3}+{{5 \over 2} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+\spadcommand{b := complex(4/3,-5/2) }
+$$
+{4 \over 3} -{{5 \over 2} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+The standard arithmetic operations are available.
+
+\spadcommand{a + b }
+$$
+8 \over 3 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+\spadcommand{a - b }
+$$
+5 \  i 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+\spadcommand{a * b }
+$$
+{289} \over {36} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+If {\tt R} is a field, you can also divide the complex objects.
+
+\spadcommand{a / b }
+$$
+-{{161} \over {289}}+{{{240} \over {289}} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+Use a conversion (\ref{ugTypesConvertPage} on 
+page~\pageref{ugTypesConvertPage} in Section 
+\ref{ugTypesConvertNumber} on page~\pageref{ugTypesConvertNumber}) 
+to view the last object as a fraction of complex integers.
+
+\spadcommand{\% :: Fraction Complex Integer }
+$$
+{-{15}+{8 \  i}} \over {{15}+{8 \  i}} 
+$$
+\returnType{Type: Fraction Complex Integer}
+
+The predefined macro {\tt \%i} is defined to be {\tt complex(0,1)}.
+
+\spadcommand{3.4 + 6.7 * \%i}
+$$
+{3.4}+{{6.7} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+You can also compute the \spadfunFrom{conjugate}{Complex} and
+\spadfunFrom{norm}{Complex} of a complex number.
+
+\spadcommand{conjugate a }
+$$
+{4 \over 3} -{{5 \over 2} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+\spadcommand{norm a }
+$$
+{289} \over {36} 
+$$
+\returnType{Type: Fraction Integer}
+
+The \spadfunFrom{real}{Complex} and \spadfunFrom{imag}{Complex} operations
+are provided to extract the real and imaginary parts, respectively.
+
+\spadcommand{real a }
+$$
+4 \over 3 
+$$
+\returnType{Type: Fraction Integer}
+
+\spadcommand{imag a }
+$$
+5 \over 2 
+$$
+\returnType{Type: Fraction Integer}
+
+The domain {\tt Complex Integer} is also called the Gaussian integers.
+If {\tt R} is the integers (or, more generally, a {\tt EuclideanDomain}), 
+you can compute greatest common divisors.
+
+\spadcommand{gcd(13 - 13*\%i,31 + 27*\%i)}
+$$
+5+i 
+$$
+\returnType{Type: Complex Integer}
+
+You can also compute least common multiples.
+
+\spadcommand{lcm(13 - 13*\%i,31 + 27*\%i)}
+$$
+{143} -{{39} \  i} 
+$$
+\returnType{Type: Complex Integer}
+
+You can \spadfunFrom{factor}{Complex} Gaussian integers.
+
+\spadcommand{factor(13 - 13*\%i)}
+$$
+-{{\left( 1+i 
+\right)}
+\  {\left( 2+{3 \  i} 
+\right)}
+\  {\left( 3+{2 \  i} 
+\right)}}
+$$
+\returnType{Type: Factored Complex Integer}
+
+\spadcommand{factor complex(2,0)}
+$$
+-{i \  {{\left( 1+i 
+\right)}
+\sp 2}} 
+$$
+\returnType{Type: Factored Complex Integer}
+
+\section{ContinuedFraction}
+\label{ContinuedFractionXmpPage}
+
+Continued fractions have been a fascinating and useful tool in
+mathematics for well over three hundred years.  Axiom implements
+continued fractions for fractions of any Euclidean domain.  In
+practice, this usually means rational numbers.  In this section we
+demonstrate some of the operations available for manipulating both
+finite and infinite continued fractions.  It may be helpful if you
+review \ref{StreamXmpPage} on page~\pageref{StreamXmpPage} to remind 
+yourself of some of the operations with streams.
+
+The {\tt ContinuedFraction} domain is a field and therefore you can
+add, subtract, multiply and divide the fractions.
+
+The \spadfunFrom{continuedFraction}{ContinuedFraction} operation
+converts its fractional argument to a continued fraction.
+
+\spadcommand{c := continuedFraction(314159/100000) }
+$$
+3+ \zag{1}{7}+ \zag{1}{{15}}+ \zag{1}{1}+ \zag{1}{{25}}+ \zag{1}{1}+ 
+\zag{1}{7}+ \zag{1}{4} 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+This display is a compact form of the bulkier
+\begin{verbatim}
+        3 +                 1
+            -------------------------------
+            7 +               1
+                ---------------------------
+                15 +            1
+                     ----------------------
+                     1 +          1
+                         ------------------
+                         25 +       1
+                              -------------
+                              1 +     1
+                                  ---------
+                                  7 +   1
+                                      -----
+                                        4
+\end{verbatim}
+
+You can write any rational number in a similar form.  The fraction
+will be finite and you can always take the ``numerators'' to be {\tt 1}.
+That is, any rational number can be written as a simple, finite
+continued fraction of the form
+
+\begin{verbatim}
+        a(1) +           1
+               -------------------------
+               a(2) +          1
+                      --------------------
+                      a(3) +
+                             .
+                              .
+                               .
+                                     1
+                               -------------
+                               a(n-1) +  1
+                                        ----
+                                        a(n)
+\end{verbatim}
+
+The $a_i$ are called partial quotients and the operation
+\spadfunFrom{partialQuotients}{ContinuedFraction} creates a stream of them.
+
+\spadcommand{partialQuotients c }
+$$
+\left[
+3, 7, {15}, 1, {25}, 1, 7, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+By considering more and more of the fraction, you get the
+\spadfunFrom{convergents}{ContinuedFraction}.  For example, the first
+convergent is $a_1$, the second is $a_1 + 1/a_2$ and so on.
+
+\spadcommand{convergents c }
+$$
+\left[
+3, {{22} \over 7}, {{333} \over {106}}, {{355} \over {113}}, 
+{{9208} \over {2931}}, {{9563} \over {3044}}, {{76149} \over {24239}}, 
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+Since this is a finite continued fraction, the last convergent is the
+original rational number, in reduced form.  The result of
+\spadfunFrom{approximants}{ContinuedFraction} is always an infinite
+stream, though it may just repeat the ``last'' value.
+
+\spadcommand{approximants c }
+$$
+\left[
+3, {{22} \over 7}, {{333} \over {106}}, {{355} \over {113}}, 
+{{9208} \over {2931}}, {{9563} \over {3044}}, {{76149} \over {24239}}, 
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+Inverting {\tt c} only changes the partial quotients of its fraction
+by inserting a {\tt 0} at the beginning of the list.
+
+\spadcommand{pq := partialQuotients(1/c) }
+$$
+\left[
+0, 3, 7, {15}, 1, {25}, 1, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Do this to recover the original continued fraction from this list of
+partial quotients.  The three-argument form of the
+\spadfunFrom{continuedFraction}{ContinuedFraction} operation takes an
+element which is the whole part of the fraction, a stream of elements
+which are the numerators of the fraction, and a stream of elements
+which are the denominators of the fraction.
+
+\spadcommand{continuedFraction(first pq,repeating [1],rest pq) }
+$$
+\zag{1}{3}+ \zag{1}{7}+ \zag{1}{{15}}+ \zag{1}{1}+ \zag{1}{{25}}+ \zag{1}{1}+ 
+\zag{1}{7}+\ldots 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+The streams need not be finite for
+\spadfunFrom{continuedFraction}{ContinuedFraction}.  Can you guess
+which irrational number has the following continued fraction?  See the
+end of this section for the answer.
+
+\spadcommand{z:=continuedFraction(3,repeating [1],repeating [3,6]) }
+$$
+3+ \zag{1}{3}+ \zag{1}{6}+ \zag{1}{3}+ \zag{1}{6}+ \zag{1}{3}+ \zag{1}{6}+ 
+\zag{1}{3}+\ldots 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+In 1737 Euler discovered the infinite continued fraction expansion
+\begin{verbatim}
+        e - 1             1
+        ----- = ---------------------
+          2     1 +         1
+                    -----------------
+                    6 +       1
+                        -------------
+                        10 +    1
+                             --------
+                             14 + ...
+\end{verbatim}
+
+We use this expansion to compute rational and floating point
+approximations of {\tt e}.\footnote{For this and other interesting
+expansions, see C. D. Olds, {\it Continued Fractions,} New
+Mathematical Library, (New York: Random House, 1963), pp.  134--139.}
+
+By looking at the above expansion, we see that the whole part is {\tt 0}
+and the numerators are all equal to {\tt 1}.  This constructs the
+stream of denominators.
+
+\spadcommand{dens:Stream Integer := cons(1,generate((x+->x+4),6)) }
+$$
+\left[
+1, 6, {10}, {14}, {18}, {22}, {26}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Therefore this is the continued fraction expansion for
+$(e - 1) / 2$.
+
+\spadcommand{cf := continuedFraction(0,repeating [1],dens) }
+$$
+\zag{1}{1}+ \zag{1}{6}+ \zag{1}{{10}}+ \zag{1}{{14}}+ \zag{1}{{18}}+ 
+\zag{1}{{22}}+ \zag{1}{{26}}+\ldots 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+These are the rational number convergents.
+
+\spadcommand{ccf := convergents cf }
+$$
+\left[
+0, 1, {6 \over 7}, {{61} \over {71}}, {{860} \over {1001}}, 
+{{15541} \over {18089}}, {{342762} \over {398959}}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+You can get rational convergents for {\tt e} by multiplying by {\tt 2} and
+adding {\tt 1}.
+
+\spadcommand{eConvergents := [2*e + 1 for e in ccf] }
+$$
+\left[
+1, 3, {{19} \over 7}, {{193} \over {71}}, {{2721} \over {1001}}, 
+{{49171} \over {18089}}, {{1084483} \over {398959}}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+You can also compute the floating point approximations to these convergents.
+
+\spadcommand{eConvergents :: Stream Float }
+$$
+\begin{array}{@{}l}
+\left[
+{1.0}, {3.0}, {2.7142857142 857142857}, {2.7183098591 549295775}, 
+\right.
+\\
+\\
+\displaystyle
+{2.7182817182 817182817}, {2.7182818287 356957267}, 
+\\
+\\
+\displaystyle
+\left.
+{2.7182818284\ 585634113}, \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream Float}
+
+Compare this to the value of {\tt e} computed by the
+\spadfunFrom{exp}{Float} operation in {\tt Float}.
+
+\spadcommand{exp 1.0}
+$$
+2.7182818284\ 590452354 
+$$
+\returnType{Type: Float}
+
+In about 1658, Lord Brouncker established the following expansion
+for $4 / \pi$,
+\begin{verbatim}
+        1 +            1
+            -----------------------
+            2 +          9
+                -------------------
+                2 +        25
+                    ---------------
+                    2 +      49
+                        -----------
+                        2 +    81
+                            -------
+                            2 + ...
+\end{verbatim}
+
+Let's use this expansion to compute rational and floating point
+approximations for $\pi$.
+
+\spadcommand{cf := continuedFraction(1,[(2*i+1)**2 for i in 0..],repeating [2])}
+$$
+1+ \zag{1}{2}+ \zag{9}{2}+ \zag{{25}}{2}+ \zag{{49}}{2}+ \zag{{81}}{2}+ 
+\zag{{121}}{2}+ \zag{{169}}{2}+\ldots 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+\spadcommand{ccf := convergents cf }
+$$
+\left[
+1, {3 \over 2}, {{15} \over {13}}, {{105} \over {76}}, {{315} 
+\over {263}}, {{3465} \over {2578}}, {{45045} \over {36979}}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+\spadcommand{piConvergents := [4/p for p in ccf] }
+$$
+\left[
+4, {8 \over 3}, {{52} \over {15}}, {{304} \over {105}}, {{1052} 
+\over {315}}, {{10312} \over {3465}}, {{147916} \over {45045}}, 
+\ldots 
+\right]
+$$
+\returnType{Type: Stream Fraction Integer}
+
+As you can see, the values are converging to
+$\pi = 3.14159265358979323846...$,
+but not very quickly.
+
+\spadcommand{piConvergents :: Stream Float }
+$$
+\begin{array}{@{}l}
+\left[
+{4.0}, {2.6666666666\ 666666667}, {3.4666666666\ 666666667}, 
+\right.
+\\
+\\
+\displaystyle
+{2.8952380952\ 380952381}, {3.3396825396\ 825396825}, 
+\\
+\\
+\displaystyle
+\left.
+{2.9760461760\ 461760462}, {3.2837384837\ 384837385}, \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream Float}
+
+You need not restrict yourself to continued fractions of integers.
+Here is an expansion for a quotient of Gaussian integers.
+
+\spadcommand{continuedFraction((- 122 + 597*\%i)/(4 - 4*\%i))}
+$$
+-{90}+{{59} \  i}+ \zag{1}{{1 -{2 \  i}}}+ \zag{1}{{-1+{2 \  i}}} 
+$$
+\returnType{Type: ContinuedFraction Complex Integer}
+
+This is an expansion for a quotient of polynomials in one variable
+with rational number coefficients.
+
+\spadcommand{r : Fraction UnivariatePolynomial(x,Fraction Integer) }
+\returnType{Type: Void}
+
+\spadcommand{r := ((x - 1) * (x - 2)) / ((x-3) * (x-4)) }
+$$
+{{x \sp 2} -{3 \  x}+2} \over {{x \sp 2} -{7 \  x}+{12}} 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{continuedFraction r }
+$$
+1+ \zag{1}{{{{1 \over 4} \  x} -{9 \over 8}}}+ \zag{1}{{{{{16} \over 3} \  x} 
+-{{40} \over 3}}} 
+$$
+\returnType{Type: ContinuedFraction UnivariatePolynomial(x,Fraction Integer)}
+
+To conclude this section, we give you evidence that
+\begin{verbatim}
+    z = 3 +            1
+            -----------------------
+            3 +          1
+                -------------------
+                6 +        1
+                    ---------------
+                    3 +      1
+                        -----------
+                        6 +    1
+                            -------
+                            3 + ...
+\end{verbatim}
+
+is the expansion of $\sqrt{11}$.
+
+\spadcommand{[i*i for i in convergents(z) :: Stream Float] }
+$$
+\begin{array}{@{}l}
+\left[
+{9.0}, {11.1111111111\ 11111111}, {10.9944598337\ 9501385}, 
+\right.
+\\
+\\
+\displaystyle
+{11.0002777777\ 77777778}, {10.9999860763\ 98799786}, 
+\\
+\\
+\displaystyle
+\left.
+{11.0000006979\ 29731039}, {10.9999999650\ 15834446}, \ldots 
+\right]
+\end{array}
+$$
+\returnType{Type: Stream Float}
+
+\section{CycleIndicators}
+\label{CycleIndicatorsXmpPage}
+
+This section is based upon the paper J. H. Redfield, ``The Theory of
+Group-Reduced Distributions'', American J. Math.,49 (1927) 433-455,
+and is an application of group theory to enumeration problems.  It is
+a development of the work by P. A. MacMahon on the application of
+symmetric functions and Hammond operators to combinatorial theory.
+
+The theory is based upon the power sum symmetric functions
+$s_i$ which are the sum of the $i$-th powers of the
+variables.  The cycle index of a permutation is an expression that
+specifies the sizes of the cycles of a permutation, and may be
+represented as a partition.  A partition of a non-negative integer
+{\tt n} is a collection of positive integers called its parts whose
+sum is {\tt n}.  For example, the partition $(3^2 \ 2 \ 1^2)$ will be
+used to represent $s^2_3 s_2 s^2_1$ and will indicate that the
+permutation has two cycles of length 3, one of length 2 and two of
+length 1.  The cycle index of a permutation group is the sum of the
+cycle indices of its permutations divided by the number of
+permutations.  The cycle indices of certain groups are provided.
+
+The operation {\tt complete} returns the cycle index of the
+symmetric group of order {\tt n} for argument {\tt n}.
+Alternatively, it is the $n$-th complete homogeneous symmetric
+function expressed in terms of power sum symmetric functions.
+
+\spadcommand{complete 1}
+$$
+\left(
+1 
+\right)
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+\spadcommand{complete 2}
+$$
+{{1 \over 2} \  {\left( 2 
+\right)}}+{{1
+\over 2} \  {\left( 1 \sp 2 
+\right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+\spadcommand{complete 3}
+$$
+{{1 \over 3} \  {\left( 3 
+\right)}}+{{1
+\over 2} \  {\left( {2 \sp {\ }} \  1 
+\right)}}+{{1
+\over 6} \  {\left( 1 \sp 3 
+\right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+\spadcommand{complete 7}
+$$
+\begin{array}{@{}l}
+{{1 \over 7} \  {\left( 7 \right)}}+
+{{1\over 6} \  {\left( {6 \sp {\ }} \  1 \right)}}+
+{{1\over {10}} \  {\left( {5 \sp {\ }} \  2 \right)}}+
+{{1\over {10}} \  {\left( {5 \sp {\ }} \  {1 \sp 2} \right)}}+
+{{1\over {12}} \  {\left( {4 \sp {\ }} \  3 \right)}}+
+{{1\over 8} \  {\left( {4 \sp {\ }} \  {2 \sp {\ }} \  1 \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {24}} \  {\left( {4 \sp {\ }} \  {1 \sp 3} \right)}}+
+{{1\over {18}} \  {\left( {3 \sp 2} \  1 \right)}}+
+{{1\over {24}} \  {\left( {3 \sp {\ }} \  {2 \sp 2} \right)}}+
+{{1\over {12}} \  {\left( {3 \sp {\ }} \  {2 \sp {\ }} \  {1 \sp 2} \right)}}+
+{{1\over {72}} \  {\left( {3 \sp {\ }} \  {1 \sp 4} \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {48}} \  {\left( {2 \sp 3} \  1 \right)}}+
+{{1\over {48}} \  {\left( {2 \sp 2} \  {1 \sp 3} \right)}}+
+{{1\over {240}} \  {\left( {2 \sp {\ }} \  {1 \sp 5} \right)}}+
+{{1\over {5040}} \  {\left( 1 \sp 7 \right)}}
+\end{array}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The operation {\tt elementary} computes the $n$-th
+elementary symmetric function for argument {\tt n.}
+
+\spadcommand{elementary 7}
+$$
+\begin{array}{@{}l}
+{{1 \over 7} \  {\left( 7 \right)}}
+-{{1 \over 6} \  {\left( {6 \sp {\ }} \  1 \right)}}
+-{{1 \over {10}} \  {\left( {5 \sp {\ }} \  2 \right)}}+
+{{1\over {10}} \  {\left( {5 \sp {\ }} \  {1 \sp 2} \right)}}
+-{{1 \over {12}} \  {\left( {4 \sp {\ }} \  3 \right)}}+
+{{1\over 8} \  {\left( {4 \sp {\ }} \  {2 \sp {\ }} \  1 \right)}}
+\\
+\\
+\displaystyle
+-{{1 \over {24}} \  {\left( {4 \sp {\ }} \  {1 \sp 3} \right)}}+
+{{1\over {18}} \  {\left( {3 \sp 2} \  1 \right)}}+
+{{1\over {24}} \  {\left( {3 \sp {\ }} \  {2 \sp 2} \right)}}
+-{{1 \over {12}} \  {\left( {3 \sp {\ }} \  {2 \sp {\ }} \  {1 \sp 2} \right)}}
++{{1\over {72}} \  {\left( {3 \sp {\ }} \  {1 \sp 4} \right)}}
+\\
+\\
+\displaystyle
+-{{1 \over {48}} \  {\left( {2 \sp 3} \  1 \right)}}+
+{{1\over {48}} \  {\left( {2 \sp 2} \  {1 \sp 3} \right)}}
+-{{1 \over {240}} \  {\left( {2 \sp {\ }} \  {1 \sp 5} \right)}}+
+{{1\over {5040}} \  {\left( 1 \sp 7 \right)}}
+\end{array}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The operation {\tt alternating} returns the cycle index of the alternating 
+group having an even number of even parts in each cycle partition.
+
+\spadcommand{alternating 7}
+$$
+\begin{array}{@{}l}
+{{2 \over 7} \  {\left( 7 \right)}}+
+{{1\over 5} \  {\left( {5 \sp {\ }} \  {1 \sp 2} \right)}}+
+{{1\over 4} \  {\left( {4 \sp {\ }} \  {2 \sp {\ }} \  1 \right)}}+
+{{1\over 9} \  {\left( {3 \sp 2} \  1 \right)}}+
+{{1\over {12}} \  {\left( {3 \sp {\ }} \  {2 \sp 2} \right)}}+
+{{1\over {36}} \  {\left( {3 \sp {\ }} \  {1 \sp 4} \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {24}} \  {\left( {2 \sp 2} \  {1 \sp 3} \right)}}+
+{{1\over {2520}} \  {\left( 1 \sp 7 \right)}}
+\end{array}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The operation {\tt cyclic} returns the cycle index of the cyclic group.
+
+\spadcommand{cyclic 7}
+$$
+{{6 \over 7} \  {\left( 7 \right)}}+
+{{1\over 7} \  {\left( 1 \sp 7 \right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The operation {\tt dihedral} is the cycle index of the
+dihedral group.
+
+\spadcommand{dihedral 7}
+$$
+{{3 \over 7} \  {\left( 7 \right)}}+
+{{1\over 2} \  {\left( {2 \sp 3} \  1 \right)}}+
+{{1\over {14}} \  {\left( 1 \sp 7 \right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The operation {\tt graphs} for argument {\tt n} returns the cycle
+index of the group of permutations on the edges of the complete graph
+with {\tt n} nodes induced by applying the symmetric group to the
+nodes.
+
+\spadcommand{graphs 5}
+$$
+\begin{array}{@{}l}
+{{1 \over 6} \  {\left( {6 \sp {\ }} \  {3 \sp {\ }} \  1 \right)}}+
+{{1\over 5} \  {\left( 5 \sp 2 \right)}}+
+{{1\over 4} \  {\left( {4 \sp 2} \  2 \right)}}+
+{{1\over 6} \  {\left( {3 \sp 3} \  1 \right)}}+
+{{1\over 8} \  {\left( {2 \sp 4} \  {1 \sp 2} \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {12}} \  {\left( {2 \sp 3} \  {1 \sp 4} \right)}}+
+{{1\over {120}} \  {\left( 1 \sp {10} \right)}}
+\end{array}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The cycle index of a direct product of two groups is the product of
+the cycle indices of the groups.  Redfield provided two operations on
+two cycle indices which will be called ``cup'' and ``cap'' here.  The
+{\tt cup} of two cycle indices is a kind of scalar product that
+combines monomials for permutations with the same cycles.  The {\tt
+cap} operation provides the sum of the coefficients of the result of
+the {\tt cup} operation which will be an integer that enumerates what
+Redfield called group-reduced distributions.
+
+We can, for example, represent {\tt complete 2 * complete 2} as the
+set of objects {\tt a a b b} and 
+{\tt complete 2 * complete 1 * complete 1} as {\tt c c d e.}
+
+This integer is the number of different sets of four pairs.
+
+\spadcommand{cap(complete 2**2, complete 2*complete 1**2)}
+$$
+4 
+$$
+\returnType{Type: Fraction Integer}
+
+For example,
+\begin{verbatim}
+a a b b     a a b b    a a b b   a a b b
+c c d e     c d c e    c e c d   d e c c
+\end{verbatim}
+
+This integer is the number of different sets of four pairs no two
+pairs being equal.
+
+\spadcommand{cap(elementary 2**2, complete 2*complete 1**2)}
+$$
+2 
+$$
+\returnType{Type: Fraction Integer}
+
+For example,
+\begin{verbatim}
+a a b b    a a b b
+c d c e    c e c d
+\end{verbatim}
+In this case the configurations enumerated are easily constructed,
+however the theory merely enumerates them providing little help in
+actually constructing them.
+
+Here are the number of 6-pairs, first from {\tt a a a b b c,} second
+from {\tt d d e e f g.}
+
+\spadcommand{cap(complete 3*complete 2*complete 1,complete 2**2*complete 1**2)}
+$$
+24 
+$$
+\returnType{Type: Fraction Integer}
+
+Here it is again, but with no equal pairs.
+
+\spadcommand{cap(elementary 3*elementary 2*elementary 1,complete 2**2*complete 1**2)}
+$$
+8 
+$$
+\returnType{Type: Fraction Integer}
+
+\spadcommand{cap(complete 3*complete 2*complete 1,elementary 2**2*elementary 1**2)}
+$$
+8 
+$$
+\returnType{Type: Fraction Integer}
+
+The number of 6-triples, first from {\tt a a a b b c,} second from
+{\tt d d e e f g,} third from {\tt h h i i j j.}
+
+\spadcommand{eval(cup(complete 3*complete 2*complete 1, cup(complete 2**2*complete 1**2,complete 2**3)))}
+$$
+1500 
+$$
+\returnType{Type: Fraction Integer}
+
+The cycle index of vertices of a square is dihedral 4.
+
+\spadcommand{square:=dihedral 4}
+$$
+{{1 \over 4} \  {\left( 4 \right)}}+
+{{3\over 8} \  {\left( 2 \sp 2 \right)}}+
+{{1\over 4} \  {\left( {2 \sp {\ }} \  {1 \sp 2} \right)}}+
+{{1\over 8} \  {\left( 1 \sp 4 \right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The number of different squares with 2 red vertices and 2 blue vertices.
+
+\spadcommand{cap(complete 2**2,square)}
+$$
+2 
+$$
+\returnType{Type: Fraction Integer}
+
+The number of necklaces with 3 red beads, 2 blue beads and 2 green beads.
+
+\spadcommand{cap(complete 3*complete 2**2,dihedral 7)}
+$$
+18 
+$$
+\returnType{Type: Fraction Integer}
+
+The number of graphs with 5 nodes and 7 edges.
+
+\spadcommand{cap(graphs 5,complete 7*complete 3)}
+$$
+4 
+$$
+\returnType{Type: Fraction Integer}
+
+The cycle index of rotations of vertices of a cube.
+
+\spadcommand{s(x) == powerSum(x)}
+\returnType{Type: Void}
+
+\spadcommand{cube:=(1/24)*(s 1**8+9*s 2**4 + 8*s 3**2*s 1**2+6*s 4**2)}
+\begin{verbatim}
+   Compiling function s with type PositiveInteger -> 
+      SymmetricPolynomial Fraction Integer 
+\end{verbatim}
+$$
+{{1 \over 4} \  {\left( 4 \sp 2 \right)}}+
+{{1\over 3} \  {\left( {3 \sp 2} \  {1 \sp 2} \right)}}+
+{{3\over 8} \  {\left( 2 \sp 4 \right)}}+
+{{1\over {24}} \  {\left( 1 \sp 8 \right)}}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+The number of cubes with 4 red vertices and 4 blue vertices.
+
+\spadcommand{cap(complete 4**2,cube)}
+$$
+7 
+$$
+\returnType{Type: Fraction Integer}
+
+The number of labeled graphs with degree sequence {\tt 2 2 2 1 1}
+with no loops or multiple edges.
+
+\spadcommand{cap(complete 2**3*complete 1**2,wreath(elementary 4,elementary 2))}
+$$
+7 
+$$
+\returnType{Type: Fraction Integer}
+
+Again, but with loops allowed but not multiple edges.
+
+\spadcommand{cap(complete 2**3*complete 1**2,wreath(elementary 4,complete 2))}
+$$
+17 
+$$
+\returnType{Type: Fraction Integer}
+
+Again, but with multiple edges allowed, but not loops
+
+\spadcommand{cap(complete 2**3*complete 1**2,wreath(complete 4,elementary 2))}
+$$
+10 
+$$
+\returnType{Type: Fraction Integer}
+
+Again, but with both multiple edges and loops allowed
+
+\spadcommand{cap(complete 2**3*complete 1**2,wreath(complete 4,complete 2))}
+$$
+23 
+$$
+\returnType{Type: Fraction Integer}
+
+Having constructed a cycle index for a configuration we are at liberty
+to evaluate the $s_i$ components any way we please.  For example we
+can produce enumerating generating functions.  This is done by
+providing a function {\tt f} on an integer {\tt i} to the value
+required of $s_i$, and then evaluating {\tt eval(f, cycleindex)}.
+
+\spadcommand{x: ULS(FRAC INT,'x,0) := 'x }
+$$
+x 
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+\spadcommand{ZeroOrOne: INT -> ULS(FRAC INT, 'x, 0) }
+\returnType{Type: Void}
+
+\spadcommand{Integers: INT -> ULS(FRAC INT, 'x, 0) }
+\returnType{Type: Void}
+
+For the integers 0 and 1, or two colors.
+
+\spadcommand{ZeroOrOne n == 1+x**n }
+\returnType{Type: Void}
+
+\spadcommand{ZeroOrOne 5 }
+\begin{verbatim}
+   Compiling function ZeroOrOne with type Integer -> 
+      UnivariateLaurentSeries(Fraction Integer,x,0) 
+\end{verbatim}
+$$
+1+{x \sp 5} 
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+For the integers {\tt 0, 1, 2, ...} we have this.
+
+\spadcommand{Integers n == 1/(1-x**n) }
+\returnType{Type: Void}
+
+\spadcommand{Integers 5 }
+\begin{verbatim}
+   Compiling function Integers with type Integer -> 
+      UnivariateLaurentSeries(Fraction Integer,x,0) 
+\end{verbatim}
+$$
+1+{x \sp 5}+{O 
+\left(
+{{x \sp 8}} 
+\right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of graphs with 5 nodes and {\tt n}
+edges. 
+
+Note that there is an eval function that takes two arguments. It has the 
+signature:
+\begin{verbatim}
+((Integer -> D1),SymmetricPolynomial Fraction Integer) -> D1
+  from EvaluateCycleIndicators D1 if D1 has ALGEBRA FRAC INT
+\end{verbatim}
+This function is not normally exposed (it will not normally be considered
+in the list of eval functions) as it is only useful for this particular
+domain. To use it we ask that it be considered thus:
+
+\spadcommand{)expose EVALCYC}
+
+and now we can use it:
+
+\spadcommand{eval(ZeroOrOne, graphs 5) }
+$$
+1+x+
+{2 \  {x \sp 2}}+
+{4 \  {x \sp 3}}+
+{6 \  {x \sp 4}}+
+{6 \  {x \sp 5}}+
+{6 \  {x \sp 6}}+
+{4 \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of necklaces with
+{\tt n} red beads and {\tt n-8} green beads.
+
+\spadcommand{eval(ZeroOrOne,dihedral 8) }
+$$
+1+x+
+{4 \  {x \sp 2}}+
+{5 \  {x \sp 3}}+
+{8 \  {x \sp 4}}+
+{5 \  {x \sp 5}}+
+{4 \  {x \sp 6}}+
+{x \sp 7}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of partitions of {\tt n} into 4
+or fewer parts.
+
+\spadcommand{eval(Integers,complete 4) }
+$$
+1+x+
+{2 \  {x \sp 2}}+
+{3 \  {x \sp 3}}+
+{5 \  {x \sp 4}}+
+{6 \  {x \sp 5}}+
+{9 \  {x \sp 6}}+
+{{11} \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of partitions of {\tt n} into 4
+boxes containing ordered distinct parts.
+
+\spadcommand{eval(Integers,elementary 4) }
+$$
+{x \sp 6}+
+{x \sp 7}+
+{2 \  {x \sp 8}}+
+{3 \  {x \sp 9}}+
+{5 \  {x \sp {10}}}+
+{6 \  {x \sp {11}}}+
+{9 \  {x \sp {12}}}+
+{{11} \  {x \sp {13}}}+
+{O \left({{x \sp {14}}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of different cubes with {\tt n}
+red vertices and {\tt 8-n} green ones.
+
+\spadcommand{eval(ZeroOrOne,cube) }
+$$
+1+x+
+{3 \  {x \sp 2}}+
+{3 \  {x \sp 3}}+
+{7 \  {x \sp 4}}+
+{3 \  {x \sp 5}}+
+{3 \  {x \sp 6}}+
+{x \sp 7}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of different cubes with integers
+on the vertices whose sum is {\tt n.}
+
+\spadcommand{eval(Integers,cube) }
+$$
+1+x+
+{4 \  {x \sp 2}}+
+{7 \  {x \sp 3}}+
+{{21} \  {x \sp 4}}+
+{{37} \  {x \sp 5}}+
+{{85} \  {x \sp 6}}+
+{{151} \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The coefficient of $x^n$ is the number of graphs with 5 nodes and with
+integers on the edges whose sum is {\tt n.}  In other words, the
+enumeration is of multigraphs with 5 nodes and {\tt n} edges.
+
+\spadcommand{eval(Integers,graphs 5) }
+$$
+1+x+
+{3 \  {x \sp 2}}+
+{7 \  {x \sp 3}}+
+{{17} \  {x \sp 4}}+
+{{35} \  {x \sp 5}}+
+{{76} \  {x \sp 6}}+
+{{149} \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+Graphs with 15 nodes enumerated with respect to number of edges.
+
+\spadcommand{eval(ZeroOrOne ,graphs 15) }
+$$
+1+x+
+{2 \  {x \sp 2}}+
+{5 \  {x \sp 3}}+
+{{11} \  {x \sp 4}}+
+{{26} \  {x \sp 5}}+
+{{68} \  {x \sp 6}}+
+{{177} \  {x \sp 7}}+
+{O \left({{x \sp 8}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+Necklaces with 7 green beads, 8 white beads, 5 yellow beads and 10
+red beads.
+
+\spadcommand{cap(dihedral 30,complete 7*complete 8*complete 5*complete 10)}
+$$
+49958972383320 
+$$
+\returnType{Type: Fraction Integer}
+
+The operation {\tt SFunction} is the S-function or Schur function of a
+partition written as a descending list of integers expressed in terms
+of power sum symmetric functions.
+
+In this case the argument partition represents a tableau shape.  For
+example {\tt 3,2,2,1} represents a tableau with three boxes in the
+first row, two boxes in the second and third rows, and one box in the
+fourth row.  {\tt SFunction [3,2,2,1]} counts the number of different
+tableaux of shape {\tt 3, 2, 2, 1} filled with objects with an
+ascending order in the columns and a non-descending order in the rows.
+
+\spadcommand{sf3221:= SFunction [3,2,2,1] }
+$$
+\begin{array}{@{}l}
+{{1 \over {12}} \  {\left( {6 \sp {\ }} \  2 \right)}}
+-{{1 \over {12}} \  {\left( {6 \sp {\ }} \  {1 \sp 2} \right)}}
+-{{1 \over {16}} \  {\left( 4 \sp 2 \right)}}+
+{{1\over {12}} \  {\left( {4 \sp {\ }} \  {3 \sp {\ }} \  1 \right)}}+
+{{1\over {24}} \  {\left( {4 \sp {\ }} \  {1 \sp 4} \right)}}
+-{{1 \over {36}} \  {\left( {3 \sp 2} \  2 \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {36}} \  {\left( {3 \sp 2} \  {1 \sp 2} \right)}}
+-{{1 \over {24}} \  {\left( {3 \sp {\ }} \  {2 \sp 2} \  1 \right)}}
+-{{1 \over {36}} \  {\left( {3 \sp {\ }} \  {2 \sp {\ }} \  {1 \sp 3} \right)}}
+-{{1 \over {72}} \  {\left( {3 \sp {\ }} \  {1 \sp 5} \right)}}
+-{{1 \over {192}} \  {\left( 2 \sp 4 \right)}}+
+\\
+\\
+\displaystyle
+{{1\over {48}} \  {\left( {2 \sp 3} \  {1 \sp 2} \right)}}+
+{{1\over {96}} \  {\left( {2 \sp 2} \  {1 \sp 4} \right)}}
+-{{1 \over {144}} \  {\left( {2 \sp {\ }} \  {1 \sp 6} \right)}}+
+{{1\over {576}} \  {\left( 1 \sp 8 \right)}}
+\end{array}
+$$
+\returnType{Type: SymmetricPolynomial Fraction Integer}
+
+This is the number filled with {\tt a a b b c c d d.}
+
+\spadcommand{cap(sf3221,complete 2**4) }
+$$
+3 
+$$
+\returnType{Type: Fraction Integer}
+
+The configurations enumerated above are:
+\begin{verbatim}
+a a b    a a c    a a d
+b c      b b      b b
+c d      c d      c c
+d        d        d
+\end{verbatim}
+
+This is the number of tableaux filled with {\tt 1..8.}
+
+\spadcommand{cap(sf3221, powerSum 1**8)}
+$$
+70 
+$$
+\returnType{Type: Fraction Integer}
+
+The coefficient of $x^n$ is the number of column strict reverse plane
+partitions of {\tt n} of shape {\tt 3 2 2 1.}
+
+\spadcommand{eval(Integers, sf3221)}
+$$
+{x \sp 9}+
+{3 \  {x \sp {10}}}+
+{7 \  {x \sp {11}}}+
+{{14} \  {x \sp {12}}}+
+{{27} \  {x \sp {13}}}+
+{{47} \  {x \sp {14}}}+
+{O \left({{x \sp {15}}} \right)}
+$$
+\returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)}
+
+The smallest is
+\begin{verbatim}
+0 0 0
+1 1
+2 2
+3
+\end{verbatim}
+
+\section{DeRhamComplex}
+\label{DeRhamComplexXmpPage}
+
+The domain constructor {\tt DeRhamComplex} creates the class of
+differential forms of arbitrary degree over a coefficient ring.  The
+De Rham complex constructor takes two arguments: a ring, {\tt
+coefRing,} and a list of coordinate variables.
+
+This is the ring of coefficients.
+
+\spadcommand{coefRing := Integer }
+$$
+Integer 
+$$
+\returnType{Type: Domain}
+
+These are the coordinate variables.
+
+\spadcommand{lv : List Symbol := [x,y,z] }
+$$
+\left[
+x, y, z 
+\right]
+$$
+\returnType{Type: List Symbol}
+
+This is the De Rham complex of Euclidean three-space using coordinates
+{\tt x, y} and {\tt z.}
+
+\spadcommand{der := DERHAM(coefRing,lv) }
+$$
+DeRhamComplex(Integer,[x,y,z]) 
+$$
+\returnType{Type: Domain}
+ 
+This complex allows us to describe differential forms having
+expressions of integers as coefficients.  These coefficients can
+involve any number of variables, for example, {\tt f(x,t,r,y,u,z).}
+As we've chosen to work with ordinary Euclidean three-space,
+expressions involving these forms are treated as functions of 
+{\tt x, y} and {\tt z} with the additional arguments {\tt t, r} 
+and {\tt u} regarded as symbolic constants.
+
+Here are some examples of coefficients.
+
+\spadcommand{R := Expression coefRing }
+$$
+\mbox{\rm Expression Integer} 
+$$
+\returnType{Type: Domain}
+
+\spadcommand{f : R := x**2*y*z-5*x**3*y**2*z**5 }
+$$
+-{5 \  {x \sp 3} \  {y \sp 2} \  {z \sp 5}}+{{x \sp 2} \  y \  z} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{g : R := z**2*y*cos(z)-7*sin(x**3*y**2)*z**2 }
+$$
+-{7 \  {z \sp 2} \  {\sin \left({{{x \sp 3} \  {y \sp 2}}} \right)}}+
+{y\  {z \sp 2} \  {\cos \left({z} \right)}}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{h : R :=x*y*z-2*x**3*y*z**2 }
+$$
+-{2 \  {x \sp 3} \  y \  {z \sp 2}}+{x \  y \  z} 
+$$
+\returnType{Type: Expression Integer}
+
+We now define the multiplicative basis elements for the exterior
+algebra over {\tt R}.
+
+\spadcommand{dx : der := generator(1) }
+$$
+dx 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+\spadcommand{dy : der := generator(2)}
+$$
+dy 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+\spadcommand{dz : der := generator(3)}
+$$
+dz 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+This is an alternative way to give the above assignments.
+
+\spadcommand{[dx,dy,dz] := [generator(i)\$der for i in 1..3] }
+$$
+\left[
+dx, dy, dz 
+\right]
+$$
+\returnType{Type: List DeRhamComplex(Integer,[x,y,z])}
+
+Now we define some one-forms.
+
+\spadcommand{alpha : der := f*dx + g*dy + h*dz }
+$$
+\begin{array}{@{}l}
+{{\left( -{2 \  {x \sp 3} \  y \  {z \sp 2}}+{x \  y \  z} \right)}\  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+-{7 \  {z \sp 2} \  {\sin \left({{{x \sp 3} \  {y \sp 2}}} \right)}}+
+{y\  {z \sp 2} \  {\cos \left({z} \right)}}
+\right)}\  dy}+
+\\
+\\
+\displaystyle
+{{\left( -{5 \  {x \sp 3} \  {y \sp 2} \  {z \sp 5}}+{{x \sp 2} \  y \  z} 
+\right)}\  dx} 
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+\spadcommand{beta  : der := cos(tan(x*y*z)+x*y*z)*dx + x*dy }
+$$
+{x \  dy}+
+{{\cos 
+\left({{{\tan \left({{x \  y \  z}} \right)}+{x\  y \  z}}} \right)}
+\  dx} 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+A well-known theorem states that the composition of
+\spadfunFrom{exteriorDifferential}{DeRhamComplex} with itself is the
+zero map for continuous forms.  Let's verify this theorem for {\tt alpha}.
+
+\spadcommand{exteriorDifferential alpha }
+$$
+\begin{array}{@{}l}
+{{\left( 
+{y \  {z \sp 2} \  {\sin \left({z} \right)}}+
+{{14}\  z \  {\sin \left({{{x \sp 3} \  {y \sp 2}}} \right)}}
+-{2 \  y \  z \  {\cos \left({z} \right)}}
+-{2 \  {x \sp 3} \  {z \sp 2}}+{x \  z} \right)}\  dy \  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+{{25} \  {x \sp 3} \  {y \sp 2} \  {z \sp 4}} -
+{6 \  {x \sp 2} \  y \  {z \sp 2}}+
+{y \  z} -
+{{x \sp 2} \  y} 
+\right)}\  dx \  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+-{{21} \  {x \sp 2} \  {y \sp 2} \  {z \sp 2} \  
+{\cos \left({{{x \sp 3} \  {y \sp 2}}} \right)}}+
+{{10}\  {x \sp 3} \  y \  {z \sp 5}} -{{x \sp 2} \  z} \right)}\  dx \  dy} 
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+We see a lengthy output of the last expression, but nevertheless, the
+composition is zero.
+
+\spadcommand{exteriorDifferential \% }
+$$
+0 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+Now we check that \spadfunFrom{exteriorDifferential}{DeRhamComplex}
+is a ``graded derivation'' {\tt D,} that is, {\tt D} satisfies:
+\begin{verbatim}
+D(a*b) = D(a)*b + (-1)**degree(a)*a*D(b)
+\end{verbatim}
+
+\spadcommand{gamma := alpha * beta }
+$$
+\begin{array}{@{}l}
+{{\left( 
+{2 \  {x \sp 4} \  y \  {z \sp 2}} -
+{{x \sp 2} \  y \  z} 
+\right)}\  dy \  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+{2 \  {x \sp 3} \  y \  {z \sp 2}} -{x \  y \  z} 
+\right)}
+\  {\cos 
+\left(
+{{{\tan \left({{x \  y \  z}} \right)}+
+{x\  y \  z}}} 
+\right)}\  dx \  dz}+
+\\
+\\
+\displaystyle
+\left( 
+{{\left( 
+{7 \  {z \sp 2} \  {\sin \left({{{x \sp 3} \  {y \sp 2}}} \right)}}
+-{y \  {z \sp 2} \  {\cos \left({z} \right)}}
+\right)}
+\  {\cos \left({{{\tan \left({{x \  y \  z}} \right)}+{x\  y \  z}}} \right)}}-
+\right.
+\\
+\\
+\left.
+\displaystyle
+{5 \  {x \sp 4} \  {y \sp 2} \  {z \sp 5}}+
+{{x \sp 3} \  y \  z} 
+\right)\  dx \  dy
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+We try this for the one-forms {\tt alpha} and {\tt beta}.
+
+\spadcommand{exteriorDifferential(gamma) - (exteriorDifferential(alpha)*beta - alpha * exteriorDifferential(beta)) }
+$$
+0 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+Now we define some ``basic operators'' (see 
+\ref{OperatorXmpPage} on page~\pageref{OperatorXmpPage}).
+
+\spadcommand{a : BOP := operator('a) }
+$$
+a 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{b : BOP := operator('b) }
+$$
+b 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{c : BOP := operator('c) }
+$$
+c 
+$$
+\returnType{Type: BasicOperator}
+
+We also define some indeterminate one- and two-forms using these
+operators.
+
+\spadcommand{sigma := a(x,y,z) * dx + b(x,y,z) * dy + c(x,y,z) * dz }
+$$
+{{c \left({x, y, z} \right)}\  dz}+
+{{b \left({x, y, z} \right)}\  dy}+
+{{a \left({x, y, z} \right)}\  dx} 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+\spadcommand{theta  := a(x,y,z) * dx * dy + b(x,y,z) * dx * dz + c(x,y,z) * dy * dz }
+$$
+{{c \left({x, y, z} \right)}\  dy \  dz}+
+{{b \left({x, y, z} \right)}\  dx \  dz}+
+{{a \left({x, y, z} \right)}\  dx \  dy} 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+This allows us to get formal definitions for the ``gradient'' \ldots
+
+\spadcommand{totalDifferential(a(x,y,z))\$der }
+$$
+{{{a \sb {{,3}}} \left({x, y, z} \right)}\  dz}+
+{{{a \sb {{,2}}} \left({x, y, z} \right)}\  dy}+
+{{{a \sb {{,1}}} \left({x, y, z} \right)}\  dx} 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+the ``curl'' \ldots
+
+\spadcommand{exteriorDifferential sigma }
+$$
+\begin{array}{@{}l}
+{{\left( 
+{{c \sb {{,2}}} \left({x, y, z} \right)}
+-{{b \sb {{,3}}} \left({x, y, z} \right)}
+\right)}\  dy \  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+{{c \sb {{,1}}} \left({x, y, z} \right)}
+-{{a \sb {{,3}}} \left({x, y, z} \right)}
+\right)}\  dx \  dz}+
+\\
+\\
+\displaystyle
+{{\left( 
+{{b \sb {{,1}}} \left({x, y, z} \right)}
+-{{a \sb {{,2}}} \left({x, y, z} \right)}
+\right)}\  dx \  dy} 
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+and the ``divergence.''
+
+\spadcommand{exteriorDifferential theta }
+$$
+{\left( 
+{{c \sb {{,1}}} \left({x, y, z} \right)}
+-{{b \sb {{,2}}} \left({x, y, z} \right)}+
+{{a\sb {{,3}}} \left({x, y, z} \right)}
+\right)}\  dx \  dy \  dz 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+Note that the De Rham complex is an algebra with unity.  This element
+{\tt 1} is the basis for elements for zero-forms, that is, functions
+in our space.
+
+\spadcommand{one : der := 1 }
+$$
+1 
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+To convert a function to a function lying in the De Rham complex,
+multiply the function by ``one.''
+
+\spadcommand{g1 : der := a([x,t,y,u,v,z,e]) * one }
+$$
+a 
+\left(
+{x, t, y, u, v, z, e} 
+\right)
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+A current limitation of Axiom forces you to write functions with more
+than four arguments using square brackets in this way.
+
+\spadcommand{h1 : der := a([x,y,x,t,x,z,y,r,u,x]) * one }
+$$
+a 
+\left(
+{x, y, x, t, x, z, y, r, u, x} 
+\right)
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+Now note how the system keeps track of where your coordinate functions
+are located in expressions.
+
+\spadcommand{exteriorDifferential g1 }
+$$
+\begin{array}{@{}l}
+{{{a \sb {{,6}}} \left({x, t, y, u, v, z, e} \right)}\  dz}+
+\\
+\\
+\displaystyle
+{{{a \sb {{,3}}} \left({x, t, y, u, v, z, e} \right)}\  dy}+
+\\
+\\
+\displaystyle
+{{{a \sb {{,1}}} \left({x, t, y, u, v, z, e} \right)}\  dx} 
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+\spadcommand{exteriorDifferential h1 }
+$$
+\begin{array}{@{}l}
+{{{a \sb {{,6}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}\  dz}+
+\\
+\\
+\displaystyle
+\begin{array}{@{}l}
+\left( {{a \sb {{,7}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}+
+\right.
+\\
+\\
+\displaystyle
+\left.
+{{a\sb {{,2}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}
+\right)\  dy+
+\end{array}
+\\
+\\
+\displaystyle
+\begin{array}{@{}l}
+\left( {{a \sb {{,{10}}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}+
+\right.
+\\
+\\
+\displaystyle
+{{a\sb {{,5}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}+
+\\
+\\
+\displaystyle
+{{a\sb {{,3}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}+
+\\
+\\
+\displaystyle
+\left.
+{{a\sb {{,1}}} 
+\left({x, y, x, t, x, z, y, r, u, x} \right)}
+\right)\  dx 
+\end{array}
+\end{array}
+$$
+\returnType{Type: DeRhamComplex(Integer,[x,y,z])}
+
+In this example of Euclidean three-space, the basis for the De Rham complex
+consists of the eight forms: {\tt 1}, {\tt dx}, {\tt dy}, {\tt dz},
+{\tt dx*dy}, {\tt dx*dz}, {\tt dy*dz}, and {\tt dx*dy*dz}.
+
+\spadcommand{coefficient(gamma, dx*dy) }
+$$
+\begin{array}{@{}l}
+{{\left( {7 \  {z \sp 2} \  {\sin \left({{{x \sp 3} \  {y \sp 2}}} \right)}}
+-{y \  {z \sp 2} \  {\cos \left({z} \right)}}\right)}\  {\cos 
+\left(
+{{{\tan \left({{x \  y \  z}} \right)}+
+{x\  y \  z}}} 
+\right)}}
+\\
+\\
+\displaystyle
+-{5 \  {x \sp 4} \  {y \sp 2} \  {z \sp 5}}+
+{{x \sp 3} \  y \  z} 
+\end{array}
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{coefficient(gamma, one) }
+$$
+0 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{coefficient(g1,one) }
+$$
+a 
+\left(
+{x, t, y, u, v, z, e} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+\section{DecimalExpansion}
+\label{DecimalExpansionXmpPage}
+
+All rationals have repeating decimal expansions.  Operations to access
+the individual digits of a decimal expansion can be obtained by
+converting the value to {\tt RadixExpansion(10)}.  More examples of
+expansions are available in 
+\ref{BinaryExpansionXmpPage} on page~\pageref{BinaryExpansionXmpPage},
+\ref{HexadecimalExpansionXmpPage} on 
+page~\pageref{HexadecimalExpansionXmpPage}, and 
+\ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}.
+
+The operation \spadfunFrom{decimal}{DecimalExpansion} is used to create
+this expansion of type {\tt DecimalExpansion}.
+
+\spadcommand{r := decimal(22/7) }
+$$
+3.{\overline {142857}} 
+$$
+\returnType{Type: DecimalExpansion}
+
+Arithmetic is exact.
+
+\spadcommand{r + decimal(6/7) }
+$$
+4 
+$$
+\returnType{Type: DecimalExpansion}
+
+The period of the expansion can be short or long \ldots
+
+\spadcommand{[decimal(1/i) for i in 350..354] }
+$$
+\begin{array}{@{}l}
+\left[
+{0.{00}{\overline {285714}}}, 
+{0.{\overline {002849}}}, 
+{0.{00284}{\overline {09}}}, 
+{0.{\overline {00283286118980169971671388101983}}}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{0.0{\overline {0282485875706214689265536723163841807909604519774011299435}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List DecimalExpansion}
+
+or very long.
+
+\spadcommand{decimal(1/2049) }
+$$
+\begin{array}{@{}l}
+0.{\overline 
+{000488042947779404587603709126403123474865788189360663738408979990239}}
+\\
+\\
+\displaystyle
+\ \ {\overline{
+141044411908247925817471937530502684236212786725231820400195217179111}}
+\\
+\\
+\displaystyle
+\ \ {\overline{
+761835041483650561249389946315275744265495363591996095656417764763299}}
+\\
+\\
+\displaystyle
+\ \ {\overline{
+170326988775012201073694485114690092728160078086871644704734016593460}}
+\\
+\\
+\displaystyle
+\ \ {\overline{
+22449975597852611029770619814543679843826256710590531966813079551}}
+\end{array}
+$$
+\returnType{Type: DecimalExpansion}
+
+These numbers are bona fide algebraic objects.
+
+\spadcommand{p := decimal(1/4)*x**2 + decimal(2/3)*x + decimal(4/9)  }
+$$
+{{0.{25}} \  {x \sp 2}}+{{0.{\overline 6}} \  x}+{0.{\overline 4}} 
+$$
+\returnType{Type: Polynomial DecimalExpansion}
+
+\spadcommand{q := differentiate(p, x) }
+$$
+{{0.5} \  x}+{0.{\overline 6}} 
+$$
+\returnType{Type: Polynomial DecimalExpansion}
+
+\spadcommand{g := gcd(p, q) }
+$$
+x+{1.{\overline 3}} 
+$$
+\returnType{Type: Polynomial DecimalExpansion}
+
+\section{DistributedMultivariatePolynomial}
+\label{DistributedMultivariatePolynomialXmpPage}
+
+\hyphenation{Homo-gen-eous-Dis-tributed-Multi-var-i-ate-Pol-y-nomial}
+
+{\tt DistributedMultivariatePolynomial} which is abbreviated as {\tt DMP}
+and {\tt HomogeneousDistributedMultivariatePolynomial}, which is abbreviated
+as {\tt HDMP}, are very similar to {\tt MultivariatePolynomial} except that 
+they are represented and displayed in a non-recursive manner.
+
+\spadcommand{(d1,d2,d3) : DMP([z,y,x],FRAC INT) }
+\returnType{Type: Void}
+
+The constructor {\tt DMP} orders its monomials lexicographically while
+{\tt HDMP} orders them by total order refined by reverse lexicographic
+order.
+
+\spadcommand{d1 := -4*z + 4*y**2*x + 16*x**2 + 1 }
+$$
+-{4 \  z}+{4 \  {y \sp 2} \  x}+{{16} \  {x \sp 2}}+1 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+\spadcommand{d2 := 2*z*y**2 + 4*x + 1 }
+$$
+{2 \  z \  {y \sp 2}}+{4 \  x}+1 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+\spadcommand{d3 := 2*z*x**2 - 2*y**2 - x }
+$$
+{2 \  z \  {x \sp 2}} -{2 \  {y \sp 2}} -x 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+These constructors are mostly used in Gr\"{o}bner basis calculations.
+
+\spadcommand{groebner [d1,d2,d3] }
+$$
+\begin{array}{@{}l}
+\left[
+{z -
+{{{1568} \over {2745}} \  {x \sp 6}} -
+{{{1264} \over {305}} \  {x \sp 5}}+
+{{6 \over {305}} \  {x \sp 4}}+
+{{{182} \over {549}} \  {x \sp 3}} 
+-{{{2047} \over {610}} \  {x \sp 2}} -
+{{{103} \over {2745}} \  x} -
+{{2857} \over {10980}}}, 
+\right.
+\\
+\\
+\displaystyle
+{{y \sp 2}+
+{{{112} \over {2745}} \  {x \sp 6}} -
+{{{84} \over {305}} \  {x \sp 5}} -
+{{{1264} \over {305}} \  {x \sp 4}} -
+{{{13} \over {549}} \  {x \sp 3}}+
+{{{84} \over {305}} \  {x \sp 2}}+
+{{{1772} \over {2745}} \  x}+
+{2 \over {2745}}}, 
+\\
+\\
+\displaystyle
+\left.
+{{x \sp 7}+
+{{{29} \over 4} \  {x \sp 6}} -
+{{{17} \over {16}} \  {x \sp 4}} -
+{{{11} \over 8} \  {x \sp 3}}+
+{{1 \over {32}} \  {x \sp 2}}+
+{{{15} \over {16}} \  x}+
+{1 \over 4}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List DistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+\spadcommand{(n1,n2,n3) : HDMP([z,y,x],FRAC INT) }
+\returnType{Type: Void}
+
+\spadcommand{n1 := d1 }
+$$
+{4 \  {y \sp 2} \  x}+{{16} \  {x \sp 2}} -{4 \  z}+1 
+$$
+\returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+\spadcommand{n2 := d2 }
+$$
+{2 \  z \  {y \sp 2}}+{4 \  x}+1 
+$$
+\returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+\spadcommand{n3 := d3 }
+$$
+{2 \  z \  {x \sp 2}} -{2 \  {y \sp 2}} -x 
+$$
+\returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+Note that we get a different Gr\"{o}bner basis when we use the 
+{\tt HDMP} polynomials, as expected.
+
+\spadcommand{groebner [n1,n2,n3] }
+$$
+\begin{array}{@{}l}
+\left[
+{{y \sp 4}+
+{2 \  {x \sp 3}} -
+{{3 \over 2} \  {x \sp 2}}+
+{{1 \over 2} \  z} -
+{1 \over 8}}, 
+\right.
+\\
+\\
+\displaystyle
+{{x \sp 4}+
+{{{29} \over 4} \  {x \sp 3}} -
+{{1 \over 8} \  {y \sp 2}} -
+{{7 \over 4} \  z \  x} -
+{{9 \over {16}} \  x} -
+{1 \over 4}}, 
+\\
+\\
+\displaystyle
+{{z \  {y \sp 2}}+
+{2 \  x}+
+{1 \over 2}}, 
+\\
+\\
+\displaystyle
+{{{y \sp 2} \  x}+
+{4 \  {x \sp 2}} -
+z+
+{1 \over 4}},
+\\
+\\
+\displaystyle
+{{z \  {x \sp 2}} -
+{y \sp 2} -
+{{1 \over 2} \  x}},
+\\
+\\
+\displaystyle
+\left.
+{{z \sp 2} -
+{4 \  {y \sp 2}}+
+{2 \  {x \sp 2}} -
+{{1 \over 4} \  z} -
+{{3 \over 2} \  x}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)}
+
+{\tt GeneralDistributedMultivariatePolynomial} is somewhat
+more flexible in the sense that as well as accepting a list of
+variables to specify the variable ordering, it also takes a
+predicate on exponent vectors to specify the term ordering.
+With this polynomial type the user can experiment with the effect
+of using completely arbitrary term orderings.
+This flexibility is mostly important for algorithms such as
+Gr\"{o}bner basis calculations which can be very
+sensitive to term ordering.
+
+For more information on related topics, see
+\ref{ugIntroVariablesPage} on page~\pageref{ugIntroVariablesPage} in Section 
+\ref{ugIntroVariablesNumber} on page~\pageref{ugIntroVariablesNumber},
+\ref{ugTypesConvertPage} on page~\pageref{ugTypesConvertPage} in Section 
+\ref{ugTypesConvertNumber} on page~\pageref{ugTypesConvertNumber},
+\ref{PolynomialXmpPage} on page~\pageref{PolynomialXmpPage},
+\ref{UnivariatePolynomialXmpPage} on 
+page~\pageref{UnivariatePolynomialXmpPage}, and
+\ref{MultivariatePolynomialXmpPage} on 
+page~\pageref{MultivariatePolynomialXmpPage}.
+
+\section{DoubleFloat}
+\label{DoubleFloatXmpPage}
+
+Axiom provides two kinds of floating point numbers.  The domain 
+{\tt Float} (abbreviation {\tt FLOAT}) implements a model of arbitrary
+precision floating point numbers.  The domain {\tt DoubleFloat}
+(abbreviation {\tt DFLOAT}) is intended to make available hardware
+floating point arithmetic in Axiom.  The actual model of floating
+point {\tt DoubleFloat} that provides is system-dependent.  For
+example, on the IBM system 370 Axiom uses IBM double precision which
+has fourteen hexadecimal digits of precision or roughly sixteen
+decimal digits.  Arbitrary precision floats allow the user to specify
+the precision at which arithmetic operations are computed.  Although
+this is an attractive facility, it comes at a cost. Arbitrary-precision 
+floating-point arithmetic typically takes twenty to two hundred times 
+more time than hardware floating point.
+
+The usual arithmetic and elementary functions are available for 
+{\tt DoubleFloat}.  Use {\tt )show DoubleFloat} to get a list of operations
+or the HyperDoc browse facility to get more extensive documentation
+about {\tt DoubleFloat}.
+
+By default, floating point numbers that you enter into Axiom are of
+type {\tt Float}.
+
+\spadcommand{2.71828}
+$$
+2.71828 
+$$
+\returnType{Type: Float}
+
+You must therefore tell Axiom that you want to use {\tt DoubleFloat}
+values and operations.  The following are some conservative guidelines
+for getting Axiom to use {\tt DoubleFloat}.
+
+To get a value of type {\tt DoubleFloat}, use a target with {\tt @}, \ldots
+
+\spadcommand{2.71828@DoubleFloat}
+$$
+2.71828 
+$$
+\returnType{Type: DoubleFloat}
+
+a conversion, \ldots
+
+\spadcommand{2.71828 :: DoubleFloat}
+$$
+2.71828 
+$$
+\returnType{Type: DoubleFloat}
+
+or an assignment to a declared variable.  It is more efficient if you
+use a target rather than an explicit or implicit conversion.
+
+\spadcommand{eApprox : DoubleFloat := 2.71828 }
+$$
+2.71828 
+$$
+\returnType{Type: DoubleFloat}
+
+You also need to declare functions that work with {\tt DoubleFloat}.
+
+\spadcommand{avg : List DoubleFloat -> DoubleFloat }
+\returnType{Type: Void}
+
+\begin{verbatim}
+avg l ==
+  empty? l => 0 :: DoubleFloat
+  reduce(_+,l) / #l
+\end{verbatim}
+\returnType{Type: Void}
+
+%\spadcommand{avg [] }
+% this complains but succeeds
+
+\spadcommand{avg [3.4,9.7,-6.8] }
+\begin{verbatim}
+   Compiling function avg with type List Float -> DoubleFloat 
+
+\end{verbatim}
+$$
+2.1 
+$$
+\returnType{Type: DoubleFloat}
+
+Use package-calling for operations from {\tt DoubleFloat} unless
+the arguments themselves are already of type {\tt DoubleFloat}.
+
+\spadcommand{cos(3.1415926)\$DoubleFloat}
+$$
+-{0.999999999999999} 
+$$
+\returnType{Type: DoubleFloat}
+
+\spadcommand{cos(3.1415926 :: DoubleFloat)}
+$$
+-{0.999999999999999} 
+$$
+\returnType{Type: DoubleFloat}
+
+By far, the most common usage of {\tt DoubleFloat} is for functions to
+be graphed.  For more information about Axiom's numerical and
+graphical facilities, see Section
+\ref{ugGraph} on page~\pageref{ugGraph}, 
+\ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}, and 
+\ref{FloatXmpPage} on page~\pageref{FloatXmpPage}.
+
+\section{EqTable} 
+\label{EqTableXmpPage}
+
+The {\tt EqTable} domain provides tables where the keys are compared
+using \spadfunFrom{eq?}{EqTable}.  Keys are considered equal only if
+they are the same instance of a structure.  This is useful if the keys
+are themselves updatable structures.  Otherwise, all operations are
+the same as for type {\tt Table}.  See 
+\ref{TableXmpPage} on page~\pageref{TableXmpPage} for general
+information about tables.
+
+The operation \spadfunFrom{table}{EqTable} is here used to create a table
+where the keys are lists of integers.
+
+\spadcommand{e: EqTable(List Integer, Integer) := table() }
+$$
+table() 
+$$
+\returnType{Type: EqTable(List Integer,Integer)}
+
+These two lists are equal according to \spadopFrom{=}{List}, but not
+according to \spadfunFrom{eq?}{List}.
+
+\spadcommand{l1 := [1,2,3] }
+$$
+\left[
+1, 2, 3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+\spadcommand{l2 := [1,2,3] }
+$$
+\left[
+1, 2, 3 
+\right]
+$$
+\returnType{Type: List PositiveInteger}
+
+Because the two lists are not \spadfunFrom{eq?}{List}, separate values
+can be stored under each.
+
+\spadcommand{e.l1 := 111    }
+$$
+111 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{e.l2 := 222    }
+$$
+222 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{e.l1}
+$$
+111 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{Equation}
+\label{EquationXmpPage}
+
+The {\tt Equation} domain provides equations as mathematical objects.
+These are used, for example, as the input to various
+\spadfunFrom{solve}{TransSolvePackage} operations.
+
+Equations are created using the equals symbol, \spadopFrom{=}{Equation}.
+
+\spadcommand{eq1 := 3*x + 4*y = 5 }
+$$
+{{4 \  y}+{3 \  x}}=5 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+\spadcommand{eq2 := 2*x + 2*y = 3 }
+$$
+{{2 \  y}+{2 \  x}}=3 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+The left- and right-hand sides of an equation are accessible using
+the operations \spadfunFrom{lhs}{Equation} and \spadfunFrom{rhs}{Equation}.
+
+\spadcommand{lhs eq1 }
+$$
+{4 \  y}+{3 \  x} 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{rhs eq1 }
+$$
+5 
+$$
+\returnType{Type: Polynomial Integer}
+
+Arithmetic operations are supported and operate on both sides of the
+equation.
+
+\spadcommand{eq1 + eq2   }
+$$
+{{6 \  y}+{5 \  x}}=8 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+\spadcommand{eq1 * eq2   }
+$$
+{{8 \  {y \sp 2}}+{{14} \  x \  y}+{6 \  {x \sp 2}}}={15} 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+\spadcommand{2*eq2 - eq1 }
+$$
+x=1 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+Equations may be created for any type so the arithmetic operations
+will be defined only when they make sense.  For example, exponentiation 
+is not defined for equations involving non-square matrices.
+
+\spadcommand{eq1**2 }
+$$
+{{{16} \  {y \sp 2}}+{{24} \  x \  y}+{9 \  {x \sp 2}}}={25} 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+Note that an equals symbol is also used to {\it test} for equality of
+values in certain contexts.  For example, {\tt x+1} and {\tt y} are
+unequal as polynomials.
+
+\spadcommand{if x+1 = y then "equal" else "unequal"}
+$$
+\mbox{\tt "unequal"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{eqpol := x+1 = y }
+$$
+{x+1}=y 
+$$
+\returnType{Type: Equation Polynomial Integer}
+
+If an equation is used where a {\tt Boolean} value is required, then
+it is evaluated using the equality test from the operand type.
+
+\spadcommand{if eqpol then "equal" else "unequal" }
+$$
+\mbox{\tt "unequal"} 
+$$
+\returnType{Type: String}
+
+If one wants a {\tt Boolean} value rather than an equation, all one
+has to do is ask!
+
+\spadcommand{eqpol::Boolean }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\section{Exit}
+\label{ExitXmpPage}
+
+A function that does not return directly to its caller has {\tt Exit}
+as its return type.  The operation {\tt error} is an example of one
+which does not return to its caller.  Instead, it causes a return to
+top-level.
+
+\spadcommand{n := 0 }
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+The function {\tt gasp} is given return type {\tt Exit} since it is
+guaranteed never to return a value to its caller.
+
+\begin{verbatim}
+gasp(): Exit ==
+    free n
+    n := n + 1
+    error "Oh no!"
+ 
+Function declaration gasp : () -> Exit has been added to workspace.
+
+\end{verbatim}
+\returnType{Type: Void}
+
+The return type of {\tt half} is determined by resolving the types of
+the two branches of the {\tt if}.
+
+\begin{verbatim}
+half(k) ==
+  if odd? k then gasp()
+  else k quo 2
+\end{verbatim}
+
+Because {\tt gasp} has the return type {\tt Exit}, the type of 
+{\tt if} in {\tt half} is resolved to be {\tt Integer}.
+
+\spadcommand{half 4 }
+\begin{verbatim}
+   Compiling function gasp with type () -> Exit 
+   Compiling function half with type PositiveInteger -> Integer 
+\end{verbatim}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{half 3 }
+\begin{verbatim}
+   Error signalled from user code in function gasp: 
+      Oh no!
+\end{verbatim}
+
+\spadcommand{n }
+$$
+1 
+$$
+\returnType{Type: NonNegativeInteger}
+
+For functions which return no value at all, use {\tt Void}.  See
+\ref{ugUserPage} on page~\pageref{ugUserPage} in Section 
+\ref{ugUserNumber} on page~\pageref{ugUserNumber} and 
+\ref{VoidXmpPage} on page~\pageref{VoidXmpPage} for
+more information.
+
+\section{Expression}
+\label{ExpressionXmpPage}
+
+{\tt Expression} is a constructor that creates domains whose objects
+can have very general symbolic forms.  Here are some examples:
+
+This is an object of type {\tt Expression Integer}.
+
+\spadcommand{sin(x) + 3*cos(x)**2}
+$$
+{\sin \left({x} \right)}+{3\  {{\cos \left({x} \right)}\sp 2}} 
+$$
+\returnType{Type: Expression Integer}
+
+This is an object of type {\tt Expression Float}.
+
+\spadcommand{tan(x) - 3.45*x}
+$$
+{\tan \left({x} \right)}-{{3.45} \  x} 
+$$
+\returnType{Type: Expression Float}
+
+This object contains symbolic function applications, sums,
+products, square roots, and a quotient.
+
+\spadcommand{(tan sqrt 7 - sin sqrt 11)**2 / (4 - cos(x - y))}
+$$
+{-{{\tan \left({{\sqrt {7}}} \right)}\sp 2}+
+{2 \  {\sin \left({{\sqrt {{11}}}} \right)}
+\  {\tan \left({{\sqrt {7}}} \right)}}
+-{{\sin \left({{\sqrt {{11}}}} \right)}\sp 2}} 
+\over {{\cos \left({{y -x}} \right)}
+-4} 
+$$
+\returnType{Type: Expression Integer}
+
+As you can see, {\tt Expression} actually takes an argument domain.
+The {\it coefficients} of the terms within the expression belong to
+the argument domain.  {\tt Integer} and {\tt Float}, along with 
+{\tt Complex Integer} and {\tt Complex Float} are the most common
+coefficient domains.
+
+The choice of whether to use a {\tt Complex} coefficient domain or not
+is important since Axiom can perform some simplifications on
+real-valued objects
+
+\spadcommand{log(exp  x)@Expression(Integer)} 
+$$
+x 
+$$
+\returnType{Type: Expression Integer}
+
+... which are not valid on complex ones.
+
+\spadcommand{log(exp  x)@Expression(Complex Integer)} 
+$$
+\log \left({{e \sp x}} \right)
+$$
+\returnType{Type: Expression Complex Integer}
+
+Many potential coefficient domains, such as {\tt AlgebraicNumber}, are
+not usually used because {\tt Expression} can subsume them.
+
+\spadcommand{sqrt 3 + sqrt(2 + sqrt(-5)) }
+$$
+{\sqrt {{{\sqrt {-5}}+2}}}+{\sqrt {3}} 
+$$
+\returnType{Type: AlgebraicNumber}
+
+\spadcommand{\% :: Expression Integer }
+$$
+{\sqrt {{{\sqrt {-5}}+2}}}+{\sqrt {3}} 
+$$
+\returnType{Type: Expression Integer}
+
+Note that we sometimes talk about ``an object of type {\tt
+Expression}.'' This is not really correct because we should say, for
+example, ``an object of type {\tt Expression Integer}'' or ``an object
+of type {\tt Expression Float}.''  By a similar abuse of language,
+when we refer to an ``expression'' in this section we will mean an
+object of type {\tt Expression R} for some domain {\tt R}.
+
+The Axiom documentation contains many examples of the use of {\tt
+Expression}.  For the rest of this section, we'll give you some
+pointers to those examples plus give you some idea of how to
+manipulate expressions.
+
+It is important for you to know that {\tt Expression} creates domains
+that have category {\tt Field}.  Thus you can invert any non-zero
+expression and you shouldn't expect an operation like {\tt factor} to
+give you much information.  You can imagine expressions as being
+represented as quotients of ``multivariate'' polynomials where the
+``variables'' are kernels (see 
+\ref{KernelXmpPage} on page~\pageref{KernelXmpPage}).  A kernel can
+either be a symbol such as {\tt x} or a symbolic function application
+like {\tt sin(x + 4)}.  The second example is actually a nested kernel
+since the argument to {\tt sin} contains the kernel {\tt x}.
+
+\spadcommand{height mainKernel sin(x + 4)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+Actually, the argument to {\tt sin} is an expression, and so the
+structure of {\tt Expression} is recursive.  
+\ref{KernelXmpPage} on page~\pageref{KernelXmpPage}
+demonstrates how to extract the kernels in an expression.
+
+Use the HyperDoc Browse facility to see what operations are applicable
+to expression.  At the time of this writing, there were 262 operations
+with 147 distinct name in {\tt Expression Integer}.  For example,
+\spadfunFrom{numer}{Expression} and \spadfunFrom{denom}{Expression}
+extract the numerator and denominator of an expression.
+
+\spadcommand{e := (sin(x) - 4)**2 / ( 1 - 2*y*sqrt(- y) ) }
+$$
+{-{{\sin \left({x} \right)}\sp 2}+
+{8 \  {\sin \left({x} \right)}}
+-{16}} 
+\over {{2 \  y \  {\sqrt {-y}}} -1} 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{numer e }
+$$
+-{{\sin \left({x} \right)}\sp 2}+
+{8 \  {\sin \left({x} \right)}}
+-{16} 
+$$
+\returnType{Type: 
+SparseMultivariatePolynomial(Integer,Kernel Expression Integer)}
+
+\spadcommand{denom e }
+$$
+{2 \  y \  {\sqrt {-y}}} -1 
+$$
+\returnType{Type: 
+SparseMultivariatePolynomial(Integer,Kernel Expression Integer)}
+
+Use \spadfunFrom{D}{Expression} to compute partial derivatives.
+
+\spadcommand{D(e, x) }
+$$
+{{{\left( 
+{4 \  y \  {\cos \left({x} \right)}\  {\sin \left({x} \right)}}-
+{{16} \  y \  {\cos \left({x} \right)}}\right)}\  {\sqrt {-y}}} -
+{2 \  {\cos \left({x} \right)}\  {\sin \left({x} \right)}}+
+{8\  {\cos \left({x} \right)}}}
+\over {{4 \  y \  {\sqrt {-y}}}+{4 \  {y \sp 3}} -1} 
+$$
+\returnType{Type: Expression Integer}
+
+See 
+\ref{ugIntroCalcDerivPage} on page~\pageref{ugIntroCalcDerivPage} in Section 
+\ref{ugIntroCalcDerivNumber} on page~\pageref{ugIntroCalcDerivNumber}
+for more examples of expressions and derivatives.
+
+\spadcommand{D(e, [x, y], [1, 2]) }
+$$
+\left(
+\begin{array}{@{}l}
+{{\left( {{\left( -{{2304} \  {y \sp 7}}+{{960} \  {y \sp 4}} \right)}
+\  {\cos \left({x} \right)}\  {\sin \left({x} \right)}}+
+{{\left({{9216} \  {y \sp 7}} -{{3840} \  {y \sp 4}} \right)}
+\  {\cos \left({x} \right)}}\right)}\  {\sqrt {-y}}}+
+\\
+\\
+\displaystyle
+{{\left( -{{960} \  {y \sp 9}}+{{2160} \  {y \sp 6}} -{{180} \  {y \sp 3}} -3 
+\right)}\  {\cos \left({x} \right)}\  {\sin \left({x} \right)}}+
+\\
+\\
+\displaystyle
+{{\left(
+{{3840} \  {y \sp 9}} -{{8640} \  {y \sp 6}}+{{720} \  {y \sp 3}}+{12} 
+\right)}\  {\cos \left({x} \right)}}
+\end{array}
+\right)
+\over 
+\left(
+\begin{array}{@{}l}
+{{\left( {{256} \  {y \sp {12}}} -{{1792} \  {y \sp 9}}+{{1120} \  {y 
+\sp 6}} -{{112} \  {y \sp 3}}+1 \right)}\  {\sqrt {-y}}} -
+\\
+\\
+\displaystyle
+{{1024} \  {y \sp {11}}}+{{1792} \  {y \sp 8}} -{{448} \  
+{y \sp 5}}+{{16} \  {y \sp 2}} 
+\end{array}
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+See 
+\ref{ugIntroCalcLimitsPage} on page~\pageref{ugIntroCalcLimitsPage} in Section
+\ref{ugIntroCalcLimitsNumber} on page~\pageref{ugIntroCalcLimitsNumber} and 
+\ref{ugIntroSeriesPage} on page~\pageref{ugIntroSeriesPage} in Section
+\ref{ugIntroSeriesNumber} on page~\pageref{ugIntroSeriesNumber} 
+for more examples of expressions and
+calculus.  Differential equations involving expressions are discussed
+in \ref{ugProblemDEQPage} on page~\pageref{ugProblemDEQPage} in Section 
+\ref{ugProblemDEQNumber} on page~\pageref{ugProblemDEQNumber}.
+Chapter 8 has many advanced examples: see
+\ref{ugProblemIntegrationPage} on page~\pageref{ugProblemIntegrationPage} 
+in Section
+\ref{ugProblemIntegrationNumber} on page~\pageref{ugProblemIntegrationNumber} 
+for a discussion of Axiom's integration facilities.
+
+When an expression involves no ``symbol kernels'' (for example, 
+{\tt x}), it may be possible to numerically evaluate the expression.
+
+If you suspect the evaluation will create a complex number, use 
+{\tt complexNumeric}.
+
+\spadcommand{complexNumeric(cos(2 - 3*\%i))}
+$$
+-{4.1896256909\ 688072301}+{{9.1092278937\ 55336598} \  i} 
+$$
+\returnType{Type: Complex Float}
+
+If you know it will be real, use {\tt numeric}.
+
+\spadcommand{numeric(tan 3.8)}
+$$
+0.7735560905\ 0312607286 
+$$
+\returnType{Type: Float}
+
+The {\tt numeric} operation will display an error message if the
+evaluation yields a calue with an non-zero imaginary part.  Both of
+these operations have an optional second argument {\tt n} which
+specifies that the accuracy of the approximation be up to {\tt n}
+decimal places.
+
+When an expression involves no ``symbolic application'' kernels, it
+may be possible to convert it a polynomial or rational function in the
+variables that are present.
+
+\spadcommand{e2 := cos(x**2 - y + 3) }
+$$
+\cos \left({{y -{x \sp 2} -3}} \right)
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{e3 := asin(e2) - \%pi/2 }
+$$
+-y+{x \sp 2}+3 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{e3 :: Polynomial Integer }
+$$
+-y+{x \sp 2}+3 
+$$
+\returnType{Type: Polynomial Integer}
+
+This also works for the polynomial types where specific variables
+and their ordering are given.
+
+\spadcommand{e3 :: DMP([x, y], Integer) }
+$$
+{x \sp 2} -y+3 
+$$
+\returnType{Type: DistributedMultivariatePolynomial([x,y],Integer)}
+
+Finally, a certain amount of simplication takes place as expressions
+are constructed.
+
+\spadcommand{sin \%pi}
+$$
+0 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{cos(\%pi / 4)}
+$$
+{\sqrt {2}} \over 2 
+$$
+\returnType{Type: Expression Integer}
+
+For simplications that involve multiple terms of the expression, use
+{\tt simplify}.
+
+\spadcommand{tan(x)**6 + 3*tan(x)**4 + 3*tan(x)**2 + 1 }
+$$
+{{\tan \left({x} \right)}\sp 6}+
+{3 \  {{\tan \left({x} \right)}\sp 4}}+
+{3 \  {{\tan \left({x} \right)}\sp 2}}+1 
+$$
+\returnType{Type: Expression Integer}
+
+\spadcommand{simplify \% }
+$$
+1 \over {{\cos \left({x} \right)}\sp 6} 
+$$
+\returnType{Type: Expression Integer}
+
+See \ref{ugUserRulesPage} on page~\pageref{ugUserRulesPage} in Section 
+\ref{ugUserRulesNumber} on page~\pageref{ugUserRulesNumber} for
+examples of how to write your own rewrite rules for expressions.
+
+\section{Factored}
+\label{FactoredXmpPage}
+
+{\tt Factored} creates a domain whose objects are kept in factored
+form as long as possible.  Thus certain operations like
+\spadopFrom{*}{Factored} (multiplication) and
+\spadfunFrom{gcd}{Factored} are relatively easy to do.  Others, such
+as addition, require somewhat more work, and the result may not be
+completely factored unless the argument domain {\tt R} provides a
+\spadfunFrom{factor}{Factored} operation.  Each object consists of a
+unit and a list of factors, where each factor consists of a member of
+{\tt R} (the {\em base}), an exponent, and a flag indicating what is
+known about the base.  A flag may be one of ``{\tt nil}'', ``{\tt sqfr}'',
+``{\tt irred}'' or ``{\tt prime}'', which mean that nothing is known about
+the base, it is square-free, it is irreducible, or it is prime,
+respectively.  The current restriction to factored objects of integral
+domains allows simplification to be performed without worrying about
+multiplication order.
+
+\subsection{Decomposing Factored Objects}
+
+In this section we will work with a factored integer.
+
+\spadcommand{g := factor(4312) }
+$$
+{2 \sp 3} \  {7 \sp 2} \  {11} 
+$$
+\returnType{Type: Factored Integer}
+
+Let's begin by decomposing {\tt g} into pieces.  The only possible
+units for integers are {\tt 1} and {\tt -1}.
+
+\spadcommand{unit(g) }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+There are three factors.
+
+\spadcommand{numberOfFactors(g) }
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+We can make a list of the bases, \ldots
+
+\spadcommand{[nthFactor(g,i) for i in 1..numberOfFactors(g)] }
+$$
+\left[
+2, 7, {11} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+and the exponents, \ldots
+
+\spadcommand{[nthExponent(g,i) for i in 1..numberOfFactors(g)] }
+$$
+\left[
+3, 2, 1 
+\right]
+$$
+\returnType{Type: List Integer}
+
+and the flags.  You can see that all the bases (factors) are prime.
+
+\spadcommand{[nthFlag(g,i) for i in 1..numberOfFactors(g)] }
+$$
+\left[
+\mbox{\tt "prime"} , \mbox{\tt "prime"} , \mbox{\tt "prime"} 
+\right]
+$$
+\returnType{Type: List Union("nil","sqfr","irred","prime")}
+
+A useful operation for pulling apart a factored object into a list
+of records of the components is \spadfunFrom{factorList}{Factored}.
+
+\spadcommand{factorList(g) }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {flg= \mbox{\tt "prime"} }, {fctr=2}, {xpnt=3} \right]},
+\right.
+\\
+\\
+\displaystyle
+{\left[ {flg= \mbox{\tt "prime"} }, {fctr=7}, {xpnt=2} \right]},
+\\
+\\
+\left.
+\displaystyle
+{\left[ {flg= \mbox{\tt "prime"} }, {fctr={11}}, {xpnt=1} \right]}
+\right]
+\end{array}
+$$
+\returnType{Type: 
+List Record(flg: Union("nil","sqfr","irred","prime"),
+fctr: Integer,xpnt: Integer)}
+
+If you don't care about the flags, use \spadfunFrom{factors}{Factored}.
+
+\spadcommand{factors(g) }
+$$
+\begin{array}{@{}l}
+\left[
+{\left[ {factor=2}, {exponent=3} \right]},
+\right.
+\\
+\\
+\displaystyle
+{\left[ {factor=7}, {exponent=2} \right]},
+\\
+\\
+\displaystyle
+\left.
+{\left[ {factor={11}}, {exponent=1} \right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List Record(factor: Integer,exponent: Integer)}
+
+Neither of these operations returns the unit.
+
+\spadcommand{first(\%).factor }
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Expanding Factored Objects}
+
+Recall that we are working with this factored integer.
+
+\spadcommand{g := factor(4312) }
+$$
+{2 \sp 3} \  {7 \sp 2} \  {11} 
+$$
+\returnType{Type: Factored Integer}
+
+To multiply out the factors with their multiplicities, use
+\spadfunFrom{expand}{Factored}.
+
+\spadcommand{expand(g) }
+$$
+4312 
+$$
+\returnType{Type: PositiveInteger}
+
+If you would like, say, the distinct factors multiplied together but
+with multiplicity one, you could do it this way.
+
+\spadcommand{reduce(*,[t.factor for t in factors(g)]) }
+$$
+154 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Arithmetic with Factored Objects}
+
+We're still working with this factored integer.
+
+\spadcommand{g := factor(4312) }
+$$
+{2 \sp 3} \  {7 \sp 2} \  {11} 
+$$
+\returnType{Type: Factored Integer}
+
+We'll also define this factored integer.
+
+\spadcommand{f := factor(246960) }
+$$
+{2 \sp 4} \  {3 \sp 2} \  5 \  {7 \sp 3} 
+$$
+\returnType{Type: Factored Integer}
+
+Operations involving multiplication and division are particularly
+easy with factored objects.
+
+\spadcommand{f * g }
+$$
+{2 \sp 7} \  {3 \sp 2} \  5 \  {7 \sp 5} \  {11} 
+$$
+\returnType{Type: Factored Integer}
+
+\spadcommand{f**500 }
+$$
+{2 \sp {2000}} \  {3 \sp {1000}} \  {5 \sp {500}} \  {7 \sp {1500}} 
+$$
+\returnType{Type: Factored Integer}
+
+\spadcommand{gcd(f,g) }
+$$
+{2 \sp 3} \  {7 \sp 2} 
+$$
+\returnType{Type: Factored Integer}
+
+\spadcommand{lcm(f,g) }
+$$
+{2 \sp 4} \  {3 \sp 2} \  5 \  {7 \sp 3} \  {11} 
+$$
+\returnType{Type: Factored Integer}
+
+If we use addition and subtraction things can slow down because
+we may need to compute greatest common divisors.
+
+\spadcommand{f + g }
+$$
+{2 \sp 3} \  {7 \sp 2} \  {641} 
+$$
+\returnType{Type: Factored Integer}
+
+\spadcommand{f - g }
+$$
+{2 \sp 3} \  {7 \sp 2} \  {619} 
+$$
+\returnType{Type: Factored Integer}
+
+Test for equality with {\tt 0} and {\tt 1} by using
+\spadfunFrom{zero?}{Factored} and \spadfunFrom{one?}{Factored},
+respectively.
+
+\spadcommand{zero?(factor(0))}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{zero?(g) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{one?(factor(1))}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{one?(f) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Another way to get the zero and one factored objects is to use
+package calling (see 
+\ref{ugTypesPkgCallPage} on page~\pageref{ugTypesPkgCallPage} in Section 
+\ref{ugTypesPkgCallNumber} on page~\pageref{ugTypesPkgCallNumber}).
+
+\spadcommand{0\$Factored(Integer)}
+$$
+0 
+$$
+\returnType{Type: Factored Integer}
+
+\spadcommand{1\$Factored(Integer)}
+$$
+1 
+$$
+\returnType{Type: Factored Integer}
+
+\subsection{Creating New Factored Objects}
+
+The \spadfunFrom{map}{Factored} operation is used to iterate across
+the unit and bases of a factored object.  See
+\ref{FactoredFunctionsTwoXmpPage} on 
+page~\pageref{FactoredFunctionsTwoXmpPage} for a discussion of
+\spadfunFrom{map}{Factored}.
+
+The following four operations take a base and an exponent and create a
+factored object.  They differ in handling the flag component.
+
+\spadcommand{nilFactor(24,2) }
+$$
+{24} \sp 2 
+$$
+\returnType{Type: Factored Integer}
+
+This factor has no associated information.
+
+\spadcommand{nthFlag(\%,1) }
+$$
+\mbox{\tt "nil"} 
+$$
+\returnType{Type: Union("nil",...)}
+
+This factor is asserted to be square-free.
+
+\spadcommand{sqfrFactor(30,2) }
+$$
+{30} \sp 2 
+$$
+\returnType{Type: Factored Integer}
+
+This factor is asserted to be irreducible.
+
+\spadcommand{irreducibleFactor(13,10) }
+$$
+{13} \sp {10} 
+$$
+\returnType{Type: Factored Integer}
+
+This factor is asserted to be prime.
+
+\spadcommand{primeFactor(11,5) }
+$$
+{11} \sp 5 
+$$
+\returnType{Type: Factored Integer}
+
+A partial inverse to \spadfunFrom{factorList}{Factored} is
+\spadfunFrom{makeFR}{Factored}.
+
+\spadcommand{h := factor(-720) }
+$$
+-{{2 \sp 4} \  {3 \sp 2} \  5} 
+$$
+\returnType{Type: Factored Integer}
+
+The first argument is the unit and the second is a list of records as
+returned by \spadfunFrom{factorList}{Factored}.
+
+\spadcommand{h - makeFR(unit(h),factorList(h)) }
+$$
+0 
+$$
+\returnType{Type: Factored Integer}
+
+\subsection{Factored Objects with Variables}
+
+Some of the operations available for polynomials are also available
+for factored polynomials.
+
+\spadcommand{p := (4*x*x-12*x+9)*y*y + (4*x*x-12*x+9)*y + 28*x*x - 84*x + 63 }
+$$
+{{\left( {4 \  {x \sp 2}} -{{12} \  x}+9 
+\right)}
+\  {y \sp 2}}+{{\left( {4 \  {x \sp 2}} -{{12} \  x}+9 
+\right)}
+\  y}+{{28} \  {x \sp 2}} -{{84} \  x}+{63} 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{fp := factor(p) }
+$$
+{{\left( {2 \  x} -3 
+\right)}
+\sp 2} \  {\left( {y \sp 2}+y+7 
+\right)}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+You can differentiate with respect to a variable.
+
+\spadcommand{D(p,x) }
+$$
+{{\left( {8 \  x} -{12} 
+\right)}
+\  {y \sp 2}}+{{\left( {8 \  x} -{12} 
+\right)}
+\  y}+{{56} \  x} -{84} 
+$$
+\returnType{Type: Polynomial Integer}
+
+\spadcommand{D(fp,x) }
+$$
+4 \  {\left( {2 \  x} -3 
+\right)}
+\  {\left( {y \sp 2}+y+7 
+\right)}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+\spadcommand{numberOfFactors(\%) }
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{FactoredFunctions2}
+\label{FactoredFunctions2XmpPage}
+
+The {\tt FactoredFunctions2} package implements one operation,
+\spadfunFrom{map}{FactoredFunctions2}, for applying an operation to every
+base in a factored object and to the unit.
+
+\spadcommand{double(x) == x + x }
+\returnType{Type: Void}
+
+\spadcommand{f := factor(720) }
+$$
+{2 \sp 4} \  {3 \sp 2} \  5 
+$$
+\returnType{Type: Factored Integer}
+
+Actually, the \spadfunFrom{map}{FactoredFunctions2} operation used
+in this example comes from {\tt Factored} itself, since {\tt double} 
+takes an integer argument and returns an integer result.
+
+\spadcommand{map(double,f) }
+$$
+2 \  {4 \sp 4} \  {6 \sp 2} \  {10} 
+$$
+\returnType{Type: Factored Integer}
+
+If we want to use an operation that returns an object that has a type
+different from the operation's argument,
+the \spadfunFrom{map}{FactoredFunctions2} in {\tt Factored}
+cannot be used and we use the one in {\tt FactoredFunctions2}.
+
+\spadcommand{makePoly(b) == x + b }
+\returnType{Type: Void}
+
+In fact, the ``2'' in the name of the package means that we might
+be using factored objects of two different types.
+
+\spadcommand{g := map(makePoly,f) }
+$$
+{\left( x+1 \right)}
+\  {{\left( x+2 \right)}\sp 4} 
+\  {{\left( x+3 \right)}\sp 2} 
+\  {\left( x+5 \right)}
+$$
+\returnType{Type: Factored Polynomial Integer}
+
+It is important to note that both versions of
+\spadfunFrom{map}{FactoredFunctions2} destroy any information known
+about the bases (the fact that they are prime, for instance).
+
+The flags for each base are set to ``nil'' in the object returned
+by \spadfunFrom{map}{FactoredFunctions2}.
+
+\spadcommand{nthFlag(g,1) }
+$$
+\mbox{\tt "nil"} 
+$$
+\returnType{Type: Union("nil",...)}
+
+For more information about factored objects and their use, see
+\ref{FactoredXmpPage} on page~\pageref{FactoredXmpPage} and 
+\ref{ugProblemGaloisPage} on page~\pageref{ugProblemGaloisPage} in Section 
+\ref{ugProblemGaloisNumber} on page~\pageref{ugProblemGaloisNumber}.
+
+\section{File}
+\label{FileXmpPage}
+
+The {\tt File(S)} domain provides a basic interface to read and
+write values of type {\tt S} in files.
+
+Before working with a file, it must be made accessible to Axiom with
+the \spadfunFrom{open}{File} operation.
+
+\spadcommand{ifile:File List Integer:=open("/tmp/jazz1","output")  }
+$$
+\mbox{\tt "/tmp/jazz1"} 
+$$
+\returnType{Type: File List Integer}
+
+The \spadfunFrom{open}{File} function arguments are a {\tt FileName}
+and a {\tt String} specifying the mode.  If a full pathname is not
+specified, the current default directory is assumed.  The mode must be
+one of ``{\tt input}'' or ``{\tt output}''.  If it is not specified, 
+``{\tt input}'' is assumed.  Once the file has been opened, you can read or
+write data.
+
+The operations \spadfunFrom{read}{File} and \spadfunFrom{write}{File} are
+provided.
+
+\spadcommand{write!(ifile, [-1,2,3])}
+$$
+\left[
+-1, 2, 3 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{write!(ifile, [10,-10,0,111])}
+$$
+\left[
+{10}, -{10}, 0, {111} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{write!(ifile, [7])}
+$$
+\left[
+7 
+\right]
+$$
+\returnType{Type: List Integer}
+
+You can change from writing to reading (or vice versa) by reopening a file.
+
+\spadcommand{reopen!(ifile, "input")}
+$$
+\mbox{\tt "/tmp/jazz1"} 
+$$
+\returnType{Type: File List Integer}
+
+\spadcommand{read! ifile}
+$$
+\left[
+-1, 2, 3 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\spadcommand{read! ifile}
+$$
+\left[
+{10}, -{10}, 0, {111} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+The \spadfunFrom{read}{File} operation can cause an error if one tries
+to read more data than is in the file.  To guard against this
+possibility the \spadfunFrom{readIfCan}{File} operation should be
+used.
+
+\spadcommand{readIfCan! ifile  }
+$$
+\left[
+7 
+\right]
+$$
+\returnType{Type: Union(List Integer,...)}
+
+\spadcommand{readIfCan! ifile  }
+$$
+\mbox{\tt "failed"} 
+$$
+\returnType{Type: Union("failed",...)}
+
+You can find the current mode of the file, and the file's name.
+
+\spadcommand{iomode ifile}
+$$
+\mbox{\tt "input"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{name ifile}
+$$
+\mbox{\tt "/tmp/jazz1"} 
+$$
+\returnType{Type: FileName}
+
+When you are finished with a file, you should close it.
+
+\spadcommand{close! ifile}
+$$
+\mbox{\tt "/tmp/jazz1"} 
+$$
+\returnType{Type: File List Integer}
+
+\spadcommand{)system rm /tmp/jazz1}
+
+A limitation of the underlying LISP system is that not all values can
+be represented in a file.  In particular, delayed values containing
+compiled functions cannot be saved.
+
+For more information on related topics, see 
+\ref{TextFileXmpPage} on page~\pageref{TextFileXmpPage},
+\ref{KeyedAccessFileXmpPage} on page~\pageref{KeyedAccessFileXmpPage}, 
+\ref{LibraryXmpPage} on page~\pageref{LibraryXmpPage}, and
+\ref{FileNameXmpPage} on page~\pageref{FileNameXmpPage}.
+
+\section{FileName}
+\label{FileNameXmpPage}
+ 
+The {\tt FileName} domain provides an interface to the computer's file
+system.  Functions are provided to manipulate file names and to test
+properties of files.
+ 
+The simplest way to use file names in the Axiom interpreter is to rely
+on conversion to and from strings.  The syntax of these strings
+depends on the operating system.
+
+\spadcommand{fn: FileName }
+\returnType{Type: Void}
+
+On Linux, this is a proper file syntax:
+
+\spadcommand{fn := "/tmp/fname.input" }
+$$
+\mbox{\tt "/tmp/fname.input"} 
+$$
+\returnType{Type: FileName}
+
+Although it is very convenient to be able to use string notation
+for file names in the interpreter, it is desirable to have a portable
+way of creating and manipulating file names from within programs.
+
+A measure of portability is obtained by considering a file name
+to consist of three parts: the {\it directory}, the {\it name},
+and the {\it extension}.
+
+\spadcommand{directory fn }
+$$
+\mbox{\tt "/tmp"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{name fn }
+$$
+\mbox{\tt "fname"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{extension fn }
+$$
+\mbox{\tt "input"} 
+$$
+\returnType{Type: String}
+
+The meaning of these three parts depends on the operating system.
+For example, on CMS the file ``{\tt SPADPROF INPUT M}''
+would have directory ``{\tt M}'', name ``{\tt SPADPROF}'' and
+extension ``{\tt INPUT}''.
+ 
+It is possible to create a filename from its parts.
+
+\spadcommand{fn := filename("/u/smwatt/work", "fname", "input") }
+$$
+\mbox{\tt "/u/smwatt/work/fname.input"} 
+$$
+\returnType{Type: FileName}
+
+When writing programs, it is helpful to refer to directories via
+variables.
+
+\spadcommand{objdir := "/tmp" }
+$$
+\mbox{\tt "/tmp"} 
+$$
+\returnType{Type: String}
+
+\spadcommand{fn := filename(objdir, "table", "spad") }
+$$
+\mbox{\tt "/tmp/table.spad"} 
+$$
+\returnType{Type: FileName}
+
+If the directory or the extension is given as an empty string, then
+a default is used.  On AIX, the defaults are the current directory
+and no extension.
+
+\spadcommand{fn := filename("", "letter", "") }
+$$
+\mbox{\tt "letter"} 
+$$
+\returnType{Type: FileName}
+ 
+Three tests provide information about names in the file system.
+
+The \spadfunFrom{exists?}{FileName} operation tests whether the named
+file exists.
+
+\spadcommand{exists? "/etc/passwd"}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+The operation \spadfunFrom{readable?}{FileName} tells whether the named file
+can be read.  If the file does not exist, then it cannot be read.
+
+\spadcommand{readable? "/etc/passwd"}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{readable? "/etc/security/passwd"}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{readable? "/ect/passwd"}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+Likewise, the operation \spadfunFrom{writable?}{FileName} tells
+whether the named file can be written.  If the file does not exist,
+the test is determined by the properties of the directory.
+
+\spadcommand{writable? "/etc/passwd"}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{writable? "/dev/null"}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{writable? "/etc/DoesNotExist"}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{writable? "/tmp/DoesNotExist"}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+ 
+The \spadfunFrom{new}{FileName} operation constructs the name of a new
+writable file.  The argument sequence is the same as for
+\spadfunFrom{filename}{FileName}, except that the name part is
+actually a prefix for a constructed unique name.
+
+The resulting file is in the specified directory
+with the given extension, and the same defaults are used.
+
+\spadcommand{fn := new(objdir, "xxx", "yy") }
+$$
+\mbox{\tt "/tmp/xxx82404.yy"} 
+$$
+\returnType{Type: FileName}
+
+\section{FlexibleArray}
+\label{FlexibleArrayXmpPage}
+
+The {\tt FlexibleArray} domain constructor creates one-dimensional
+arrays of elements of the same type.  Flexible arrays are an attempt
+to provide a data type that has the best features of both
+one-dimensional arrays (fast, random access to elements) and lists
+(flexibility).  They are implemented by a fixed block of storage.
+When necessary for expansion, a new, larger block of storage is
+allocated and the elements from the old storage area are copied into
+the new block.
+
+Flexible arrays have available most of the operations provided by 
+{\tt OneDimensionalArray} (see 
+\ref{OneDimensionalArrayXmpPage} on page~\pageref{OneDimensionalArrayXmpPage} 
+and \ref{VectorXmpPage} on page~\pageref{VectorXmpPage}).  
+Since flexible arrays are also of category 
+{\tt ExtensibleLinearAggregate}, they have operations {\tt concat!}, 
+{\tt delete!}, {\tt insert!}, {\tt merge!}, {\tt remove!}, 
+{\tt removeDuplicates!}, and {\tt select!}.  In addition, the operations
+{\tt physicalLength} and {\tt physicalLength!} provide user-control
+over expansion and contraction.
+
+A convenient way to create a flexible array is to apply the operation
+{\tt flexibleArray} to a list of values.
+
+\spadcommand{flexibleArray [i for i in 1..6]}
+$$
+\left[
+1, 2, 3, 4, 5, 6 
+\right]
+$$
+\returnType{Type: FlexibleArray PositiveInteger}
+
+Create a flexible array of six zeroes.
+
+\spadcommand{f : FARRAY INT := new(6,0)}
+$$
+\left[
+0, 0, 0, 0, 0, 0 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+For $i=1\ldots 6$ set the $i$-th element to $i$.  Display {\tt f}.
+
+\spadcommand{for i in 1..6 repeat f.i := i; f}
+$$
+\left[
+1, 2, 3, 4, 5, 6 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Initially, the physical length is the same as the number of elements.
+
+\spadcommand{physicalLength f}
+$$
+6 
+$$
+\returnType{Type: PositiveInteger}
+
+Add an element to the end of {\tt f}.
+
+\spadcommand{concat!(f,11)}
+$$
+\left[
+1, 2, 3, 4, 5, 6, {11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+See that its physical length has grown.
+
+\spadcommand{physicalLength f}
+$$
+10 
+$$
+\returnType{Type: PositiveInteger}
+
+Make {\tt f} grow to have room for {\tt 15} elements.
+
+\spadcommand{physicalLength!(f,15)}
+$$
+\left[
+1, 2, 3, 4, 5, 6, {11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Concatenate the elements of {\tt f} to itself.  The physical length
+allows room for three more values at the end.
+
+\spadcommand{concat!(f,f)}
+$$
+\left[
+1, 2, 3, 4, 5, 6, {11}, 1, 2, 3, 4, 5, 6, 
+{11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Use {\tt insert!} to add an element to the front of a flexible array.
+
+\spadcommand{insert!(22,f,1)}
+$$
+\left[
+{22}, 1, 2, 3, 4, 5, 6, {11}, 1, 2, 3, 4, 
+5, 6, {11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Create a second flexible array from {\tt f} consisting of the elements
+from index 10 forward.
+
+\spadcommand{g := f(10..)}
+$$
+\left[
+2, 3, 4, 5, 6, {11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Insert this array at the front of {\tt f}.
+
+\spadcommand{insert!(g,f,1)}
+$$
+\left[
+2, 3, 4, 5, 6, {11}, {22}, 1, 2, 3, 4, 5, 
+6, {11}, 1, 2, 3, 4, 5, 6, {11} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Merge the flexible array {\tt f} into {\tt g} after sorting each in place.
+
+\spadcommand{merge!(sort! f, sort! g)}
+$$
+\left[
+1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 
+4, 5, 5, 5, 5, 6, 6, 6, 6, {11}, {11}, {11}, 
+{11}, {22} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Remove duplicates in place.
+
+\spadcommand{removeDuplicates! f}
+$$
+\left[
+1, 2, 3, 4, 5, 6, {11}, {22} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+Remove all odd integers.
+
+\spadcommand{select!(i +-> even? i,f)}
+$$
+\left[
+2, 4, 6, {22} 
+\right]
+$$
+\returnType{Type: FlexibleArray Integer}
+
+All these operations have shrunk the physical length of {\tt f}.
+
+\spadcommand{physicalLength f}
+$$
+8 
+$$
+\returnType{Type: PositiveInteger}
+
+To force Axiom not to shrink flexible arrays call the {\tt shrinkable}
+operation with the argument {\tt false}.  You must package call this
+operation.  The previous value is returned.
+
+\spadcommand{shrinkable(false)\$FlexibleArray(Integer)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\section{Float}
+\label{FloatXmpPage}
+
+Axiom provides two kinds of floating point numbers.  The domain 
+{\tt Float} (abbreviation {\tt FLOAT}) implements a model of arbitrary
+precision floating point numbers.  The domain {\tt DoubleFloat}
+(abbreviation {\tt DFLOAT}) is intended to make available hardware
+floating point arithmetic in Axiom.  The actual model of floating
+point that {\tt DoubleFloat} provides is system-dependent.  For
+example, on the IBM system 370 Axiom uses IBM double precision which
+has fourteen hexadecimal digits of precision or roughly sixteen
+decimal digits.  Arbitrary precision floats allow the user to specify
+the precision at which arithmetic operations are computed.  Although
+this is an attractive facility, it comes at a cost.
+Arbitrary-precision floating-point arithmetic typically takes twenty
+to two hundred times more time than hardware floating point.
+
+For more information about Axiom's numeric and graphic facilities, see
+\ref{ugGraphPage} on page~\pageref{ugGraphPage} in Section 
+\ref{ugGraphNumber} on page~\pageref{ugGraphNumber},
+\ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}, and 
+\ref{DoubleFloatXmpPage} on page~\pageref{DoubleFloatXmpPage}.
+
+\subsection{Introduction to Float}
+
+Scientific notation is supported for input and output of floating
+point numbers.  A floating point number is written as a string of
+digits containing a decimal point optionally followed by the letter
+``{\tt E}'', and then the exponent.
+
+We begin by doing some calculations using arbitrary precision floats.
+The default precision is twenty decimal digits.
+
+\spadcommand{1.234}
+$$
+1.234 
+$$
+\returnType{Type: Float}
+
+A decimal base for the exponent is assumed, so the number 
+{\tt 1.234E2} denotes $1.234 \cdot 10^2$.
+
+\spadcommand{1.234E2}
+$$
+123.4 
+$$
+\returnType{Type: Float}
+
+The normal arithmetic operations are available for floating point numbers.
+
+\spadcommand{sqrt(1.2 + 2.3 / 3.4 ** 4.5)}
+$$
+1.0996972790\ 671286226 
+$$
+\returnType{Type: Float}
+
+\subsection{Conversion Functions}
+
+You can use conversion (\ref{ugTypesConvertPage} on
+page~\pageref{ugTypesConvertPage} in Section
+\ref{ugTypesConvertNumber} on page~\pageref{ugTypesConvertNumber}) to
+go back and forth between {\tt Integer}, {\tt Fraction Integer} and
+{\tt Float}, as appropriate.
+
+\spadcommand{i := 3 :: Float }
+$$
+3.0 
+$$
+\returnType{Type: Float}
+
+\spadcommand{i :: Integer }
+$$
+3 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{i :: Fraction Integer }
+$$
+3 
+$$
+\returnType{Type: Fraction Integer}
+
+Since you are explicitly asking for a conversion, you must take
+responsibility for any loss of exactness.
+
+\spadcommand{r := 3/7 :: Float }
+$$
+0.4285714285\ 7142857143 
+$$
+\returnType{Type: Float}
+
+\spadcommand{r :: Fraction Integer }
+$$
+3 \over 7 
+$$
+\returnType{Type: Fraction Integer}
+
+This conversion cannot be performed: use \spadfunFrom{truncate}{Float}
+or \spadfunFrom{round}{Float} if that is what you intend.
+
+\spadcommand{r :: Integer }
+\begin{verbatim}
+   Cannot convert from type Float to Integer for value
+   0.4285714285 7142857143
+\end{verbatim}
+
+The operations \spadfunFrom{truncate}{Float} and \spadfunFrom{round}{Float}
+truncate  \ldots
+
+\spadcommand{truncate 3.6}
+$$
+3.0 
+$$
+\returnType{Type: Float}
+
+and round to the nearest integral {\tt Float} respectively.
+
+\spadcommand{round 3.6}
+$$
+4.0 
+$$
+\returnType{Type: Float}
+
+\spadcommand{truncate(-3.6)}
+$$
+-{3.0} 
+$$
+\returnType{Type: Float}
+
+\spadcommand{round(-3.6)}
+$$
+-{4.0} 
+$$
+\returnType{Type: Float}
+
+The operation \spadfunFrom{fractionPart}{Float} computes the
+fractional part of {\tt x}, that is, {\tt x - truncate x}.
+
+\spadcommand{fractionPart 3.6}
+$$
+0.6 
+$$
+\returnType{Type: Float}
+
+The operation \spadfunFrom{digits}{Float} allows the user to set the
+precision.  It returns the previous value it was using.
+
+\spadcommand{digits 40 }
+$$
+20 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{sqrt 0.2}
+$$
+0.4472135954\ 9995793928\ 1834733746\ 2552470881 
+$$
+\returnType{Type: Float}
+
+\spadcommand{pi()\$Float }
+$$
+3.1415926535\ 8979323846\ 2643383279\ 502884197 
+$$
+\returnType{Type: Float}
+
+The precision is only limited by the computer memory available.
+Calculations at 500 or more digits of precision are not difficult.
+
+\spadcommand{digits 500 }
+$$
+40 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{pi()\$Float }
+$$
+\begin{array}{@{}l}
+3.1415926535\ 8979323846\ 2643383279\ 5028841971\ 6939937510\ 5820974944 
+\\
+\displaystyle
+\ \ 5923078164\ 0628620899\ 8628034825\ 3421170679\ 8214808651\ 3282306647
+\\
+\displaystyle
+\ \ 0938446095\ 5058223172\ 5359408128\ 4811174502\ 8410270193\ 8521105559
+\\
+\displaystyle
+\ \ 6446229489\ 5493038196\ 4428810975\ 6659334461\ 2847564823\ 3786783165
+\\
+\displaystyle
+\ \ 2712019091\ 4564856692\ 3460348610\ 4543266482\ 1339360726\ 0249141273
+\\
+\displaystyle
+\ \ 7245870066\ 0631558817\ 4881520920\ 9628292540\ 9171536436\ 7892590360
+\\
+\displaystyle
+\ \ 0113305305\ 4882046652\ 1384146951\ 9415116094\ 3305727036\ 5759591953
+\\
+\displaystyle
+\ \ 0921861173\ 8193261179\ 3105118548\ 0744623799\ 6274956735\ 1885752724
+\\
+\displaystyle
+\ \ 8912279381\ 830119491 
+\end{array}
+$$
+\returnType{Type: Float}
+
+Reset \spadfunFrom{digits}{Float} to its default value.
+
+\spadcommand{digits 20}
+$$
+500 
+$$
+\returnType{Type: PositiveInteger}
+
+Numbers of type {\tt Float} are represented as a record of two
+integers, namely, the mantissa and the exponent where the base of the
+exponent is binary.  That is, the floating point number {\tt (m,e)}
+represents the number $m \cdot 2^e$.  A consequence of using a binary
+base is that decimal numbers can not, in general, be represented
+exactly.
+
+\subsection{Output Functions}
+
+A number of operations exist for specifying how numbers of type 
+{\tt Float} are to be displayed.  By default, spaces are inserted every ten
+digits in the output for readability.\footnote{Note that you cannot
+include spaces in the input form of a floating point number, though
+you can use underscores.}
+
+Output spacing can be modified with the \spadfunFrom{outputSpacing}{Float} 
+operation.  This inserts no spaces and then displays the value of {\tt x}.
+
+\spadcommand{outputSpacing 0; x := sqrt 0.2 }
+$$
+0.44721359549995793928 
+$$
+\returnType{Type: Float}
+
+Issue this to have the spaces inserted every {\tt 5} digits.
+
+\spadcommand{outputSpacing 5; x }
+$$
+0.44721\ 35954\ 99957\ 93928 
+$$
+\returnType{Type: Float}
+
+By default, the system displays floats in either fixed format
+or scientific format, depending on the magnitude of the number.
+
+\spadcommand{y := x/10**10 }
+$$
+0.44721\ 35954\ 99957\ 93928\ {\rm E\ }-10 
+$$
+\returnType{Type: Float}
+
+A particular format may be requested with the operations
+\spadfunFrom{outputFloating}{Float} and \spadfunFrom{outputFixed}{Float}.
+
+\spadcommand{outputFloating(); x  }
+$$
+0.44721\ 35954\ 99957\ 93928\ {\rm E\ }0 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputFixed(); y  }
+$$
+0.00000\ 00000\ 44721\ 35954\ 99957\ 93928 
+$$
+\returnType{Type: Float}
+
+Additionally, you can ask for {\tt n} digits to be displayed after the
+decimal point.
+
+\spadcommand{outputFloating 2; y  }
+$$
+0.45\ {\rm E\ } -10 
+$$
+\returnType{Type: Float}
+
+\spadcommand{outputFixed 2; x  }
+$$
+0.45 
+$$
+\returnType{Type: Float}
+
+This resets the output printing to the default behavior.
+
+\spadcommand{outputGeneral()}
+\returnType{Type: Void}
+
+\subsection{An Example: Determinant of a Hilbert Matrix}
+
+Consider the problem of computing the determinant of a {\tt 10} by
+{\tt 10} Hilbert matrix.  The $(i,j)$-th entry of a Hilbert
+matrix is given by {\tt 1/(i+j+1)}.
+
+First do the computation using rational numbers to obtain the
+exact result.
+
+\spadcommand{a: Matrix Fraction Integer := matrix [ [1/(i+j+1) for j in 0..9] for i in 0..9] }
+$$
+\left[
+\begin{array}{cccccccccc}
+1 & {1 \over 2} & {1 \over 3} & {1 \over 4} & {1 \over 5} & {1 \over 6} & 
+{1 \over 7} & {1 \over 8} & {1 \over 9} & {1 \over {10}} \\ 
+{1 \over 2} & {1 \over 3} & {1 \over 4} & {1 \over 5} & {1 \over 6} & 
+{1 \over 7} & {1 \over 8} & {1 \over 9} & {1 \over {10}} & {1 \over {11}} \\ 
+{1 \over 3} & {1 \over 4} & {1 \over 5} & {1 \over 6} & {1 \over 7} & 
+{1 \over 8} & {1 \over 9} & {1 \over {10}} & {1 \over {11}} & 
+{1 \over {12}} \\ 
+{1 \over 4} & {1 \over 5} & {1 \over 6} & {1 \over 7} & {1 \over 8} & 
+{1 \over 9} & {1 \over {10}} & {1 \over {11}} & {1 \over {12}} & 
+{1 \over {13}} \\ 
+{1 \over 5} & {1 \over 6} & {1 \over 7} & {1 \over 8} & {1 \over 9} & 
+{1 \over {10}} & {1 \over {11}} & {1 \over {12}} & {1 \over {13}} & 
+{1 \over {14}} \\ 
+{1 \over 6} & {1 \over 7} & {1 \over 8} & {1 \over 9} & {1 \over {10}} & 
+{1 \over {11}} & {1 \over {12}} & {1 \over {13}} & {1 \over {14}} & 
+{1 \over {15}} \\ 
+{1 \over 7} & {1 \over 8} & {1 \over 9} & {1 \over {10}} & {1 \over {11}} & 
+{1 \over {12}} & {1 \over {13}} & {1 \over {14}} & {1 \over {15}} & 
+{1 \over {16}} \\ 
+{1 \over 8} & {1 \over 9} & {1 \over {10}} & {1 \over {11}} & {1 \over {12}} 
+& {1 \over {13}} & {1 \over {14}} & {1 \over {15}} & {1 \over {16}} & 
+{1 \over {17}} \\ 
+{1 \over 9} & {1 \over {10}} & {1 \over {11}} & {1 \over {12}} & 
+{1 \over {13}} & {1 \over {14}} & {1 \over {15}} & {1 \over {16}} & 
+{1 \over {17}} & {1 \over {18}} \\ 
+{1 \over {10}} & {1 \over {11}} & {1 \over {12}} & {1 \over {13}} & 
+{1 \over {14}} & {1 \over {15}} & {1 \over {16}} & {1 \over {17}} & 
+{1 \over {18}} & {1 \over {19}} 
+\end{array}
+\right]
+$$
+\returnType{Type: Matrix Fraction Integer}
+
+This version of \spadfunFrom{determinant}{Matrix} uses Gaussian elimination.
+
+\spadcommand{d:= determinant a }
+$$
+1 \over {46206893947914691316295628839036278726983680000000000} 
+$$
+\returnType{Type: Fraction Integer}
+
+\spadcommand{d :: Float }
+$$
+0.21641\ 79226\ 43149\ 18691\ {\rm E\ } -52 
+$$
+\returnType{Type: Float}
+
+Now use hardware floats. Note that a semicolon (;) is used to prevent
+the display of the matrix.
+
+\spadcommand{b: Matrix DoubleFloat := matrix [ [1/(i+j+1\$DoubleFloat) for j in 0..9] for i in 0..9]; }
+\returnType{Type: Matrix DoubleFloat}
+
+The result given by hardware floats is correct only to four
+significant digits of precision.  In the jargon of numerical analysis,
+the Hilbert matrix is said to be ``ill-conditioned.''
+
+\spadcommand{determinant b }
+$$
+2.1643677945721411e-53 
+$$
+\returnType{Type: DoubleFloat}
+
+Now repeat the computation at a higher precision using {\tt Float}.
+
+\spadcommand{digits 40 }
+$$
+20 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{c: Matrix Float := matrix [ [1/(i+j+1\$Float) for j in 0..9] for i in 0..9];  }
+\returnType{Type: Matrix Float}
+
+\spadcommand{determinant c }
+$$
+0.21641\ 79226\ 43149\ 18690\ 60594\ 98362\ 26174\ 36159\ {\rm E\ } -52 
+$$
+\returnType{Type: Float}
+
+Reset \spadfunFrom{digits}{Float} to its default value.
+
+\spadcommand{digits 20}
+$$
+40 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{Fraction}
+\label{FractionXmpPage}
+
+The {\tt Fraction} domain implements quotients.  The elements must
+belong to a domain of category {\tt IntegralDomain}: multiplication
+must be commutative and the product of two non-zero elements must not
+be zero.  This allows you to make fractions of most things you would
+think of, but don't expect to create a fraction of two matrices!  The
+abbreviation for {\tt Fraction} is {\tt FRAC}.
+
+Use \spadopFrom{/}{Fraction} to create a fraction.
+
+\spadcommand{a := 11/12 }
+$$
+{11} \over {12} 
+$$
+\returnType{Type: Fraction Integer}
+
+\spadcommand{b := 23/24 }
+$$
+{23} \over {24} 
+$$
+\returnType{Type: Fraction Integer}
+
+The standard arithmetic operations are available.
+
+\spadcommand{3 - a*b**2 + a + b/a }
+$$
+{313271} \over {76032} 
+$$
+\returnType{Type: Fraction Integer}
+
+Extract the numerator and denominator by using
+\spadfunFrom{numer}{Fraction} and \spadfunFrom{denom}{Fraction},
+respectively.
+
+\spadcommand{numer(a) }
+$$
+11 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{denom(b) }
+$$
+24 
+$$
+\returnType{Type: PositiveInteger}
+
+Operations like \spadfunFrom{max}{Fraction},
+\spadfunFrom{min}{Fraction}, \spadfunFrom{negative?}{Fraction},
+\spadfunFrom{positive?}{Fraction} and \spadfunFrom{zero?}{Fraction}
+are all available if they are provided for the numerators and
+denominators.  
+See \ref{IntegerXmpPage} on page~\pageref{IntegerXmpPage} for examples.
+
+Don't expect a useful answer from \spadfunFrom{factor}{Fraction},
+\spadfunFrom{gcd}{Fraction} or \spadfunFrom{lcm}{Fraction} if you apply
+them to fractions.
+
+\spadcommand{r := (x**2 + 2*x + 1)/(x**2 - 2*x + 1) }
+$$
+{{x \sp 2}+{2 \  x}+1} \over {{x \sp 2} -{2 \  x}+1} 
+$$
+\returnType{Type: Fraction Polynomial Integer}
+
+Since all non-zero fractions are invertible, these operations have trivial
+definitions.
+
+\spadcommand{factor(r) }
+$$
+{{x \sp 2}+{2 \  x}+1} \over {{x \sp 2} -{2 \  x}+1} 
+$$
+\returnType{Type: Factored Fraction Polynomial Integer}
+
+Use \spadfunFrom{map}{Fraction} to apply \spadfunFrom{factor}{Fraction} to
+the numerator and denominator, which is probably what you mean.
+
+\spadcommand{map(factor,r) }
+$$
+{{\left( x+1 
+\right)}
+\sp 2} \over {{\left( x -1 
+\right)}
+\sp 2} 
+$$
+\returnType{Type: Fraction Factored Polynomial Integer}
+
+Other forms of fractions are available.  Use {\tt continuedFraction}
+to create a continued fraction.
+
+\spadcommand{continuedFraction(7/12)}
+$$
+\zag{1}{1}+ \zag{1}{1}+ \zag{1}{2}+ \zag{1}{2} 
+$$
+\returnType{Type: ContinuedFraction Integer}
+
+Use {\tt partialFraction} to create a partial fraction.
+See 
+\ref{ContinuedFractionXmpPage} on page~\pageref{ContinuedFractionXmpPage} 
+and \ref{PartialFractionXmpPage} on page~\pageref{PartialFractionXmpPage} for
+additional information and examples.
+
+\spadcommand{partialFraction(7,12)}
+$$
+1 -{3 \over {2 \sp 2}}+{1 \over 3} 
+$$
+\returnType{Type: PartialFraction Integer}
+
+Use conversion to create alternative views of fractions with objects
+moved in and out of the numerator and denominator.
+
+\spadcommand{g := 2/3 + 4/5*\%i }
+$$
+{2 \over 3}+{{4 \over 5} \  i} 
+$$
+\returnType{Type: Complex Fraction Integer}
+
+Conversion is discussed in detail in 
+Section~\ref{ugTypesConvertPage} 
+on page~\pageref{ugTypesConvertPage}.
+
+\spadcommand{g :: FRAC COMPLEX INT }
+$$
+{{10}+{{12} \  i}} \over {15} 
+$$
+\returnType{Type: Fraction Complex Integer}
+
+\section{FullPartialFractionExpansion}
+\label{FullPartialFractionExpansionXmpPage}
+
+The domain {\tt FullPartialFractionExpansion} implements
+factor-free conversion of quotients to full partial fractions.
+
+Our examples will all involve quotients of univariate polynomials
+with rational number coefficients.
+
+\spadcommand{Fx := FRAC UP(x, FRAC INT) }
+$$
+\mbox{\rm Fraction UnivariatePolynomial(x,Fraction Integer)} 
+$$
+\returnType{Type: Domain}
+
+Here is a simple-looking rational function.
+
+\spadcommand{f : Fx := 36 / (x**5-2*x**4-2*x**3+4*x**2+x-2) }
+$$
+{36} \over {{x \sp 5} -{2 \  {x \sp 4}} -{2 \  {x \sp 3}}+{4 \  {x \sp 2}}+x 
+-2} 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+We use \spadfunFrom{fullPartialFraction}{FullPartialFractionExpansion}
+to convert it to an object of type {\tt FullPartialFractionExpansion}.
+
+\spadcommand{g := fullPartialFraction f }
+$$
+{4 \over {x -2}} -{4 \over {x+1}}+
+{\sum \sb{\displaystyle {{{ \%A \sp 2} -1}=0}} 
+{{-{3 \  \%A} -6} \over {{\left( x - \%A \right)}\sp 2}}} 
+$$
+\returnType{Type: FullPartialFractionExpansion(Fraction Integer,UnivariatePolynomial(x,Fraction Integer))}
+
+Use a coercion to change it back into a quotient.
+
+\spadcommand{g :: Fx }
+$$
+{36} \over {{x \sp 5} -{2 \  {x \sp 4}} -{2 \  {x \sp 3}}+{4 \  {x \sp 2}}+x 
+-2} 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+Full partial fractions differentiate faster than rational functions.
+
+\spadcommand{g5 := D(g, 5) }
+$$
+-{{480} \over {{\left( x -2 \right)}\sp 6}}+
+{{480} \over {{\left( x+1 \right)}\sp 6}}+
+{\sum \sb{\displaystyle {{{ \%A \sp 2} -1}=0}} 
+{{{{2160} \   \%A}+{4320}} \over {{\left( x - \%A \right)}\sp 7}}} 
+$$
+\returnType{Type: FullPartialFractionExpansion(Fraction Integer,UnivariatePolynomial(x,Fraction Integer))}
+
+\spadcommand{f5 := D(f, 5) }
+$$
+\left(
+\begin{array}{@{}l}
+-{{544320} \  {x \sp {10}}}+
+{{4354560} \  {x \sp 9}} -
+{{14696640} \  {x \sp 8}}+
+{{28615680} \  {x \sp 7}} -
+\\
+\\
+\displaystyle
+{{40085280} \  {x \sp 6}}+
+{{46656000} \  {x \sp 5}} -
+{{39411360} \  {x \sp 4}}+
+{{18247680} \  {x \sp 3}} -
+\\
+\\
+\displaystyle
+{{5870880} \  {x \sp 2}}+
+{{3317760} \  x}+{246240}
+\end{array}
+\right)
+\over 
+\left(
+\begin{array}{@{}l}
+{x \sp {20}} -
+{{12} \  {x \sp {19}}}+
+{{53} \  {x \sp {18}}} -
+{{76} \  {x \sp {17}}} -
+{{159} \  {x \sp {16}}}+
+{{676} \  {x \sp {15}}} -
+{{391} \  {x \sp {14}}} -
+\\
+\\
+\displaystyle
+{{1596} \  {x \sp {13}}}+
+{{2527} \  {x \sp {12}}}+
+{{1148} \  {x \sp {11}}} -
+{{4977} \  {x \sp {10}}}+
+{{1372} \  {x \sp 9}}+
+\\
+\\
+\displaystyle
+{{4907} \  {x \sp 8}} -
+{{3444} \  {x \sp 7}} 
+-{{2381} \  {x \sp 6}}+
+{{2924} \  {x \sp 5}}+
+{{276} \  {x \sp 4}} -
+\\
+\\
+\displaystyle
+{{1184} \  {x \sp 3}}+
+{{208} \  {x \sp 2}}+
+{{192} \  x} -
+{64} 
+\end{array}
+\right)
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+We can check that the two forms represent the same function.
+
+\spadcommand{g5::Fx - f5 }
+$$
+0 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+Here are some examples that are more complicated.
+
+\spadcommand{f : Fx := (x**5 * (x-1)) / ((x**2 + x + 1)**2 * (x-2)**3) }
+$$
+{{x \sp 6} -
+{x \sp 5}} 
+\over 
+{{x \sp 7} -
+{4 \  {x \sp 6}}+
+{3 \  {x \sp 5}}+
+{9 \  {x \sp 3}} -
+{6 \  {x \sp 2}} -
+{4 \  x} -
+8}
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{g := fullPartialFraction f }
+$$
+\begin{array}{@{}l}
+{{{1952} \over {2401}} \over {x -2}}+
+{{{464} \over {343}} \over {{\left( x -2 \right)}\sp 2}}+
+{{{32} \over {49}} \over {{\left( x -2 \right)}\sp 3}}+
+\\
+\\
+\displaystyle
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+ \%A+1}=0}} 
+{{-{{{179} \over {2401}} \  \%A}+{{135} \over {2401}}} \over {x - \%A}}}+
+\\
+\\
+\displaystyle
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+ \%A+1}=0}} 
+{{{{{37} \over {1029}} \   \%A}+
+{{20} \over {1029}}} \over {{\left( x - \%A \right)}\sp 2}}} 
+\end{array}
+$$
+\returnType{Type: FullPartialFractionExpansion(Fraction Integer,UnivariatePolynomial(x,Fraction Integer))}
+
+\spadcommand{g :: Fx - f }
+$$
+0 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{f : Fx := (2*x**7-7*x**5+26*x**3+8*x) / (x**8-5*x**6+6*x**4+4*x**2-8) }
+$$
+{{2 \  {x \sp 7}} -{7 \  {x \sp 5}}+{{26} \  {x \sp 3}}+{8 \  x}} 
+\over 
+{{x \sp 8} -{5 \  {x \sp 6}}+{6 \  {x \sp 4}}+{4 \  {x \sp 2}} -8} 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{g := fullPartialFraction f }
+$$
+\begin{array}{@{}l}
+{\sum \sb{\displaystyle {{{ \%A \sp 2} -2}=0}} 
+{{1 \over 2} \over {x -  \%A}}}+
+\\
+\\
+\displaystyle
+{\sum \sb{\displaystyle {{{ \%A \sp 2} -2}=0}} 
+{1 \over {{\left( x -  \%A \right)}\sp 3}}}+
+\\
+\\
+\displaystyle
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+1}=0}} 
+{{1 \over 2} \over {x - \%A}}} 
+\end{array}
+$$
+\returnType{Type: FullPartialFractionExpansion(Fraction Integer,UnivariatePolynomial(x,Fraction Integer))}
+
+\spadcommand{g :: Fx - f }
+$$
+0 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{f:Fx := x**3 / (x**21 + 2*x**20 + 4*x**19 + 7*x**18 + 10*x**17 + 17*x**16 + 22*x**15 + 30*x**14 + 36*x**13 + 40*x**12 + 47*x**11 + 46*x**10 + 49*x**9 + 43*x**8 + 38*x**7 + 32*x**6 + 23*x**5 + 19*x**4 + 10*x**3 + 7*x**2 + 2*x + 1)}
+$$
+{x \sp 3} 
+\over 
+\left(
+\begin{array}{@{}l}
+{x \sp {21}}+
+{2 \  {x \sp {20}}}+
+{4 \  {x \sp {19}}}+
+{7 \  {x \sp {18}}}+
+{{10} \  {x \sp {17}}}+
+{{22} \  {x \sp {15}}}+
+{{30} \  {x \sp {14}}}+
+\\
+\\
+\displaystyle
+{{36} \  {x \sp {13}}}+
+{{40} \  {x \sp {12}}}+
+{{47} \  {x \sp {11}}}+
+{{46} \  {x \sp {10}}}+
+{{49} \  {x \sp 9}}+
+{{43} \  {x \sp 8}}+
+{{38} \  {x \sp 7}}+
+\\
+\\
+\displaystyle
+{{32} \  {x \sp 6}}+
+{{23} \  {x \sp 5}}+
+{{19} \  {x \sp 4}}+
+{{10} \  {x \sp 3}}+
+{7 \  {x \sp 2}}+
+{2 \  x}+
+1
+\end{array}
+\right)
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+\spadcommand{g := fullPartialFraction f }
+$$
+\begin{array}{@{}l}
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+1}=0}} 
+{{{1 \over 2} \  \%A} \over {x - \%A}}}+
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+ \%A+1}=0}} 
+{{{{1 \over 9} \   \%A} -{{19} \over {27}}} \over {x - \%A}}}+
+\\
+\\
+\displaystyle
+{\sum \sb{\displaystyle {{{ \%A \sp 2}+ \%A+1}=0}} 
+{{{{1 \over {27}} \  \%A} -{1 \over {27}}} 
+\over {{\left( x - \%A \right)}\sp 2}}}+
+\\
+\\
+\displaystyle
+\sum \sb{\displaystyle {{{ \%A \sp 5}+{ \%A \sp 2}+1}=0}}
+\left(
+\begin{array}{@{}l}
+-{{{96556567040} \over {912390759099}} \  { \%A \sp 4}}+
+{{{420961732891} \over {912390759099}} \  { \%A \sp 3}} -
+\\
+\\
+\displaystyle
+{{{59101056149} \over {912390759099}} \  { \%A \sp 2}} -
+{{{373545875923} \over {912390759099}} \   \%A}+
+\\
+\\
+\displaystyle
+{{529673492498} \over {912390759099}}
+\end{array}
+\right)
+\over {x - \%A}+
+\\
+\\
+\displaystyle
+\sum \sb{\displaystyle {{{ \%A \sp 5}+{ \%A \sp 2}+1}=0}}
+\left(
+\begin{array}{@{}l}
+-{{{5580868} \over {94070601}} \  { \%A \sp 4}} -
+{{{2024443} \over {94070601}} \  { \%A \sp 3}}+
+{{{4321919} \over {94070601}} \  { \%A \sp 2}} -
+\\
+\\
+\displaystyle
+{{{84614} \over {1542141}} \  \%A} -
+{{5070620} \over {94070601}} 
+\end{array}
+\right)
+\over {{\left( x - \%A \right)}\sp 2}+
+\\
+\\
+\displaystyle
+\sum \sb{\displaystyle {{{ \%A \sp 5}+{ \%A \sp 2}+1}=0}} 
+\left(
+\begin{array}{@{}l}
+{{{1610957} \over {94070601}} \  { \%A \sp 4}}+
+{{{2763014} \over {94070601}} \  { \%A \sp 3}} -
+{{{2016775} \over {94070601}} \  { \%A \sp 2}}+
+\\
+\\
+\displaystyle
+{{{266953} \over {94070601}} \  \%A}+
+{{4529359} \over {94070601}}
+\end{array}
+\right)
+\over {{\left( x - \%A \right)}\sp 3} 
+\end{array}
+$$
+\returnType{Type: FullPartialFractionExpansion(Fraction Integer,UnivariatePolynomial(x,Fraction Integer))}
+
+This verification takes much longer than the conversion to
+partial fractions.
+
+\spadcommand{g :: Fx - f }
+$$
+0 
+$$
+\returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)}
+
+For more information, see the paper: Bronstein, M and Salvy, B.
+``Full Partial Fraction Decomposition of Rational Functions,'' 
+{\it Proceedings of ISSAC'93, Kiev}, ACM Press.  Also see
+\ref{PartialFractionXmpPage} on page~\pageref{PartialFractionXmpPage} 
+for standard partial fraction decompositions.
+
+\section{GeneralSparseTable}
+\label{GeneralSparseTableXmpPage}
+
+Sometimes when working with tables there is a natural value to use as
+the entry in all but a few cases.  The {\tt GeneralSparseTable}
+constructor can be used to provide any table type with a default value
+for entries.  See \ref{TableXmpPage} on page~\pageref{TableXmpPage} 
+for general information about tables.  
+
+Suppose we launched a fund-raising campaign to raise fifty thousand dollars.
+To record the contributions, we want a table with strings as keys
+(for the names) and integer entries (for the amount).
+In a data base of cash contributions, unless someone
+has been explicitly entered, it is reasonable to assume they have made
+a zero dollar contribution.
+
+This creates a keyed access file with default entry {\tt 0}.
+
+\spadcommand{patrons: GeneralSparseTable(String, Integer, KeyedAccessFile(Integer), 0) := table() ; }
+\returnType{Type: GeneralSparseTable(String,Integer,KeyedAccessFile Integer,0)}
+
+
+Now {\tt patrons} can be used just as any other table.
+Here we record two gifts.
+
+\spadcommand{patrons."Smith" := 10500 }
+$$
+10500 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{patrons."Jones" := 22000 }
+$$
+22000 
+$$
+\returnType{Type: PositiveInteger}
+
+Now let us look up the size of the contributions from Jones and Stingy.
+
+\spadcommand{patrons."Jones"  }
+$$
+22000 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{patrons."Stingy" }
+$$
+0 
+$$
+\returnType{Type: NonNegativeInteger}
+
+Have we met our seventy thousand dollar goal?
+
+\spadcommand{reduce(+, entries patrons) }
+$$
+32500 
+$$
+\returnType{Type: PositiveInteger}
+
+So the project is cancelled and we can delete the data base:
+
+\spadcommand{)system rm -r kaf*.sdata }
+
+\section{GroebnerFactorizationPackage}
+\label{GroebnerFactorizationPackageXmpPage}
+
+Solving systems of polynomial equations with the Gr\"{o}bner basis
+algorithm can often be very time consuming because, in general, the
+algorithm has exponential run-time.  These systems, which often come
+from concrete applications, frequently have symmetries which are not
+taken advantage of by the algorithm.  However, it often happens in
+this case that the polynomials which occur during the Gr\"{o}bner
+calculations are reducible.  Since Axiom has an excellent polynomial
+factorization algorithm, it is very natural to combine the Gr\"{o}bner
+and factorization algorithms.
+
+{\tt GroebnerFactorizationPackage} exports the
+\spadfunFrom{groebnerFactorize}{GroebnerFactorizationPackage}
+operation which implements a modified Gr\"{o}bner basis algorithm.  In
+this algorithm, each polynomial that is to be put into the partial
+list of the basis is first factored.  The remaining calculation is
+split into as many parts as there are irreducible factors.  Call these
+factors $p_1, \ldots,p_n.$ In the branches corresponding to $p_2,
+\ldots,p_n,$ the factor $p_1$ can be divided out, and so on.  This
+package also contains operations that allow you to specify the
+polynomials that are not zero on the common roots of the final
+Gr\"{o}bner basis.
+
+Here is an example from chemistry.  In a theoretical model of the
+cyclohexan ${\rm C}_6{\rm H}_{12}$, the six carbon atoms each sit in
+the center of gravity of a tetrahedron that has two hydrogen atoms and
+two carbon atoms at its corners.  We first normalize and set the
+length of each edge to 1.  Hence, the distances of one fixed carbon
+atom to each of its immediate neighbours is 1.  We will denote the
+distances to the other three carbon atoms by $x$, $y$ and $z$.
+
+A.~Dress developed a theory to decide whether a set of points
+and distances between them can be realized in an $n$-dimensional space.
+Here, of course, we have $n = 3$.
+
+\spadcommand{mfzn : SQMATRIX(6,DMP([x,y,z],Fraction INT)) := [ [0,1,1,1,1,1], [1,0,1,8/3,x,8/3], [1,1,0,1,8/3,y], [1,8/3,1,0,1,8/3], [1,x,8/3,1,0,1], [1,8/3,y,8/3,1,0] ] }
+$$
+\left[
+\begin{array}{cccccc}
+0 & 1 & 1 & 1 & 1 & 1 \\ 
+1 & 0 & 1 & {8 \over 3} & x & {8 \over 3} \\ 
+1 & 1 & 0 & 1 & {8 \over 3} & y \\ 
+1 & {8 \over 3} & 1 & 0 & 1 & {8 \over 3} \\ 
+1 & x & {8 \over 3} & 1 & 0 & 1 \\ 
+1 & {8 \over 3} & y & {8 \over 3} & 1 & 0 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(6,DistributedMultivariatePolynomial([x,y,z],Fraction Integer))}
+
+For the cyclohexan, the distances have to satisfy this equation.
+
+\spadcommand{eq := determinant mfzn }
+$$
+\begin{array}{@{}l}
+-{{x \sp 2} \  {y \sp 2}}+
+{{{22} \over 3} \  {x \sp 2} \  y} -
+{{{25} \over 9} \  {x \sp 2}}+
+{{{22} \over 3} \  x \  {y \sp 2}} -
+{{{388} \over 9} \  x \  y} -
+\\
+\\
+\displaystyle
+{{{250} \over {27}} \  x} -
+{{{25} \over 9} \  {y \sp 2}} -
+{{{250} \over {27}} \  y}+
+{{14575} \over {81}} 
+\end{array}
+$$
+\returnType{Type: DistributedMultivariatePolynomial([x,y,z],Fraction Integer)}
+
+They also must satisfy the equations
+given by cyclic shifts of the indeterminates.
+
+\spadcommand{groebnerFactorize [eq, eval(eq, [x,y,z], [y,z,x]), eval(eq, [x,y,z], [z,x,y])] }
+$$
+\begin{array}{@{}l}
+\left[
+
+\begin{array}{@{}l}
+\left[ 
+{x \  y}+
+{x \  z} -
+{{{22} \over 3} \  x}+
+{y \  z} -
+{{{22} \over 3} \  y} -
+{{{22} \over 3} \  z}+
+{{121} \over 3}, 
+\right.
+\\
+\\
+\displaystyle
+{x \  {z \sp 2}} -
+{{{22} \over 3} \  x \  z}+
+{{{25} \over 9} \  x}+
+{y \  {z \sp 2}} -
+{{{22} \over 3} \ y \  z}+
+{{{25} \over 9} \  y} -
+{{{22} \over 3} \  {z \sp 2}}+
+{{{388} \over 9} \  z}+
+{{250} \over {27}}, 
+\\
+\\
+\displaystyle
+\left.
+\begin{array}{@{}l}
+{{y \sp 2} \  {z \sp 2}} -
+{{{22} \over 3} \  {y \sp 2} \  z}+
+{{{25} \over 9} \  {y \sp 2}} -
+{{{22} \over 3} \  y \  {z \sp 2}}+
+{{{388} \over 9} \  y \  z}+
+{{{250} \over {27}} \  y}+
+\\
+\\
+\displaystyle
+{{{25} \over 9} \  {z \sp 2}}+
+{{{250} \over {27}} \  z} -
+{{14575} \over {81}}
+\end{array}
+\right],
+\end{array}
+\right.
+\\
+\\
+\displaystyle
+{\left[ 
+{x+y -{{21994} \over {5625}}}, 
+{{y \sp 2} -{{{21994} \over {5625}} \  y}+{{4427} \over {675}}}, 
+{z -{{463} \over {87}}} 
+\right]},
+\\
+\\
+\displaystyle
+{\left[ 
+{{x \sp 2} -
+{{1 \over 2} \  x \  z} -
+{{{11} \over 2} \  x} -
+{{5 \over 6} \  z}+
+{{265} \over {18}}}, 
+{y -z}, 
+{{z \sp 2} -{{{38} \over 3} \  z}+{{265} \over 9}} 
+\right]},
+\\
+\\
+\displaystyle
+{\left[ 
+{x -{{25} \over 9}}, 
+{y -{{11} \over 3}}, 
+{z -{{11} \over 3}} \right]},
+\\
+\\
+\displaystyle
+{\left[ 
+{x -{{11} \over 3}}, 
+{y -{{11} \over 3}}, 
+{z -{{11} \over 3}} 
+\right]},
+\\
+\\
+\displaystyle
+{\left[ 
+{x+{5 \over 3}}, 
+{y+{5 \over 3}}, 
+{z+{5 \over 3}} 
+\right]},
+\\
+\\
+\displaystyle
+\left.
+{\left[ 
+{x -{{19} \over 3}}, 
+{y+{5 \over 3}}, 
+{z+{5 \over 3}} 
+\right]}
+\right]
+\end{array}
+$$
+\returnType{Type: List List 
+DistributedMultivariatePolynomial([x,y,z],Fraction Integer)}
+
+The union of the solutions of this list is the solution of our
+original problem.  If we impose positivity conditions, we get two
+relevant ideals.  One ideal is zero-dimensional, namely $x = y = z = 11/3$, 
+and this determines the ``boat'' form of the cyclohexan.  The
+other ideal is one-dimensional, which means that we have a solution
+space given by one parameter.  This gives the ``chair'' form of the
+cyclohexan.  The parameter describes the angle of the ``back of the
+chair.''
+
+\spadfunFrom{groebnerFactorize}{GroebnerFactorizationPackage} has an
+optional {\tt Boolean}-valued second argument.  When it is {\tt true}
+partial results are displayed, since it may happen that the
+calculation does not terminate in a reasonable time.  See the source
+code for {\tt GroebnerFactorizationPackage} in {\bf groebf.input} 
+for more details about the algorithms used.
+
+\section{Heap}
+\label{HeapXmpPage}
+
+The domain {\tt Heap(S)} implements a priority queue of objects of
+type {\tt S} such that the operation {\tt extract!} removes and
+returns the maximum element.  The implementation represents heaps as
+flexible arrays (see 
+\ref{FlexibleArrayXmpPage} on page~\pageref{FlexibleArrayXmpPage}).  
+The representation and algorithms give complexity of $O(\log(n))$ 
+for insertion and extractions, and $O(n)$ for construction.
+
+Create a heap of six elements.
+
+\spadcommand{h := heap [-4,9,11,2,7,-7]}
+$$
+\left[
+{11}, 7, 9, -4, 2, -7 
+\right]
+$$
+\returnType{Type: Heap Integer}
+
+Use {\tt insert!} to add an element.
+
+\spadcommand{insert!(3,h)}
+$$
+\left[
+{11}, 7, 9, -4, 2, -7, 3 
+\right]
+$$
+\returnType{Type: Heap Integer}
+
+The operation {\tt extract!} removes and returns the maximum element.
+
+\spadcommand{extract! h}
+$$
+11 
+$$
+\returnType{Type: PositiveInteger}
+
+The internal structure of {\tt h} has been appropriately adjusted.
+
+\spadcommand{h}
+$$
+\left[
+9, 7, 3, -4, 2, -7 
+\right]
+$$
+\returnType{Type: Heap Integer}
+
+Now {\tt extract!} elements repeatedly until none are left, collecting
+the elements in a list.
+
+\spadcommand{[extract!(h) while not empty?(h)]}
+$$
+\left[
+9, 7, 3, 2, -4, -7 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Another way to produce the same result is by defining a {\tt heapsort}
+function.
+
+\spadcommand{heapsort(x) == (empty? x => []; cons(extract!(x),heapsort x))}
+\returnType{Void}
+
+Create another sample heap.
+
+\spadcommand{h1 := heap [17,-4,9,-11,2,7,-7]}
+$$
+\left[
+{17}, 2, 9, -{11}, -4, 7, -7 
+\right]
+$$
+\returnType{Type: Heap Integer}
+
+Apply {\tt heapsort} to present elements in order.
+
+\spadcommand{heapsort h1}
+$$
+\left[
+{17}, 9, 7, 2, -4, -7, -{11} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+\section{HexadecimalExpansion}
+\label{HexadecimalExpansionXmpPage}
+
+All rationals have repeating hexadecimal expansions.  The operation
+\spadfunFrom{hex}{HexadecimalExpansion} returns these expansions of
+type {\tt HexadecimalExpansion}.  Operations to access the individual
+numerals of a hexadecimal expansion can be obtained by converting the
+value to {\tt RadixExpansion(16)}.  More examples of expansions are
+available in the 
+\ref{DecimalExpansionXmpPage} on page~\pageref{DecimalExpansionXmpPage},
+\ref{BinaryExpansionXmpPage} on page~\pageref{BinaryExpansionXmpPage}, and 
+\ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}.
+
+This is a hexadecimal expansion of a rational number.
+
+\spadcommand{r := hex(22/7) }
+$$
+3.{\overline {249}} 
+$$
+\returnType{Type: HexadecimalExpansion}
+
+Arithmetic is exact.
+
+\spadcommand{r + hex(6/7) }
+$$
+4 
+$$
+\returnType{Type: HexadecimalExpansion}
+
+The period of the expansion can be short or long \ldots
+
+\spadcommand{[hex(1/i) for i in 350..354] }
+$$
+\begin{array}{@{}l}
+\left[
+{0.0{\overline {\rm 0BB3EE721A54D88}}}, 
+{0.{\overline {\rm 00BAB6561}}}, 
+{0.{00}{\overline {\rm BA2E8}}}, 
+\right.
+\\
+\\
+\displaystyle
+\left.
+{0.{\overline {\rm 00B9A7862A0FF465879D5F}}}, 
+{0.0{\overline {\rm 0B92143FA36F5E02E4850FE8DBD78}}} 
+\right]
+\end{array}
+$$
+\returnType{Type: List HexadecimalExpansion}
+
+or very long!
+
+\spadcommand{hex(1/1007) }
+$$
+\begin{array}{@{}l}
+0.{\overline 
+{\rm 0041149783F0BF2C7D13933192AF6980619EE345E91EC2BB9D5CC}}
+\\
+\displaystyle
+\ \ {\overline
+{\rm A5C071E40926E54E8DDAE24196C0B2F8A0AAD60DBA57F5D4C8}}
+\\
+\displaystyle
+\ \ {\overline
+{\rm 536262210C74F1}}
+\end{array}
+$$
+\returnType{Type: HexadecimalExpansion}
+
+These numbers are bona fide algebraic objects.
+
+\spadcommand{p := hex(1/4)*x**2 + hex(2/3)*x + hex(4/9)  }
+$$
+{{0.4} \  {x \sp 2}}+{{0.{\overline {\rm A}}} \  x}+{0.{\overline {\rm 71C}}} 
+$$
+\returnType{Type: Polynomial HexadecimalExpansion}
+
+\spadcommand{q := D(p, x) }
+$$
+{{0.8} \  x}+{0.{\overline {\rm A}}} 
+$$
+\returnType{Type: Polynomial HexadecimalExpansion}
+
+\spadcommand{g := gcd(p, q)}
+$$
+x+{1.{\overline 5}} 
+$$
+\returnType{Type: Polynomial HexadecimalExpansion}
+
+\section{Integer}
+\label{IntegerXmpPage}
+
+Axiom provides many operations for manipulating arbitrary precision
+integers.  In this section we will show some of those that come from
+{\tt Integer} itself plus some that are implemented in other packages.
+More examples of using integers are in the following sections:
+\ref{ugIntroNumbersPage} on page~\pageref{ugIntroNumbersPage} in section 
+\ref{ugIntroNumbersNumber} on page~\pageref{ugIntroNumbersNumber}
+\ref{IntegerNumberTheoryFunctionsXmpPage} on 
+page~\pageref{IntegerNumberTheoryFunctionsXmpPage},
+\ref{DecimalExpansionXmpPage} on page~\pageref{DecimalExpansionXmpPage}, 
+\ref{BinaryExpansionXmpPage} on page~\pageref{BinaryExpansionXmpPage},
+\ref{HexadecimalExpansionXmpPage} on 
+page~\pageref{HexadecimalExpansionXmpPage}, and 
+\ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}.
+
+\subsection{Basic Functions}
+
+The size of an integer in Axiom is only limited by the amount of
+computer storage you have available.  The usual arithmetic operations
+are available.
+
+\spadcommand{2**(5678 - 4856 + 2 * 17)}
+$$
+\begin{array}{@{}l}
+48048107704350081471815409251259243912395261398716822634738556100
+\\
+\displaystyle
+88084200076308293086342527091412083743074572278211496076276922026
+\\
+\displaystyle
+43343568752733498024953930242542523045817764949544214392905306388
+\\
+\displaystyle
+478705146745768073877141698859815495632935288783334250628775936
+\end{array}
+$$
+\returnType{Type: PositiveInteger}
+
+There are a number of ways of working with the sign of an integer.
+Let's use this {\tt x} as an example.
+
+\spadcommand{x := -101 }
+$$
+-{101} 
+$$
+\returnType{Type: Integer}
+
+First of all, there is the absolute value function.
+
+\spadcommand{abs(x) }
+$$
+101 
+$$
+\returnType{Type: PositiveInteger}
+
+The \spadfunFrom{sign}{Integer} operation returns {\tt -1} if its argument
+is negative, {\tt 0} if zero and {\tt 1} if positive.
+
+\spadcommand{sign(x) }
+$$
+-1 
+$$
+\returnType{Type: Integer}
+
+You can determine if an integer is negative in several other ways.
+
+\spadcommand{x < 0 }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{x <= -1 }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{negative?(x) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+Similarly, you can find out if it is positive.
+
+\spadcommand{x > 0 }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{x >= 1 }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{positive?(x) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+This is the recommended way of determining whether an integer is zero.
+
+\spadcommand{zero?(x) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+\boxed{4.6in}{
+\vskip 0.1cm
+Use the \spadfunFrom{zero?}{Integer} operation whenever you are
+testing any mathematical object for equality with zero.  This is
+usually more efficient that using {\tt =} (think of matrices: it is
+easier to tell if a matrix is zero by just checking term by term than
+constructing another ``zero'' matrix and comparing the two matrices
+term by term) and also avoids the problem that {\tt =} is usually used
+for creating equations.\\
+}
+
+This is the recommended way of determining whether an integer is equal
+to one.
+
+\spadcommand{one?(x) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+This syntax is used to test equality using \spadopFrom{=}{Integer}.
+It says that you want a {\tt Boolean} ({\tt true} or {\tt false})
+answer rather than an equation.
+
+\spadcommand{(x = -101)@Boolean }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+The operations \spadfunFrom{odd?}{Integer} and
+\spadfunFrom{even?}{Integer} determine whether an integer is odd or
+even, respectively.  They each return a {\tt Boolean} object.
+
+\spadcommand{odd?(x) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{even?(x) }
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+The operation \spadfunFrom{gcd}{Integer} computes the greatest common
+divisor of two integers.
+
+\spadcommand{gcd(56788,43688)}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+The operation \spadfunFrom{lcm}{Integer} computes their least common multiple.
+
+\spadcommand{lcm(56788,43688)}
+$$
+620238536 
+$$
+\returnType{Type: PositiveInteger}
+
+To determine the maximum of two integers, use \spadfunFrom{max}{Integer}.
+
+\spadcommand{max(678,567)}
+$$
+678 
+$$
+\returnType{Type: PositiveInteger}
+
+To determine the minimum, use \spadfunFrom{min}{Integer}.
+
+\spadcommand{min(678,567)}
+$$
+567 
+$$
+\returnType{Type: PositiveInteger}
+
+The {\tt reduce} operation is used to extend binary operations to more
+than two arguments.  For example, you can use {\tt reduce} to find the
+maximum integer in a list or compute the least common multiple of all
+integers in the list.
+
+\spadcommand{reduce(max,[2,45,-89,78,100,-45])}
+$$
+100 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{reduce(min,[2,45,-89,78,100,-45])}
+$$
+-{89} 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{reduce(gcd,[2,45,-89,78,100,-45])}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{reduce(lcm,[2,45,-89,78,100,-45])}
+$$
+1041300 
+$$
+\returnType{Type: PositiveInteger}
+
+The infix operator ``/'' is {\it not} used to compute the quotient of
+integers.  Rather, it is used to create rational numbers as described
+in \ref{FractionXmpPage} on page~\pageref{FractionXmpPage}.
+
+\spadcommand{13 / 4}
+$$
+{13} \over 4 
+$$
+\returnType{Type: Fraction Integer}
+
+The infix operation \spadfunFrom{quo}{Integer} computes the integer
+quotient.
+
+\spadcommand{13 quo 4}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+The infix operation \spadfunFrom{rem}{Integer} computes the integer
+remainder.
+
+\spadcommand{13 rem 4}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+One integer is evenly divisible by another if the remainder is zero.
+The operation \spadfunFrom{exquo}{Integer} can also be used.  See
+\ref{ugTypesUnionsPage} on page~\pageref{ugTypesUnionsPage} in Section 
+\ref{ugTypesUnionsNumber} on page~\pageref{ugTypesUnionsNumber} for an
+example.
+
+\spadcommand{zero?(167604736446952 rem 2003644)}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+The operation \spadfunFrom{divide}{Integer} returns a record of the
+quotient and remainder and thus is more efficient when both are needed.
+
+\spadcommand{d := divide(13,4) }
+$$
+\left[
+{quotient=3}, {remainder=1} 
+\right]
+$$
+\returnType{Type: Record(quotient: Integer,remainder: Integer)}
+
+\spadcommand{d.quotient }
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+Records are discussed in detail in Section 
+\ref{ugTypesRecords} on page~\pageref{ugTypesRecords}.
+
+\spadcommand{d.remainder }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\subsection{Primes and Factorization}
+
+Use the operation \spadfunFrom{factor}{Integer} to factor integers.
+It returns an object of type {\tt Factored Integer}.
+See \ref{FactoredXmpPage} on page~\pageref{FactoredXmpPage} 
+for a discussion of the manipulation of factored objects.
+
+\spadcommand{factor 102400}
+$$
+{2 \sp {12}} \  {5 \sp 2} 
+$$
+\returnType{Type: Factored Integer}
+
+The operation \spadfunFrom{prime?}{Integer} returns {\tt true} or 
+{\tt false} depending on whether its argument is a prime.
+
+\spadcommand{prime? 7}
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+\spadcommand{prime? 8}
+$$
+{\tt false} 
+$$
+\returnType{Type: Boolean}
+
+The operation \spadfunFrom{nextPrime}{IntegerPrimesPackage} returns the
+least prime number greater than its argument.
+
+\spadcommand{nextPrime 100}
+$$
+101 
+$$
+\returnType{Type: PositiveInteger}
+
+The operation \spadfunFrom{prevPrime}{IntegerPrimesPackage} returns
+the greatest prime number less than its argument.
+
+\spadcommand{prevPrime 100}
+$$
+97 
+$$
+\returnType{Type: PositiveInteger}
+
+To compute all primes between two integers (inclusively), use the
+operation \spadfunFrom{primes}{IntegerPrimesPackage}.
+
+\spadcommand{primes(100,175)}
+$$
+\left[
+{173}, {167}, {163}, {157}, {151}, {149}, {139}, {137}, 
+{131}, {127}, {113}, {109}, {107}, {103}, {101} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+You might sometimes want to see the factorization of an integer
+when it is considered a {\it Gaussian integer}.
+See \ref{ComplexXmpPage} on page~\pageref{ComplexXmpPage} for more details.
+
+\spadcommand{factor(2 :: Complex Integer)}
+$$
+-{i \  {{\left( 1+i 
+\right)}
+\sp 2}} 
+$$
+\returnType{Type: Factored Complex Integer}
+
+\subsection{Some Number Theoretic Functions}
+
+Axiom provides several number theoretic operations for integers.
+More examples are in \ref{IntegerNumberTheoryFunctionsXmpPage} on 
+page~\pageref{IntegerNumberTheoryFunctionsXmpPage}.
+
+The operation \spadfunFrom{fibonacci}{IntegerNumberTheoryFunctions}
+computes the Fibonacci numbers.  The algorithm has running time
+$O\,(\log^3(n))$ for argument {\tt n}.
+
+\spadcommand{[fibonacci(k) for k in 0..]}
+$$
+\left[
+0, 1, 1, 2, 3, 5, 8, {13}, {21}, {34}, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+The operation \spadfunFrom{legendre}{IntegerNumberTheoryFunctions}
+computes the Legendre symbol for its two integer arguments where the
+second one is prime.  If you know the second argument to be prime, use
+\spadfunFrom{jacobi}{IntegerNumberTheoryFunctions} instead where no
+check is made.
+
+\spadcommand{[legendre(i,11) for i in 0..10]}
+$$
+\left[
+0, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1 
+\right]
+$$
+\returnType{Type: List Integer}
+
+The operation \spadfunFrom{jacobi}{IntegerNumberTheoryFunctions}
+computes the Jacobi symbol for its two integer arguments.  By
+convention, {\tt 0} is returned if the greatest common divisor of the
+numerator and denominator is not {\tt 1}.
+
+\spadcommand{[jacobi(i,15) for i in 0..9]}
+$$
+\left[
+0, 1, 1, 0, 1, 0, 0, -1, 1, 0 
+\right]
+$$
+\returnType{Type: List Integer}
+
+The operation \spadfunFrom{eulerPhi}{IntegerNumberTheoryFunctions}
+computes the values of Euler's $\phi$-function where $\phi(n)$ equals
+the number of positive integers less than or equal to {\tt n} that are
+relatively prime to the positive integer {\tt n}.
+
+\spadcommand{[eulerPhi i for i in 1..]}
+$$
+\left[
+1, 1, 2, 2, 4, 2, 6, 4, 6, 4, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+The operation \spadfunFrom{moebiusMu}{IntegerNumberTheoryFunctions}
+computes the M\"{o}bius $\mu$ function.
+
+\spadcommand{[moebiusMu i for i in 1..]}
+$$
+\left[
+1, -1, -1, 0, -1, 1, -1, 0, 0, 1, \ldots 
+\right]
+$$
+\returnType{Type: Stream Integer}
+
+Although they have somewhat limited utility, Axiom provides Roman numerals.
+
+\spadcommand{a := roman(78) }
+$$
+{\rm LXXVIII }
+$$
+\returnType{Type: RomanNumeral}
+
+\spadcommand{b := roman(87) }
+$$
+{\rm LXXXVII }
+$$
+\returnType{Type: RomanNumeral}
+
+\spadcommand{a + b }
+$$
+{\rm CLXV }
+$$
+\returnType{Type: RomanNumeral}
+
+\spadcommand{a * b }
+$$
+{\rm MMMMMMDCCLXXXVI }
+$$
+\returnType{Type: RomanNumeral}
+
+\spadcommand{b rem a }
+$$
+{\rm IX }
+$$
+\returnType{Type: RomanNumeral}
+
+\section{IntegerLinearDependence}
+\label{IntegerLinearDependenceXmpPage}
+
+The elements $v_1, \dots,v_n$ of a module {\tt M} over a ring {\tt R}
+are said to be {\it linearly dependent over {\tt R}} if there exist
+$c_1,\dots,c_n$ in {\tt R}, not all $0$, such that $c_1 v_1 +
+\dots c_n v_n = 0$.  If such $c_i$'s exist, they form what is called a
+{\it linear dependence relation over {\tt R}} for the $v_i$'s.
+
+The package {\tt IntegerLinearDependence} provides functions
+for testing whether some elements of a module over the integers are
+linearly dependent over the integers, and to find the linear
+dependence relations, if any.
+
+Consider the domain of two by two square matrices with integer entries.
+
+\spadcommand{M := SQMATRIX(2,INT) }
+$$
+SquareMatrix(2,Integer) 
+$$
+\returnType{Type: Domain}
+
+Now create three such matrices.
+
+\spadcommand{m1: M := squareMatrix matrix [ [1, 2], [0, -1] ] }
+$$
+\left[
+\begin{array}{cc}
+1 & 2 \\ 
+0 & -1 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+\spadcommand{m2: M := squareMatrix matrix [ [2, 3], [1, -2] ] }
+$$
+\left[
+\begin{array}{cc}
+2 & 3 \\ 
+1 & -2 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+\spadcommand{m3: M := squareMatrix matrix [ [3, 4], [2, -3] ] }
+$$
+\left[
+\begin{array}{cc}
+3 & 4 \\ 
+2 & -3 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+This tells you whether {\tt m1}, {\tt m2} and {\tt m3} are linearly
+dependent over the integers.
+
+\spadcommand{linearlyDependentOverZ? vector [m1, m2, m3] }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+Since they are linearly dependent, you can ask for the dependence relation.
+
+\spadcommand{c := linearDependenceOverZ vector [m1, m2, m3] }
+$$
+\left[
+1, -2, 1 
+\right]
+$$
+\returnType{Type: Union(Vector Integer,...)}
+
+This means that the following linear combination should be {\tt 0}.
+
+\spadcommand{c.1 * m1 + c.2 * m2 + c.3 * m3 }
+$$
+\left[
+\begin{array}{cc}
+0 & 0 \\ 
+0 & 0 
+\end{array}
+\right]
+$$
+\returnType{Type: SquareMatrix(2,Integer)}
+
+When a given set of elements are linearly dependent over {\tt R}, this
+also means that at least one of them can be rewritten as a linear
+combination of the others with coefficients in the quotient field of
+{\tt R}.
+
+To express a given element in terms of other elements, use the operation
+\spadfunFrom{solveLinearlyOverQ}{IntegerLinearDependence}.
+
+\spadcommand{solveLinearlyOverQ(vector [m1, m3], m2) }
+$$
+\left[
+{1 \over 2}, {1 \over 2} 
+\right]
+$$
+\returnType{Type: Union(Vector Fraction Integer,...)}
+
+\section{IntegerNumberTheoryFunctions}
+\label{IntegerNumberTheoryFunctionsXmpPage}
+
+The {\tt IntegerNumberTheoryFunctions} package contains a variety of
+operations of interest to number theorists.  Many of these operations
+deal with divisibility properties of integers.  (Recall that an
+integer {\tt a} divides an integer {\tt b} if there is an integer 
+{\tt c} such that {\tt b = a * c}.)
+
+The operation \spadfunFrom{divisors}{IntegerNumberTheoryFunctions}
+returns a list of the divisors of an integer.
+
+\spadcommand{div144 := divisors(144) }
+$$
+\left[
+1, 2, 3, 4, 6, 8, 9, {12}, {16}, {18}, {24}, 
+{36}, {48}, {72}, {144} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+You can now compute the number of divisors of {\tt 144} and the sum of
+the divisors of {\tt 144} by counting and summing the elements of the
+list we just created.
+
+\spadcommand{\#(div144) }
+$$
+15 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{reduce(+,div144) }
+$$
+403 
+$$
+\returnType{Type: PositiveInteger}
+
+Of course, you can compute the number of divisors of an integer 
+{\tt n}, usually denoted {\tt d(n)}, and the sum of the divisors of an
+integer {\tt n}, usually denoted {\tt $\sigma$(n)}, without ever
+listing the divisors of {\tt n}.
+
+In Axiom, you can simply call the operations
+\spadfunFrom{numberOfDivisors}{IntegerNumberTheoryFunctions} and
+\spadfunFrom{sumOfDivisors}{IntegerNumberTheoryFunctions}.
+
+\spadcommand{numberOfDivisors(144)}
+$$
+15 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{sumOfDivisors(144)}
+$$
+403 
+$$
+\returnType{Type: PositiveInteger}
+
+The key is that {\tt d(n)} and {\tt $\sigma$(n)} are ``multiplicative
+functions.''  This means that when {\tt n} and {\tt m} are relatively
+prime, that is, when {\tt n} and {\tt m} have no prime factor in
+common, then {\tt d(nm) = d(n) d(m)} and {\tt $\sigma$(nm) =
+$\sigma$(n) $\sigma$(m)}.  Note that these functions are trivial to
+compute when {\tt n} is a prime power and are computed for general
+{\tt n} from the prime factorization of {\tt n}.  Other examples of
+multiplicative functions are {\tt $\sigma_k$(n)}, the sum of the
+$k$-th powers of the divisors of {\tt n} and $\varphi(n)$, the
+number of integers between 1 and {\tt n} which are prime to {\tt n}.
+The corresponding Axiom operations are called
+\spadfunFrom{sumOfKthPowerDivisors}{IntegerNumberTheoryFunctions} and
+\spadfunFrom{eulerPhi}{IntegerNumberTheoryFunctions}.
+
+An interesting function is {\tt $\mu$(n)}, the M\"{o}bius $\mu$
+function, defined as follows: {\tt $\mu$(1) = 1}, {\tt $\mu$(n) = 0},
+when {\tt n} is divisible by a square, and {\tt $\mu = {(-1)}^k$, when
+{\tt n} is the product of {\tt k} distinct primes.  The corresponding
+Axiom operation is \spadfunFrom{moebiusMu}{IntegerNumberTheoryFunctions}.  
+This function occurs in the following theorem:
+
+\noindent
+
+{\bf Theorem} (M\"{o}bius Inversion Formula): \newline Let {\tt f(n)}
+be a function on the positive integers and let {\tt F(n)} be defined
+by $${F(n) = \sum_{d \mid n} f(n)}$$ sum of {\tt f(n)} over
+{\tt d | n}} where the sum is taken over the positive divisors of 
+{\tt n}.  Then the values of {\tt f(n)} can be recovered from the values of
+{\tt F(n)}: 
+$${f(n) = \sum_{d \mid n} \mu(n) F({{n}\over{d}})}$$
+where again the sum is taken over the positive divisors of {\tt n}.
+
+When {\tt f(n) = 1}, then {\tt F(n) = d(n)}.  Thus, if you sum $\mu(d)
+\cdot d(n/d)$ over the positive divisors {\tt d} of {\tt n}, you
+should always get {\tt 1}.
+
+\spadcommand{f1(n) == reduce(+,[moebiusMu(d) * numberOfDivisors(quo(n,d)) for d in divisors(n)]) }
+\returnType{Void}
+
+\spadcommand{f1(200) }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{f1(846) }
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+Similarly, when {\tt f(n) = n}, then {\tt F(n) = $\sigma$(n)}.  Thus,
+if you sum {\tt $\mu$(d) $\cdot$ $\sigma$(n/d)} over the positive
+divisors {\tt d} of {\tt n}, you should always get {\tt n}.
+
+\spadcommand{f2(n) == reduce(+,[moebiusMu(d) * sumOfDivisors(quo(n,d)) for d in divisors(n)]) }
+\returnType{Void}
+
+\spadcommand{f2(200) }
+$$
+200 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{f2(846) }
+$$
+846 
+$$
+\returnType{Type: PositiveInteger}
+
+The Fibonacci numbers are defined by $F(1) = F(2) = 1$ and
+$F(n) = F(n-1) + F(n-2)$ for $n = 3,4,\ldots$.
+
+The operation \spadfunFrom{fibonacci}{IntegerNumberTheoryFunctions}
+computes the $n$-th Fibonacci number.
+
+\spadcommand{fibonacci(25)}
+$$
+75025 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{[fibonacci(n) for n in 1..15]}
+$$
+\left[
+1, 1, 2, 3, 5, 8, {13}, {21}, {34}, {55}, {89}, 
+{144}, {233}, {377}, {610} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Fibonacci numbers can also be expressed as sums of binomial coefficients.
+
+\spadcommand{fib(n) == reduce(+,[binomial(n-1-k,k) for k in 0..quo(n-1,2)]) }
+\returnType{Void}
+
+\spadcommand{fib(25) }
+$$
+75025 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{[fib(n) for n in 1..15] }
+$$
+\left[
+1, 1, 2, 3, 5, 8, {13}, {21}, {34}, {55}, {89}, 
+{144}, {233}, {377}, {610} 
+\right]
+$$
+\returnType{Type: List Integer}
+
+Quadratic symbols can be computed with the operations
+\spadfunFrom{legendre}{IntegerNumberTheoryFunctions} and
+\spadfunFrom{jacobi}{IntegerNumberTheoryFunctions}.  The Legendre
+symbol $\left({a \over p}\right)$ is defined for integers $a$ and
+$p$ with $p$ an odd prime number.  By definition, 
+$\left({a\over p}\right)$ = +1, when $a$ is a square $({\rm mod\ }p)$,
+$\left({a \over p}\right)$ = -1, when $a$ is not a square $({\rm mod\ }p)$,
+and $\left({a \over p}\right)$ = 0, when $a$ is divisible by $p$.
+
+You compute $\left({a \over p}\right)$ via the command {\tt legendre(a,p)}.
+
+\spadcommand{legendre(3,5)}
+$$
+-1 
+$$
+\returnType{Type: Integer}
+
+\spadcommand{legendre(23,691)}
+$$
+-1 
+$$
+\returnType{Type: Integer}
+
+The Jacobi symbol $\left({a \over n}\right)$ is the usual extension of
+the Legendre symbol, where {\tt n} is an arbitrary integer.  The most
+important property of the Jacobi symbol is the following: if {\tt K}
+is a quadratic field with discriminant {\tt d} and quadratic character
+$\chi$, then $\chi(n) = (d/n)$.  Thus, you can use the Jacobi symbol
+to compute, say, the class numbers of imaginary quadratic fields from
+a standard class number formula.
+
+This function computes the class number of the imaginary quadratic
+field with discriminant {\tt d}.
+
+\spadcommand{h(d) == quo(reduce(+, [jacobi(d,k) for k in 1..quo(-d, 2)]), 2 - jacobi(d,2)) }
+\returnType{Void}
+
+\spadcommand{h(-163) }   
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{h(-499) }   
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{h(-1832) }
+$$
+26 
+$$
+\returnType{Type: PositiveInteger}
+
+\section{Kernel}
+\label{KernelXmpPage}
+
+A {\it kernel} is a symbolic function application (such as {\tt sin(x+ y)}) 
+or a symbol (such as {\tt x}).  More precisely, a non-symbol
+kernel over a set {\it S} is an operator applied to a given list of
+arguments from {\it S}.  The operator has type {\tt BasicOperator}
+(see \ref{BasicOperatorXmpPage} on page~\pageref{BasicOperatorXmpPage}) 
+and the kernel object is usually part of an expression object (see 
+\ref{ExpressionXmpPage} on page~\pageref{ExpressionXmpPage}).
+
+Kernels are created implicitly for you when you create expressions.
+
+\spadcommand{x :: Expression Integer}
+$$
+x 
+$$
+\returnType{Type: Expression Integer}
+
+You can directly create a ``symbol'' kernel by using the
+\spadfunFrom{kernel}{Kernel} operation.
+
+\spadcommand{kernel x}
+$$
+x 
+$$
+\returnType{Type: Kernel Expression Integer}
+
+This expression has two different kernels.
+
+\spadcommand{sin(x) + cos(x) }
+$$
+{\sin 
+\left(
+{x} 
+\right)}+{\cos
+\left(
+{x} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+The operator \spadfunFrom{kernels}{Expression} returns a list of the
+kernels in an object of type {\tt Expression}.
+
+\spadcommand{kernels \% }
+$$
+\left[
+{\sin 
+\left(
+{x} 
+\right)},
+{\cos 
+\left(
+{x} 
+\right)}
+\right]
+$$
+\returnType{Type: List Kernel Expression Integer}
+
+This expression also has two different kernels.
+
+\spadcommand{sin(x)**2 + sin(x) + cos(x) }
+$$
+{{\sin 
+\left(
+{x} 
+\right)}
+\sp 2}+{\sin 
+\left(
+{x} 
+\right)}+{\cos
+\left(
+{x} 
+\right)}
+$$
+\returnType{Type: Expression Integer}
+
+The {\tt sin(x)} kernel is used twice.
+
+\spadcommand{kernels \% }
+$$
+\left[
+{\sin 
+\left(
+{x} 
+\right)},
+{\cos 
+\left(
+{x} 
+\right)}
+\right]
+$$
+\returnType{Type: List Kernel Expression Integer}
+
+An expression need not contain any kernels.
+
+\spadcommand{kernels(1 :: Expression Integer)}
+$$
+\left[\ 
+\right]
+$$
+\returnType{Type: List Kernel Expression Integer}
+
+If one or more kernels are present, one of them is
+designated the {\it main} kernel.
+
+\spadcommand{mainKernel(cos(x) + tan(x))}
+$$
+\tan 
+\left(
+{x} 
+\right)
+$$
+\returnType{Type: Union(Kernel Expression Integer,...)}
+
+Kernels can be nested. Use \spadfunFrom{height}{Kernel} to determine
+the nesting depth.
+
+\spadcommand{height kernel x}
+$$
+1 
+$$
+\returnType{Type: PositiveInteger}
+
+This has height 2 because the {\tt x} has height 1 and then we apply
+an operator to that.
+
+\spadcommand{height mainKernel(sin x)}
+$$
+2 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{height mainKernel(sin cos x)}
+$$
+3 
+$$
+\returnType{Type: PositiveInteger}
+
+\spadcommand{height mainKernel(sin cos (tan x + sin x))}
+$$
+4 
+$$
+\returnType{Type: PositiveInteger}
+
+Use the \spadfunFrom{operator}{Kernel} operation to extract the
+operator component of the kernel.  The operator has type {\tt BasicOperator}.
+
+\spadcommand{operator mainKernel(sin cos (tan x + sin x))}
+$$
+\sin 
+$$
+\returnType{Type: BasicOperator}
+
+Use the \spadfunFrom{name}{Kernel} operation to extract the name of
+the operator component of the kernel.  The name has type {\tt Symbol}.
+This is really just a shortcut for a two-step process of extracting
+the operator and then calling \spadfunFrom{name}{BasicOperator} on
+the operator.
+
+\spadcommand{name mainKernel(sin cos (tan x + sin x))}
+$$
+\sin 
+$$
+\returnType{Type: Symbol}
+
+Axiom knows about functions such as {\tt sin}, {\tt cos} and so on and
+can make kernels and then expressions using them.  To create a kernel
+and expression using an arbitrary operator, use
+\spadfunFrom{operator}{BasicOperator}.
+
+Now {\tt f} can be used to create symbolic function applications.
+
+\spadcommand{f := operator 'f }
+$$
+f 
+$$
+\returnType{Type: BasicOperator}
+
+\spadcommand{e := f(x, y, 10) }
+$$
+f 
+\left(
+{x, y, {10}} 
+\right)
+$$
+\returnType{Type: Expression Integer}
+
+Use the \spadfunFrom{is?}{Kernel} operation to learn if the
+operator component of a kernel is equal to a given operator.
+
+\spadcommand{is?(e, f) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+You can also use a symbol or a string as the second argument to
+\spadfunFrom{is?}{Kernel}.
+
+\spadcommand{is?(e, 'f) }
+$$
+{\tt true} 
+$$
+\returnType{Type: Boolean}
+
+Use the \spadfunFrom{argument}{Kernel} operation to get a list containing
+the argument component of a kernel.
+
+\spadcommand{argument mainKernel e }
+$$
+\left[
+x, y, {10} 
+\right]
+$$
+\returnType{Type: List Expression Integer}
+
+Conceptually, an object of ty