diff options
author | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
commit | ab8cc85adde879fb963c94d15675783f2cf4b183 (patch) | |
tree | c202482327f474583b750b2c45dedfc4e4312b1d /src/hyper/pages/ug01.ht | |
download | open-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz |
Initial population.
Diffstat (limited to 'src/hyper/pages/ug01.ht')
-rw-r--r-- | src/hyper/pages/ug01.ht | 2591 |
1 files changed, 2591 insertions, 0 deletions
diff --git a/src/hyper/pages/ug01.ht b/src/hyper/pages/ug01.ht new file mode 100644 index 00000000..b193daeb --- /dev/null +++ b/src/hyper/pages/ug01.ht @@ -0,0 +1,2591 @@ +% Copyright The Numerical Algorithms Group Limited 1992-94. All rights reserved. +% !! DO NOT MODIFY THIS FILE BY HAND !! Created by ht.awk. + +\texht{\setcounter{chapter}{0}}{} % Chapter 1 + + +% +\newcommand{\ugIntroTitle}{An Overview of \Language{}} +\newcommand{\ugIntroNumber}{1.} +% +% ===================================================================== +\begin{page}{ugIntroPage}{1. An Overview of \Language{}} +% ===================================================================== +\beginscroll + +Welcome to the \Language{} environment for interactive computation +and problem solving. +Consider this chapter a brief, whirlwind tour of the \Language{} +world. +We introduce you to \Language{}'s graphics and the \Language{} +language. +Then we give a sampling of the large variety of facilities +in the \Language{} 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 \Language{} on some details. +Others can skip right immediately to +\downlink{``\ugIntroTypoTitle''}{ugIntroTypoPage} in Section \ugIntroTypoNumber\ignore{ugIntroTypo}. + +\beginmenu + \menudownlink{{1.1. Starting Up and Winding Down}}{ugIntroStartPage} + \menudownlink{{1.2. Typographic Conventions}}{ugIntroTypoPage} + \menudownlink{{1.3. The \Language{} Language}}{ugIntroExpressionsPage} + \menudownlink{{1.4. Graphics}}{ugIntroGraphicsPage} + \menudownlink{{1.5. Numbers}}{ugIntroNumbersPage} + \menudownlink{{1.6. Data Structures}}{ugIntroCollectPage} + \menudownlink{{1.7. Expanding to Higher Dimensions}}{ugIntroTwoDimPage} + \menudownlink{{1.8. Writing Your Own Functions}}{ugIntroYouPage} + \menudownlink{{1.9. Polynomials}}{ugIntroVariablesPage} + \menudownlink{{1.10. Limits}}{ugIntroCalcLimitsPage} + \menudownlink{{1.11. Series}}{ugIntroSeriesPage} + \menudownlink{{1.12. Derivatives}}{ugIntroCalcDerivPage} + \menudownlink{{1.13. Integration}}{ugIntroIntegratePage} + \menudownlink{{1.14. Differential Equations}}{ugIntroDiffEqnsPage} + \menudownlink{{1.15. Solution of Equations}}{ugIntroSolutionPage} + \menudownlink{{1.16. System Commands}}{ugIntroSysCmmandsPage} +\endmenu +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroStartTitle}{Starting Up and Winding Down} +\newcommand{\ugIntroStartNumber}{1.1.} +% +% ===================================================================== +\begin{page}{ugIntroStartPage}{1.1. Starting Up and Winding Down} +% ===================================================================== +\beginscroll +% + +You need to know how to start the \Language{} system and how to stop it. +We assume that \Language{} has been correctly installed on your +machine (as described in another \Language{} document). + +To begin using \Language{}, issue the command {\bf axiom} to the +%-% \HDindex{starting @{starting \Language{}}}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +operating system shell. +%-% \HDindex{axiom @{\bf axiom}}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +There is a brief pause, some start-up messages, and then one +or more windows appear. + +If you are not running \Language{} under the X Window System, there is +only one window (the console). +At the lower left of the screen there is a prompt that +%-% \HDindex{prompt}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +looks like +\begin{verbatim} +(1) -> +\end{verbatim} +%%--> do you want to talk about equation numbers on the right, etc. +When you want to enter input to \Language{}, you do so on the same line +after the prompt. +The ``1'' in ``(1)'' is the computation step number and is incremented +%-% \HDindex{step number}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +after you enter \Language{} statements. +Note, however, that a system command +such as \spadsys{)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 \Language{} under the X Window System, there may be two +%-% \HDindex{X Window System}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +windows: the console window (as just described) and the \HyperName{} +main menu. +%-% \HDindex{Hyper @{\HyperName{}}}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +\HyperName{} is a multiple-window hypertext system that lets you +%-% \HDindex{window}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +view \Language{} documentation and examples on-line, +execute \Language{} expressions, and generate graphics. +If you are in a graphical windowing environment, +it is usually started automatically when \Language{} begins. +If it is not running, issue \spadsys{)hd} to start it. +We discuss the basics of \HyperName{} in \downlink{``\ugHyperTitle''}{ugHyperPage} in Chapter \ugHyperNumber\ignore{ugHyper}. +%-% \HDsyscmdindex{hd}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} + +To interrupt an \Language{} computation, hold down the +%-% \HDindex{interrupt}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +\texht{\fbox{\bf Ctrl}}{{\bf Ctrl}} (control) key and press +\texht{\fbox{\bf c}}{{\bf c}}. +This brings you back to the \Language{} prompt. + +\beginImportant +To exit from \Language{}, move to the console window, +%-% \HDindex{stopping @{stopping \Language{}}}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +type \spadsys{)quit} +%-% \HDindex{exiting @{exiting \Language{}}}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +at the input prompt and press the \texht{\fbox{\bf Enter}}{{\bf Enter}} key. +%-% \HDsyscmdindex{quit}{ugIntroStartPage}{1.1.}{Starting Up and Winding Down} +You will probably be prompted with the following message: +\centerline{{Please enter {\bf y} or {\bf yes} if you really want to leave the }} +\centerline{{interactive environment and return to the operating system}} +You should respond {\bf yes}, for example, to exit \Language{}. +\endImportant + +We are purposely vague in describing exactly what your screen +looks like or what messages \Language{} displays. +\Language{} 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 \Language{} behaves via +\spadgloss{system commands} described later in this chapter and in +\downlink{``\ugSysCmdTitle''}{ugSysCmdPage} in Appendix \ugSysCmdNumber\ignore{ugSysCmd}. +System commands are special commands, like \spadcmd{)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 \Language{}. + +\beginmenu + \menudownlink{{1.1.1. \Clef{}}}{ugAvailCLEFPage} +\endmenu +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugAvailCLEFTitle}{\Clef{}} +\newcommand{\ugAvailCLEFNumber}{1.1.1.} +% +% ===================================================================== +\begin{page}{ugAvailCLEFPage}{1.1.1. \Clef{}} +% ===================================================================== +\beginscroll +% +If you are using \Language{} under the X Window System, the +%-% \HDindex{Clef@{\Clef{}}}{ugAvailCLEFPage}{1.1.1.}{\Clef{}} +%-% \HDindex{command line editor}{ugAvailCLEFPage}{1.1.1.}{\Clef{}} +\Clef{} command line editor is probably available and installed. +With this editor you can recall previous lines with the up and +down arrow keys\texht{ (\fbox{$\uparrow$} and +\fbox{$\downarrow$})}{}. +To move forward and backward on a line, use the right and +left arrows\texht{ (\fbox{$\rightarrow$} and +\fbox{$\leftarrow$})}{}. +You can use the +\texht{\fbox{\bf Insert}}{{\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 +\texht{\fbox{\bf Home}}{{\bf Home}} +key, the cursor moves to the beginning of the line and if you press the +\texht{\fbox{\bf End}}{{\bf End}} +key, the cursor moves to the end of the line. +Pressing +\texht{\fbox{\bf Ctrl}--\fbox{\bf End}}{{\bf Ctrl-End}} +deletes all the text from the cursor to the end of the line. + +\Clef{} also provides \Language{} operation name completion for +%-% \HDindex{operation name completion}{ugAvailCLEFPage}{1.1.1.}{\Clef{}} +a limited set of operations. +If you enter a few letters and then press the +\texht{\fbox{\bf Tab}}{{\bf Tab}} key, +\Clef{} tries to use those letters as the prefix of an \Language{} +operation name. +If a name appears and it is not what you want, press +\texht{\fbox{\bf Tab}}{{\bf Tab}} again +to see another name. + +You are ready to begin your journey into the world of \Language{}. +Proceed to the first stop. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroTypoTitle}{Typographic Conventions} +\newcommand{\ugIntroTypoNumber}{1.2.} +% +% ===================================================================== +\begin{page}{ugIntroTypoPage}{1.2. Typographic Conventions} +% ===================================================================== +\beginscroll + +In this book we have followed these typographical conventions: +\indent{4} +\beginitems +% +\item[-] Categories, domains and packages are displayed in +\texht{a sans-serif typeface:}{this font:} +\axiomType{Ring}, \axiomType{Integer}, \axiomType{DiophantineSolutionPackage}. +% +\item[-] Prefix operators, infix operators, and punctuation symbols in the \Language{} +language are displayed in the text like this: +\axiomOp{+}, \axiomSyntax{\$}, \axiomSyntax{+->}. +% +\item[-] \Language{} expressions or expression fragments are displayed in +\texht{a mon\-o\-space typeface:}{this font:} +\axiom{inc(x) == x + 1}. +% +\item[-] For clarity of presentation, \TeX{} is often +used to format expressions\texht{: $g(x)=x^2+1.$}{.} +% +\item[-] Function names and \HyperName{} button names +are displayed in the text in +\texht{a bold typeface:}{this font:} +\axiomFun{factor}, \axiomFun{integrate}, {\bf Lighting}. +% +\item[-] Italics are used for emphasis and for words defined in the +glossary: \spadgloss{category}. +\enditems +\indent{0} + +This book contains over 2500 examples of \Language{} input and output. +All examples were run though \Language{} and their output was +created in \texht{\TeX{}}{TeX} form for this book by the \Language{} +\axiomType{TexFormat} package. +%-% \HDexptypeindex{TexFormat}{ugIntroTypoPage}{1.2.}{Typographic Conventions} +We have deleted system messages from the example output if those +messages are not important for the discussions in which the examples +appear. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroExpressionsTitle}{The \Language{} Language} +\newcommand{\ugIntroExpressionsNumber}{1.3.} +% +% ===================================================================== +\begin{page}{ugIntroExpressionsPage}{1.3. The \Language{} Language} +% ===================================================================== +\beginscroll +% + +The \Language{} language is a rich language for performing +interactive computations and for building components of the +\Language{} 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 at the back of the book. + +\beginmenu + \menudownlink{{1.3.1. Arithmetic Expressions}}{ugIntroArithmeticPage} + \menudownlink{{1.3.2. Previous Results}}{ugIntroPreviousPage} + \menudownlink{{1.3.3. Some Types}}{ugIntroTypesPage} + \menudownlink{{1.3.4. Symbols, Variables, Assignments, and Declarations}}{ugIntroAssignPage} + \menudownlink{{1.3.5. Conversion}}{ugIntroConversionPage} + \menudownlink{{1.3.6. Calling Functions}}{ugIntroCallFunPage} + \menudownlink{{1.3.7. Some Predefined Macros}}{ugIntroMacrosPage} + \menudownlink{{1.3.8. Long Lines}}{ugIntroLongPage} + \menudownlink{{1.3.9. Comments}}{ugIntroCommentsPage} +\endmenu +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroArithmeticTitle}{Arithmetic Expressions} +\newcommand{\ugIntroArithmeticNumber}{1.3.1.} +% +% ===================================================================== +\begin{page}{ugIntroArithmeticPage}{1.3.1. Arithmetic Expressions} +% ===================================================================== +\beginscroll + +For arithmetic expressions, use the \spadop{+} and \spadop{-} +\spadglossSee{operators}{operator} as in mathematics. +Use \spadop{*} for multiplication, and \spadop{**} for +exponentiation. +To create a fraction, use \spadop{/}. +When an expression contains several operators, those of highest +\spadgloss{precedence} are evaluated first. +For arithmetic operators, \spadop{**} has highest precedence, +\spadop{*} and \spadop{/} have the next highest +precedence, and \spadop{+} and \spadop{-} have the lowest +precedence. + +\xtc{ +\Language{} puts implicit parentheses around operations of higher +precedence, and groups those of equal precedence from left to right. +}{ +\spadpaste{1 + 2 - 3 / 4 * 3 ** 2 - 1} +} +\xtc{ +The above expression is equivalent to this. +}{ +\spadpaste{((1 + 2) - ((3 / 4) * (3 ** 2))) - 1} +} +\xtc{ +If an expression contains subexpressions enclosed in parentheses, +the parenthesized subexpressions are evaluated first (from left to +right, from inside out). +}{ +\spadpaste{1 + 2 - 3/ (4 * 3 ** (2 - 1))} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroPreviousTitle}{Previous Results} +\newcommand{\ugIntroPreviousNumber}{1.3.2.} +% +% ===================================================================== +\begin{page}{ugIntroPreviousPage}{1.3.2. Previous Results} +% ===================================================================== +\beginscroll + +Use the percent sign (\axiomSyntax{\%}) to refer to the last +result. +%-% \HDindex{result!previous}{ugIntroPreviousPage}{1.3.2.}{Previous Results} +Also, use \axiomSyntax{\%\%} to refer to previous results. +%-% \HDindex{percentpercent@{\%\%}}{ugIntroPreviousPage}{1.3.2.}{Previous Results} +\axiom{\%\%(-1)} is equivalent to \axiomSyntax{\%}, +\axiom{\%\%(-2)} returns the next to the last result, and so on. +\axiom{\%\%(1)} returns the result from step number 1, +\axiom{\%\%(2)} returns the result from step number 2, and so on. +\axiom{\%\%(0)} is not defined. + +\xtc{ +This is ten to the tenth power. +}{ +\spadpaste{10 ** 10 \bound{prev}} +} +\xtc{ +This is the last result minus one. +}{ +\spadpaste{\% - 1 \free{prev}\bound{prev1}} +} +\xtc{ +This is the last result. +}{ +\spadpaste{\%\%(-1) \free{prev1}\bound{prev2}} +} +\xtc{ +This is the result from step number 1. +}{ +\spadpaste{\%\%(1) \free{prev2}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroTypesTitle}{Some Types} +\newcommand{\ugIntroTypesNumber}{1.3.3.} +% +% ===================================================================== +\begin{page}{ugIntroTypesPage}{1.3.3. Some Types} +% ===================================================================== +\beginscroll + +Everything in \Language{} has a type. +The type determines what operations you can perform on an object and +how the object can be used. +An entire chapter of this book (\downlink{``\ugTypesTitle''}{ugTypesPage} in Chapter \ugTypesNumber\ignore{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 \Language{} library. + +\xtc{ +Positive integers are given type \spadtype{PositiveInteger}. +}{ +\spadpaste{8} +} +\xtc{ +Negative ones are given type \spadtype{Integer}. +This fine distinction is helpful to the +\Language{} interpreter. +}{ +\spadpaste{-8} +} +\xtc{ +Here a positive integer exponent gives a polynomial result. +}{ +\spadpaste{x**8} +} +\xtc{ +Here a negative integer exponent produces a fraction. +}{ +\spadpaste{x**(-8)} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroAssignTitle}{Symbols, Variables, Assignments, and Declarations} +\newcommand{\ugIntroAssignNumber}{1.3.4.} +% +% ===================================================================== +\begin{page}{ugIntroAssignPage}{1.3.4. Symbols, Variables, Assignments, and Declarations} +% ===================================================================== +\beginscroll + +A \spadgloss{symbol} is a literal used for the input of things like +the ``variables'' in polynomials and power series. + +\labelSpace{2pc} +\xtc{ +We use the three symbols \axiom{x}, \axiom{y}, and \axiom{z} in +entering this polynomial. +}{ +\spadpaste{(x - y*z)**2} +} +A symbol has a name beginning with an uppercase or lowercase alphabetic +%-% \HDindex{symbol!naming}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +character, \axiomSyntax{\%}, or \axiomSyntax{!}. +Successive characters (if any) can be any of the above, digits, or +\axiomSyntax{?}. +Case is distinguished: the symbol \axiom{points} is different +from the symbol \axiom{Points}. + +A symbol can also be used in \Language{} as a \spadgloss{variable}. +A variable refers to a value. +To \spadglossSee{assign}{assignment} +a value to a variable, +%-% \HDindex{variable!naming}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +the operator \axiomSyntax{:=} +%-% \HDindex{assignment}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +is used.\footnote{\Language{} actually has two forms of assignment: +{\it immediate} assignment, as discussed here, +and {\it delayed assignment}. See \downlink{``\ugLangAssignTitle''}{ugLangAssignPage} in Section \ugLangAssignNumber\ignore{ugLangAssign} for details.} +A variable initially has no restrictions on the kinds of +%-% \HDindex{declaration}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +values to which it can refer. + +\xtc{ +This assignment gives the value \axiom{4} (an integer) to +a variable named \axiom{x}. +}{ +\spadpaste{x := 4} +} +\xtc{ +This gives the value \axiom{z + 3/5} (a polynomial) to \axiom{x}. +}{ +\spadpaste{x := z + 3/5} +} +\xtc{ +To restrict the types of objects that can be assigned to a variable, +use a \spadgloss{declaration} +}{ +\spadpaste{y : Integer \bound{y}} +} +\xtc{ +After a variable is declared to be of some type, only values +of that type can be assigned to that variable. +}{ +\spadpaste{y := 89\bound{y1}\free{y}} +} +\xtc{ +The declaration for \axiom{y} forces values assigned to \axiom{y} to +be converted to integer values. +}{ +\spadpaste{y := sin \%pi} +} +\xtc{ +If no such conversion is possible, +\Language{} refuses to assign a value to \axiom{y}. +}{ +\spadpaste{y := 2/3} +} +\xtc{ +A type declaration can also be given together with an assignment. +The declaration can assist \Language{} in choosing the correct +operations to apply. +}{ +\spadpaste{f : Float := 2/3} +} + +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. + +\xtc{ +These two expressions have the same effect as +the previous single expression. +}{ +\spadpaste{f : Float; f := 2/3 \bound{fff}} +} + +The type of a symbol is either \axiomType{Symbol} +%-% \HDexptypeindex{Symbol}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +or \axiomType{Variable({\it name})} where {\it name} is the name +of the symbol. + +\xtc{ +By default, the interpreter +%-% \HDexptypeindex{Variable}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +gives this symbol the type \axiomType{Variable(q)}. +}{ +\spadpaste{q} +} +\xtc{ +When multiple symbols are involved, \axiomType{Symbol} is used. +}{ +\spadpaste{[q, r]} +} + +\xtc{ +What happens when you try to use a symbol that is the name of a variable? +}{ +\spadpaste{f \free{fff}} +} +\xtc{ +Use a single quote (\axiomSyntax{'}) before +%-% \HDindex{quote}{ugIntroAssignPage}{1.3.4.}{Symbols, Variables, Assignments, and Declarations} +the name to get the symbol. +}{ +\spadpaste{'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. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroConversionTitle}{Conversion} +\newcommand{\ugIntroConversionNumber}{1.3.5.} +% +% ===================================================================== +\begin{page}{ugIntroConversionPage}{1.3.5. Conversion} +% ===================================================================== +\beginscroll + +Objects of one type can usually be ``converted'' to objects of several +other types. +To \spadglossSee{convert}{conversion} +an object to a new type, use the \axiomSyntax{::} infix +operator.\footnote{Conversion is discussed in detail in \downlink{``\ugTypesConvertTitle''}{ugTypesConvertPage} in Section \ugTypesConvertNumber\ignore{ugTypesConvert}.} +For example, to display an object, it is necessary to +convert the object to type \spadtype{OutputForm}. + +\xtc{ +This produces a polynomial with rational number coefficients. +}{ +\spadpaste{p := r**2 + 2/3 \bound{p}} +} +\xtc{ +Create a quotient of polynomials with integer coefficients +by using \axiomSyntax{::}. +}{ +\spadpaste{p :: Fraction Polynomial Integer \free{p}} +} + +Some conversions can be performed automatically when +\Language{} tries to evaluate your input. +Others conversions must be explicitly requested. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroCallFunTitle}{Calling Functions} +\newcommand{\ugIntroCallFunNumber}{1.3.6.} +% +% ===================================================================== +\begin{page}{ugIntroCallFunPage}{1.3.6. Calling Functions} +% ===================================================================== +\beginscroll + +As we saw earlier, when you want to add or subtract two values, +you place the arithmetic operator \spadop{+} +or \spadop{-} between the two +\spadglossSee{arguments}{argument} denoting the values. +To use most other \Language{} operations, however, you use another syntax: +%-% \HDindex{function!calling}{ugIntroCallFunPage}{1.3.6.}{Calling Functions} +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. + +\xtc{ +This calls the operation \axiomFun{factor} with the single +integer argument \axiom{120}. +}{ +\spadpaste{factor(120)} +} +\xtc{ +This is a call to \axiomFun{divide} with the two integer arguments +\axiom{125} and \axiom{7}. +}{ +\spadpaste{divide(125,7)} +} +\xtc{ +This calls \axiomFun{quatern} with four floating-point arguments. +}{ +\spadpaste{quatern(3.4,5.6,2.9,0.1)} +} +\xtc{ +This is the same as \axiom{factorial(10)}. +}{ +\spadpaste{factorial 10} +} + +An operations that returns a \spadtype{Boolean} value (that is, +\spad{true} or \spad{false}) frequently has a name suffixed with +a question mark (``?''). For example, the \spadfun{even?} +operation returns \spad{true} if its integer argument is an even +number, \spad{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. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroMacrosTitle}{Some Predefined Macros} +\newcommand{\ugIntroMacrosNumber}{1.3.7.} +% +% ===================================================================== +\begin{page}{ugIntroMacrosPage}{1.3.7. Some Predefined Macros} +% ===================================================================== +\beginscroll + +\Language{} provides several \spadglossSee{macros}{macro} +for your convenience.\footnote{See \downlink{``\ugUserMacrosTitle''}{ugUserMacrosPage} in Section \ugUserMacrosNumber\ignore{ugUserMacros} +for a discussion on how to write your own macros.} +Macros are names +%-% \HDindex{macro!predefined}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +(or forms) that expand to larger expressions for commonly used values. + +\texht{ +\centerline{{\begin{tabular}{ll}}} +\centerline{{\spadgloss{\%i} & The square root of -1. }} +\centerline{{\spadgloss{\%e} & The base of the natural logarithm. }} +\centerline{{\spadgloss{\%pi} & $\pi$. }} +\centerline{{\spadgloss{\%infinity} & $\infty$. }} +\centerline{{\spadgloss{\%plusInfinity} & $+\infty$. }} +\centerline{{\spadgloss{\%minusInfinity} & $-\infty$.}} +\centerline{{\end{tabular}}} +%-% \HDindex{\%i}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{\%e}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{\%pi}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{pi@{$\pi$ (= \%pi)}}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{\%infinity}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{infinity@{$\infty$ (= \%infinity)}}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{\%plusInfinity}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +%-% \HDindex{\%minusInfinity}{ugIntroMacrosPage}{1.3.7.}{Some Predefined Macros} +}{ +\indent{0} +\beginitems +\item[\axiomSyntax{\%i}] \tab{17} The square root of -1. +\item[\axiomSyntax{\%e}] \tab{17} The base of the natural logarithm. +\item[\axiomSyntax{\%pi}] \tab{17} Pi. +\item[\axiomSyntax{\%infinity}] \tab{17} Infinity. +\item[\axiomSyntax{\%plusInfinity}] \tab{17} Plus infinity. +\item[\axiomSyntax{\%minusInfinity}] \tab{17} Minus infinity. +\enditems +\indent{0} +} + +%To display all the macros (along with anything you have +%defined in the workspace), issue the system command \spadsys{)display all}. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroLongTitle}{Long Lines} +\newcommand{\ugIntroLongNumber}{1.3.8.} +% +% ===================================================================== +\begin{page}{ugIntroLongPage}{1.3.8. Long Lines} +% ===================================================================== +\beginscroll + +When you enter \Language{} expressions from your keyboard, there +will be times when they are too long to fit on one line. +\Language{} 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 \Language{} 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} + +If you are putting your \Language{} statements in an input file +(see \downlink{``\ugInOutInTitle''}{ugInOutInPage} in Section \ugInOutInNumber\ignore{ugInOutIn}), +you can use indentation to indicate the structure of your program. +(see \downlink{``\ugLangBlocksTitle''}{ugLangBlocksPage} in Section \ugLangBlocksNumber\ignore{ugLangBlocks}). + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroCommentsTitle}{Comments} +\newcommand{\ugIntroCommentsNumber}{1.3.9.} +% +% ===================================================================== +\begin{page}{ugIntroCommentsPage}{1.3.9. Comments} +% ===================================================================== +\beginscroll + +Comment statements begin with two consecutive hyphens or two +consecutive plus signs and continue until the end of the line. + +\xtc{ +The comment beginning with {\tt --} is ignored by \Language{}. +}{ +\spadpaste{2 + 3 -- this is rather simple, no?} +} + +There is no way to write long multi-line comments +other than starting each line with \axiomSyntax{--} or +\axiomSyntax{++}. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroGraphicsTitle}{Graphics} +\newcommand{\ugIntroGraphicsNumber}{1.4.} +% +% ===================================================================== +\begin{page}{ugIntroGraphicsPage}{1.4. Graphics} +% ===================================================================== +\beginscroll +% + +\Language{} has a two- and three-dimensional drawing and rendering +%-% \HDindex{graphics}{ugIntroGraphicsPage}{1.4.}{Graphics} +package that allows you to draw, shade, color, rotate, translate, map, +clip, scale and combine graphic output of \Language{} 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. + +\psXtc{ +This is an example of \Language{}'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 +\texht{\fbox{\bf PS}}{{\bf PS}} 2D Control Panel button. +}{ +\graphpaste{draw(cos(5*t/8), t=0..16*\%pi, coordinates==polar)} +}{ +\epsffile[72 72 300 300]{../ps/rose-1.ps} +} + +\psXtc{ +This is an example of \Language{}'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 +\texht{\fbox{\bf save}}{{\bf save}} 3D Control Panel button and then +clicking on the \texht{\fbox{\bf PS}}{{\bf PS}} button. +See \downlink{``\ugProblemNumericTitle''}{ugProblemNumericPage} in Section \ugProblemNumericNumber\ignore{ugProblemNumeric} for more details and examples +of \Language{}'s numeric and graphics capabilities. +}{ +\graphpaste{draw((x,y) +-> real atan complex(x,y), -\%pi..\%pi, -\%pi..\%pi, colorFunction == (x,y) +-> argument atan complex(x,y))} +}{ +\epsffile[72 72 285 285]{../ps/atan-1.ps} +} + +An exhibit of \Gallery{} is given in the +center section of this book. +For a description of the commands and programs that +produced these figures, see \downlink{``\ugAppGraphicsTitle''}{ugAppGraphicsPage} in Appendix \ugAppGraphicsNumber\ignore{ugAppGraphics}. +PostScript +%-% \HDindex{PostScript}{ugIntroGraphicsPage}{1.4.}{Graphics} +output is available so that \Language{} images can be +printed.\footnote{PostScript is a trademark of Adobe Systems Incorporated, +registered in the United States.} +See \downlink{``\ugGraphTitle''}{ugGraphPage} in Chapter \ugGraphNumber\ignore{ugGraph} for more examples and details about using +\Language{}'s graphics facilities. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroNumbersTitle}{Numbers} +\newcommand{\ugIntroNumbersNumber}{1.5.} +% +% ===================================================================== +\begin{page}{ugIntroNumbersPage}{1.5. Numbers} +% ===================================================================== +\beginscroll +% + +\Language{} 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. + +\xtc{ +Integer arithmetic is always exact. +}{ +\spadpaste{11**13 * 13**11 * 17**7 - 19**5 * 23**3} +} +\xtc{ +Integers can be represented in factored form. +}{ +\spadpaste{factor 643238070748569023720594412551704344145570763243 \bound{ex1}} +} +\xtc{ +Results stay factored when you do arithmetic. +Note that the \axiom{12} is automatically factored for you. +}{ +\spadpaste{\% * 12 \free{ex1}} +} +%-% \HDindex{radix}{ugIntroNumbersPage}{1.5.}{Numbers} +\xtc{ +Integers can also be displayed to bases other than 10. +This is an integer in base 11. +}{ +\spadpaste{radix(25937424601,11)} +} +\xtc{ +Roman numerals are also available for those special occasions. +%-% \HDindex{Roman numerals}{ugIntroNumbersPage}{1.5.}{Numbers} +}{ +\spadpaste{roman(1992)} +} +\xtc{ +Rational number arithmetic is also exact. +}{ +\spadpaste{r := 10 + 9/2 + 8/3 + 7/4 + 6/5 + 5/6 + 4/7 + 3/8 + 2/9\bound{r}} +} +\xtc{ +To factor fractions, you have to +map \axiomFun{factor} onto the numerator and denominator. +}{ +\spadpaste{map(factor,r) \free{r}} +} +\xtc{ +Type \spadtype{SingleInteger} refers to machine word-length +integers. +%-% \HDexptypeindex{SingleInteger}{ugIntroNumbersPage}{1.5.}{Numbers} +In English, this expression means ``\axiom{11} as a small +integer''. +}{ +\spadpaste{11@SingleInteger} +} +\xtc{ +Machine double-precision floating-point numbers are also +available for numeric and graphical +applications. +%-% \HDexptypeindex{DoubleFloat}{ugIntroNumbersPage}{1.5.}{Numbers} +}{ +\spadpaste{123.21@DoubleFloat} +} + +The normal floating-point type in \Language{}, \spadtype{Float}, +is a software implementation of floating-point numbers in which +the exponent and the mantissa may have any number of +digits.\footnote{See \downlink{`Float'}{FloatXmpPage}\ignore{Float} and \downlink{`DoubleFloat'}{DoubleFloatXmpPage}\ignore{DoubleFloat} for +additional information on floating-point types.} +The types \spadtype{Complex(Float)} and +\spadtype{Complex(DoubleFloat)} are the corresponding software +implementations of complex floating-point numbers. + +\xtc{ +This is a floating-point approximation to about twenty digits. +%-% \HDindex{floating point}{ugIntroNumbersPage}{1.5.}{Numbers} +The \axiomSyntax{::} +is used here to change from one kind of object +(here, a rational number) to another (a floating-point number). +}{ +\spadpaste{r :: Float \free{r}} +} +\xtc{ +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. +}{ +\spadpaste{digits(22) \bound{fewerdigits}} +} +\xtc{ +To \axiom{22} digits of precision, the number +\texht{$e^{\pi {\sqrt {163.0}}}$}{\axiom{exp(\%pi * sqrt 163.0)}} +appears to be an integer. +}{ +\spadpaste{exp(\%pi * sqrt 163.0) \free{fewerdigits}} +} +\xtc{ +Increase the precision to forty digits and try again. +}{ +\spadpaste{digits(40); exp(\%pi * sqrt 163.0) \free{moredigits}} +} +\xtc{ +Here are complex numbers with rational numbers as real and +%-% \HDindex{complex numbers}{ugIntroNumbersPage}{1.5.}{Numbers} +imaginary parts. +}{ +\spadpaste{(2/3 + \%i)**3 \bound{gaussint}} +} +\xtc{ +The standard operations on complex numbers are available. +}{ +\spadpaste{conjugate \% \free{gaussint}} +} +\xtc{ +You can factor complex integers. +}{ +\spadpaste{factor(89 - 23 * \%i)} +} +\xtc{ +Complex numbers with floating point parts are also available. +}{ +\spadpaste{exp(\%pi/4.0 * \%i)} +} +%%--> These are not numbers: +%\xtc{ +%The real and imaginary parts can be symbolic. +%}{ +%\spadcommand{complex(u,v) \bound{cuv}} +%} +%\xtc{ +%Of course, you can do complex arithmetic with these also. +%See \downlink{`Complex'}{ComplexXmpPage}\ignore{Complex} for more information. +%}{ +%\spadcommand{\% ** 2 \free{cuv}} +%} +\xtc{ +Every rational number has an exact representation as a +repeating decimal expansion +(see \downlink{`DecimalExpansion'}{DecimalExpansionXmpPage}\ignore{DecimalExpansion}). +}{ +\spadpaste{decimal(1/352)} +} +\xtc{ +A rational number can also be expressed as a continued fraction (see +%-% \HDindex{continued fraction}{ugIntroNumbersPage}{1.5.}{Numbers} +\downlink{`ContinuedFraction'}{ContinuedFractionXmpPage}\ignore{ContinuedFraction}). +%-% \HDindex{fraction!continued}{ugIntroNumbersPage}{1.5.}{Numbers} +}{ +\spadpaste{continuedFraction(6543/210)} +} +\xtc{ +Also, partial fractions can be used and can be displayed in a +%-% \HDindex{partial fraction}{ugIntroNumbersPage}{1.5.}{Numbers} +compact \ldots +%-% \HDindex{fraction!partial}{ugIntroNumbersPage}{1.5.}{Numbers} +}{ +\spadpaste{partialFraction(1,factorial(10)) \bound{partfrac}} +} +\xtc{ +or expanded format (see \downlink{`PartialFraction'}{PartialFractionXmpPage}\ignore{PartialFraction}). +}{ +\spadpaste{padicFraction(\%) \free{partfrac}} +} +\xtc{ +Like integers, bases (radices) other than ten can be used for rational +numbers (see \downlink{`RadixExpansion'}{RadixExpansionXmpPage}\ignore{RadixExpansion}). +Here we use base eight. +}{ +\spadpaste{radix(4/7, 8)\bound{rad}} +} +\xtc{ +Of course, there are complex versions of these as well. +\Language{} decides to make the result a complex rational number. +}{ +\spadpaste{\% + 2/3*\%i\free{rad}} +} +\xtc{ +You can also use \Language{} to manipulate fractional powers. +%-% \HDindex{radical}{ugIntroNumbersPage}{1.5.}{Numbers} +}{ +\spadpaste{(5 + sqrt 63 + sqrt 847)**(1/3)} +} +\xtc{ +You can also compute with integers modulo a prime. +}{ +\spadpaste{x : PrimeField 7 := 5 \bound{x}} +} +\xtc{ +Arithmetic is then done modulo \mathOrSpad{7}. +}{ +\spadpaste{x**3 \free{x}} +} +\xtc{ +Since \mathOrSpad{7} is prime, you can invert nonzero values. +}{ +\spadpaste{1/x \free{x}} +} +\xtc{ +You can also compute modulo an integer that is not a prime. +}{ +\spadpaste{y : IntegerMod 6 := 5 \bound{y}} +} +\xtc{ +All of the usual arithmetic operations are available. +}{ +\spadpaste{y**3 \free{y}} +} +\xtc{ +Inversion is not available if the modulus is not a prime +number. +Modular arithmetic and prime fields are discussed in +\downlink{``\ugxProblemFinitePrimeTitle''}{ugxProblemFinitePrimePage} in Section \ugxProblemFinitePrimeNumber\ignore{ugxProblemFinitePrime}. +}{ +\spadpaste{1/y \free{y}} +} +\xtc{ +This defines \axiom{a} to be an algebraic number, that is, +a root of a polynomial equation. +}{ +\spadpaste{a := rootOf(a**5 + a**3 + a**2 + 3,a) \bound{a}} +} +\xtc{ +Computations with \axiom{a} are reduced according +to the polynomial equation. +}{ +\spadpaste{(a + 1)**10\free{a}} +} +\xtc{ +Define \axiom{b} to be an algebraic number involving \axiom{a}. +}{ +\spadpaste{b := rootOf(b**4 + a,b) \bound{b}\free{a}} +} +\xtc{ +Do some arithmetic. +}{ +\spadpaste{2/(b - 1) \free{b}\bound{check}} +} +\xtc{ +To expand and simplify this, call \axiomFun{ratDenom} +to rationalize the denominator. +}{ +\spadpaste{ratDenom(\%) \free{check}\bound{check1}} +} +\xtc{ +If we do this, we should get \axiom{b}. +}{ +\spadpaste{2/\%+1 \free{check1}\bound{check2}} +} +\xtc{ +But we need to rationalize the denominator again. +}{ +\spadpaste{ratDenom(\%) \free{check2}} +} +\xtc{ +Types \spadtype{Quaternion} and \spadtype{Octonion} are also available. +Multiplication of quaternions is non-commutative, as expected. +}{ +\spadpaste{q:=quatern(1,2,3,4)*quatern(5,6,7,8) - quatern(5,6,7,8)*quatern(1,2,3,4)} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroCollectTitle}{Data Structures} +\newcommand{\ugIntroCollectNumber}{1.6.} +% +% ===================================================================== +\begin{page}{ugIntroCollectPage}{1.6. Data Structures} +% ===================================================================== +\beginscroll +% + +\Language{} 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 \Language{} are organized into +\spadglossSee{category hierarchies}{hierarchy} as shown on +the inside back cover. + +A \spadgloss{list} is the most commonly used data structure in +\Language{} for holding objects all of the same +type.\footnote{Lists are discussed in \downlink{`List'}{ListXmpPage}\ignore{List} and in +\downlink{``\ugLangItsTitle''}{ugLangItsPage} in Section \ugLangItsNumber\ignore{ugLangIts}.} +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 +\spadglossSee{points}{pointer} to the next node, or to a +distinguished value denoting the empty list. +To get to, say, the third element, \Language{} starts at the front +of the list, then traverses across two links to the third node. + +\xtc{ +Write a list of elements using +square brackets with commas separating the elements. +}{ +\spadpaste{u := [1,-7,11] \bound{u}} +} +\xtc{ +This is the value at the third node. +Alternatively, you can say \axiom{u.3}. +}{ +\spadpaste{first rest rest u\free{u}} +} + +Many operations are defined on lists, such as: +\axiomFun{empty?}, to test that a list has no elements; +\axiomFun{cons}\axiom{(x,l)}, to create a new list with +\axiomFun{first} element \axiom{x} and \axiomFun{rest} \axiom{l}; +\axiomFun{reverse}, to create a new list with elements in reverse +order; and \axiomFun{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 \axiomSyntax{!}. + +\xtc{ +The operation \spadfunFromX{concat}{List}\axiom{(u,v)} +replaces the last link of the list +\axiom{u} to point to some other list \axiom{v}. +Since \axiom{u} refers to the original list, +this change is seen by \axiom{u}. +}{ +\spadpaste{concat!(u,[9,1,3,-4]); u\free{u}\bound{u1}} +} +\xtc{ +A {\it cyclic list} is a list with a ``cycle'': +%-% \HDindex{list!cyclic}{ugIntroCollectPage}{1.6.}{Data Structures} +a link pointing back to an earlier node of the list. +%-% \HDindex{cyclic list}{ugIntroCollectPage}{1.6.}{Data Structures} +To create a cycle, first get a node somewhere down +the list. +}{ +\spadpaste{lastnode := rest(u,3)\free{u1}\bound{u2}} +} +\xtc{ +Use \spadfunFromX{setrest}{List} to +change the link emanating from that node to point back to an +earlier part of the list. +}{ +\spadpaste{setrest!(lastnode,rest(u,2)); u\free{u2}} +} + +A \spadgloss{stream} +is a structure that (potentially) has an infinite number of +distinct elements.\footnote{Streams are discussed in +\downlink{`Stream'}{StreamXmpPage}\ignore{Stream} and in \downlink{``\ugLangItsTitle''}{ugLangItsPage} in Section \ugLangItsNumber\ignore{ugLangIts}.} +Think of a stream as an ``infinite list'' where elements are +computed successively. + +\xtc{ +Create an infinite stream of factored integers. +Only a certain number of initial elements are computed +and displayed. +}{ +\spadpaste{[factor(i) for i in 2.. by 2] \bound{stream1}} +} +\xtc{ +\Language{} represents streams by a collection of already-computed +elements together with a function to compute the next element +``on demand.'' +Asking for the \eth{\axiom{n}} element causes elements \axiom{1} through +\axiom{n} to be evaluated. +}{ +\spadpaste{\%.36 \free{stream1}} +} + +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, \axiomFun{first} and \axiomFun{rest} are used to access +elements and successive nodes of a stream. +%%> reverse and sort do not exist for streams +%%Don't try to reverse or sort a stream: the +%%operation will generally run forever! + +A \spadgloss{one-dimensional array} is another data structure used +to hold objects of the same type.\footnote{See \downlink{`OneDimensionalArray'}{OneDimensionalArrayXmpPage}\ignore{OneDimensionalArray} for +details.} +Unlike lists, one-dimensional arrays are inflexible---they are +%-% \HDindex{array!one-dimensional}{ugIntroCollectPage}{1.6.}{Data Structures} +implemented using a fixed block of storage. +Their advantage is that they give quick and equal access time to +any element. + +\xtc{ +A simple way to create a one-dimensional array is to apply the +operation \axiomFun{oneDimensionalArray} to a list of elements. +}{ +\spadpaste{a := oneDimensionalArray [1, -7, 3, 3/2]\bound{a}} +} +\xtc{ +One-dimensional arrays are also mutable: +you can change their constituent elements ``in place.'' +}{ +\spadpaste{a.3 := 11; a\bound{a1}\free{a}} +} +\xtc{ +However, one-dimensional arrays are not flexible structures. +You cannot destructively \spadfunX{concat} them together. +}{ +\spadpaste{concat!(a,oneDimensionalArray [1,-2])\free{a1}} +} + +Examples of datatypes similar to \spadtype{OneDimensionalArray} +are: \spadtype{Vector} (vectors are mathematical structures +implemented by one-dimensional arrays), \spadtype{String} (arrays +of ``characters,'' represented by byte vectors), and +\spadtype{Bits} (represented by ``bit vectors''). + +\xtc{ +A vector of 32 bits, each representing the \spadtype{Boolean} value \axiom{true}. +}{ +\spadpaste{bits(32,true)} +} + +A \spadgloss{flexible array} is a cross between a list +%-% \HDindex{array!flexible}{ugIntroCollectPage}{1.6.}{Data Structures} +and a one-dimensional array.\footnote{See \downlink{`FlexibleArray'}{FlexibleArrayXmpPage}\ignore{FlexibleArray} for +details.} +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. + +\xtc{ +Create a flexible array of three elements. +}{ +\spadpaste{f := flexibleArray [2, 7, -5]\bound{f}} +} +\xtc{ +Insert some elements between the second and third elements. +}{ +\spadpaste{insert!(flexibleArray [11, -3],f,2)\free{f}} +} + +Flexible arrays are used to implement ``heaps.'' A +\spadgloss{heap} is an example of a data structure called a +\spadgloss{priority queue}, where elements are ordered with +respect to one another.\footnote{See \downlink{`Heap'}{HeapXmpPage}\ignore{Heap} for more details. +Heaps are also examples of data structures called +\spadglossSee{bags}{bag}. +Other bag data structures are \spadtype{Stack}, \spadtype{Queue}, +and \spadtype{Dequeue}.} +A heap is organized +so as to optimize insertion and extraction of maximum elements. +The \spadfunX{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. + +\xtc{ +An easy way to create a heap is to apply the +operation \spadfun{heap} to a list of values. +}{ +\spadpaste{h := heap [-4,7,11,3,4,-7]\bound{h}} +} +\xtc{ +This loop extracts elements one-at-a-time from \spad{h} +until the heap is exhausted, returning the elements +as a list in the order they were extracted. +}{ +\spadpaste{[extract!(h) while not empty?(h)]\free{h}} +} + +A \spadgloss{binary tree} is a ``tree'' with at most two branches +%-% \HDindex{tree}{ugIntroCollectPage}{1.6.}{Data Structures} +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{Example of binary tree types are +\spadtype{BinarySearchTree} (see \downlink{`BinarySearchTree'}{BinarySearchTreeXmpPage}\ignore{BinarySearchTree}, +\spadtype{PendantTree}, \spadtype{TournamentTree}, +and \spadtype{BalancedBinaryTree} (see \downlink{`BalancedBinaryTree'}{BalancedBinaryTreeXmpPage}\ignore{BalancedBinaryTree}).} + +\xtc{ +A {\it binary search tree} is a binary tree such that, +%-% \HDindex{tree!binary search}{ugIntroCollectPage}{1.6.}{Data Structures} +for each node, the value of the node is +%-% \HDindex{binary search tree}{ugIntroCollectPage}{1.6.}{Data Structures} +greater than all values (if any) in the left subtree, +and less than or equal all values (if any) in the right subtree. +}{ +\spadpaste{binarySearchTree [5,3,2,9,4,7,11]} +} + +\xtc{ +A {\it balanced binary tree} is useful for doing modular computations. +%-% \HDindex{balanced binary tree}{ugIntroCollectPage}{1.6.}{Data Structures} +Given a list \axiom{lm} of moduli, +%-% \HDindex{tree!balanced binary}{ugIntroCollectPage}{1.6.}{Data Structures} +\axiomFun{modTree}\axiom{(a,lm)} produces a balanced binary +tree with the values \texht{$a \bmod m$}{a {\tt mod} m} +at its leaves. +}{ +\spadpaste{modTree(8,[2,3,5,7])} +} + +A \spadgloss{set} is a collection of elements where duplication +and order is irrelevant.\footnote{See \downlink{`Set'}{SetXmpPage}\ignore{Set} for more +details.} +Sets are always finite and have no corresponding +structure like streams for infinite collections. + +\xtc{ +%Create sets using braces (\axiomSyntax{\{} and \axiomSyntax{\}}) +%rather than brackets. +}{ +\spadpaste{fs := set[1/3,4/5,-1/3,4/5] \bound{fs}} +} + +A \spadgloss{multiset} +is a set that keeps track of the number +of duplicate values.\footnote{See \downlink{`MultiSet'}{MultiSetXmpPage}\ignore{MultiSet} for details.} +\xtc{ +For all the primes \axiom{p} between 2 and 1000, find the +distribution of \texht{$p \bmod 5$}{p mod 5}. +}{ +\spadpaste{multiset [x rem 5 for x in primes(2,1000)]} +} + +A \spadgloss{table} +is conceptually a set of ``key--value'' pairs and +is a generalization of a multiset.\footnote{For examples of tables, see +\spadtype{AssociationList} (\downlink{`AssociationList'}{AssociationListXmpPage}\ignore{AssociationList}), +\spadtype{HashTable}, +\spadtype{KeyedAccessFile} (\downlink{`KeyedAccessFile'}{KeyedAccessFileXmpPage}\ignore{KeyedAccessFile}), +\spadtype{Library} (\downlink{`Library'}{LibraryXmpPage}\ignore{Library}), +\spadtype{SparseTable} (\downlink{`SparseTable'}{SparseTableXmpPage}\ignore{SparseTable}), +\spadtype{StringTable} (\downlink{`StringTable'}{StringTableXmpPage}\ignore{StringTable}), +and \spadtype{Table} (\downlink{`Table'}{TableXmpPage}\ignore{Table}).} +The domain \spadtype{Table(Key, Entry)} provides a general-purpose +type for tables with {\it values} of type \axiom{Entry} indexed +by {\it keys} of type \axiom{Key}. + +\xtc{ +Compute the above distribution of primes using tables. +First, let \axiom{t} denote an empty table of keys and values, +each of type \spadtype{Integer}. +}{ +\spadpaste{t : Table(Integer,Integer) := empty()\bound{t}} +} + +We define a function \userfun{howMany} to return the number +of values of a given modulus \axiom{k} seen so far. +It calls \axiomFun{search}\axiom{(k,t)} which returns the number of +values stored under the key \axiom{k} in table \axiom{t}, or +\axiom{"failed"} if no such value is yet stored in \axiom{t} under +\axiom{k}. + +\xtc{ +In English, this says ``Define \axiom{howMany(k)} as follows. +First, let \smath{n} be the value of \axiomFun{search}\smath{(k,t)}. +Then, if \smath{n} has the value \smath{"failed"}, return the value +\smath{1}; otherwise return \smath{n + 1}.'' +}{ +\spadpaste{howMany(k) == (n:=search(k,t); n case "failed" => 1; n+1)\bound{how}} +} +\xtc{ +Run through the primes to create the table, then print the table. +The expression \axiom{t.m := howMany(m)} updates the value in table \axiom{t} +stored under key \axiom{m}. +}{ +\spadpaste{for p in primes(2,1000) repeat (m:= p rem 5; t.m:= howMany(m)); t\free{how t}} +} + +A {\it record} +is an example of an inhomogeneous collection +of objects.\footnote{See \downlink{``\ugTypesRecordsTitle''}{ugTypesRecordsPage} in Section \ugTypesRecordsNumber\ignore{ugTypesRecords} for details.} +A record consists of a set of named {\it selectors} that +can be used to access its components. +%-% \HDindex{Record@{\sf Record}}{ugIntroCollectPage}{1.6.}{Data Structures} + +\xtc{ +Declare that \axiom{daniel} can only be +assigned a record with two prescribed fields. +}{ +\spadpaste{daniel : Record(age : Integer, salary : Float) \bound{danieldec}} +} +\xtc{ +Give \axiom{daniel} a value, using square brackets to enclose the values of +the fields. +}{ +\spadpaste{daniel := [28, 32005.12] \free{danieldec}\bound{daniel}} +} +\xtc{ +Give \axiom{daniel} a raise. +}{ +\spadpaste{daniel.salary := 35000; daniel \free{daniel}} +} + +A {\it union} +is a data structure used when objects +have multiple types.\footnote{See \downlink{``\ugTypesUnionsTitle''}{ugTypesUnionsPage} in Section \ugTypesUnionsNumber\ignore{ugTypesUnions} for details.} +%-% \HDindex{Union@{\sf Union}}{ugIntroCollectPage}{1.6.}{Data Structures} + +\xtc{ +Let \axiom{dog} be either an integer or a string value. +}{ +\spadpaste{dog: Union(licenseNumber: Integer, name: String)\bound{xint}} +} +\xtc{ +Give \axiom{dog} a name. +}{ +\spadpaste{dog := "Whisper"\free{xint}} +} + +All told, there are over forty different data structures in +\Language{}. +Using the domain constructors described in \downlink{``\ugDomainsTitle''}{ugDomainsPage} in Chapter \ugDomainsNumber\ignore{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. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroTwoDimTitle}{Expanding to Higher Dimensions} +\newcommand{\ugIntroTwoDimNumber}{1.7.} +% +% ===================================================================== +\begin{page}{ugIntroTwoDimPage}{1.7. Expanding to Higher Dimensions} +% ===================================================================== +\beginscroll +% + +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} +%-% \HDindex{matrix}{ugIntroTwoDimPage}{1.7.}{Expanding to Higher Dimensions} +and {\it matrices} most useful. +%-% \HDindex{array!two-dimensional}{ugIntroTwoDimPage}{1.7.}{Expanding to Higher Dimensions} + +The entries in \spadtype{TwoDimensionalArray} and +\spadtype{Matrix} objects +are all the same type, except that those for +\spadtype{Matrix} must belong to a \spadtype{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 +\spadtype{Matrix}, that can be regarded as an extension of +\spadtype{TwoDimensionalArray}.\footnote{See +\downlink{`TwoDimensionalArray'}{TwoDimensionalArrayXmpPage}\ignore{TwoDimensionalArray} for more information about arrays. +For more information about \Language{}'s linear algebra +facilities, see \downlink{`Matrix'}{MatrixXmpPage}\ignore{Matrix}, \downlink{`Permanent'}{PermanentXmpPage}\ignore{Permanent}, +\downlink{`SquareMatrix'}{SquareMatrixXmpPage}\ignore{SquareMatrix}, \downlink{`Vector'}{VectorXmpPage}\ignore{Vector}, +\downlink{``\ugProblemEigenTitle''}{ugProblemEigenPage} in Section \ugProblemEigenNumber\ignore{ugProblemEigen}\texht{(computation of eigenvalues and +eigenvectors)}{}, and +\downlink{``\ugProblemLinPolEqnTitle''}{ugProblemLinPolEqnPage} in Section \ugProblemLinPolEqnNumber\ignore{ugProblemLinPolEqn}\texht{(solution of linear and +polynomial equations)}{}.} + +\xtc{ +You can create a matrix from a list of lists, +%-% \HDindex{matrix!creating}{ugIntroTwoDimPage}{1.7.}{Expanding to Higher Dimensions} +where each of the inner lists represents a row of the matrix. +}{ +\spadpaste{m := matrix([[1,2], [3,4]]) \bound{m}} +} +\xtc{ +The ``collections'' construct (see \downlink{``\ugLangItsTitle''}{ugLangItsPage} in Section \ugLangItsNumber\ignore{ugLangIts}) is +useful for creating matrices whose entries are given by formulas. +%-% \HDindex{matrix!Hilbert}{ugIntroTwoDimPage}{1.7.}{Expanding to Higher Dimensions} +}{ +\spadpaste{matrix([[1/(i + j - x) for i in 1..4] for j in 1..4]) \bound{hilb}} +} +\xtc{ +Let \axiom{vm} denote the three by three Vandermonde matrix. +}{ +\spadpaste{vm := matrix [[1,1,1], [x,y,z], [x*x,y*y,z*z]] \bound{vm}} +} +\xtc{ +Use this syntax to extract an entry in the matrix. +}{ +\spadpaste{vm(3,3) \free{vm}} +} +\xtc{ +You can also pull out a \axiomFun{row} or a \axiom{column}. +}{ +\spadpaste{column(vm,2) \free{vm}} +} +\xtc{ +You can do arithmetic. +}{ +\spadpaste{vm * vm \free{vm}} +} +\xtc{ +You can perform operations such as +\axiomFun{transpose}, \axiomFun{trace}, and \axiomFun{determinant}. +}{ +\spadpaste{factor determinant vm \free{vm}\bound{d}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroYouTitle}{Writing Your Own Functions} +\newcommand{\ugIntroYouNumber}{1.8.} +% +% ===================================================================== +\begin{page}{ugIntroYouPage}{1.8. Writing Your Own Functions} +% ===================================================================== +\beginscroll +% + +\Language{} provides you with a very large library of predefined +operations and objects to compute with. +You can use the \Language{} 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 +\Language{} programs to tackle your application. +\Language{} allows you to write functions interactively, +%-% \HDindex{function}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +thereby effectively extending the system library. +Here we give a few simple examples, leaving the details to \downlink{``\ugUserTitle''}{ugUserPage} in Chapter \ugUserNumber\ignore{ugUser}. + +We begin by looking at several ways that you can define the +``factorial'' function in \Language{}. +The first way is to give a +%-% \HDindex{function!piece-wise definition}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +piece-wise definition of the function. +%-% \HDindex{piece-wise function definition}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +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. + +\xtc{ +Define the value of \userfun{fact} at \axiom{0}. +}{ +\spadpaste{fact(0) == 1 \bound{fact}} +} +\xtc{ +Define the value of \axiom{fact(n)} for general \axiom{n}. +}{ +\spadpaste{fact(n) == n*fact(n-1)\bound{facta}\free{fact}} +} +\xtc{ +Ask for the value at \axiom{50}. +The resulting function created by \Language{} +computes the value by iteration. +}{ +\spadpaste{fact(50) \free{facta}} +} +\xtc{ +A second definition uses an \axiom{if-then-else} and recursion. +}{ +\spadpaste{fac(n) == if n < 3 then n else n * fac(n - 1) \bound{fac}} +} +\xtc{ +This function is less efficient than the previous version since +each iteration involves a recursive function call. +}{ +\spadpaste{fac(50) \free{fac}} +} +\xtc{ +A third version directly uses iteration. +}{ +\spadpaste{fa(n) == (a := 1; for i in 2..n repeat a := a*i; a) \bound{fa}} +} +\xtc{ +This is the least space-consumptive version. +}{ +\spadpaste{fa(50) \free{fa}} +} +\xtc{ +A final version appears to construct a large list and then reduces over +it with multiplication. +}{ +\spadpaste{f(n) == reduce(*,[i for i in 2..n]) \bound{f}} +} +\xtc{ +In fact, the resulting computation is optimized into an efficient +iteration loop equivalent to that of the third version. +}{ +\spadpaste{f(50) \free{f}} +} +\xtc{ +The library version uses an algorithm that is different from the four +above because it highly optimizes the recurrence relation definition of +\axiomFun{factorial}. +}{ +\spadpaste{factorial(50)} +} + +You are not limited to one-line functions in \Language{}. +If you place your function definitions in {\bf .input} files +%-% \HDindex{file!input}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +(see \downlink{``\ugInOutInTitle''}{ugInOutInPage} in Section \ugInOutInNumber\ignore{ugInOutIn}), you can have +multi-line functions that use indentation for grouping. + +Given \axiom{n} elements, \axiomFun{diagonalMatrix} creates an +\axiom{n} by \axiom{n} matrix with those elements down the diagonal. +This function uses a permutation matrix +that interchanges the \axiom{i}th and \axiom{j}th rows of a matrix +by which it is right-multiplied. + +\xtc{ +This function definition shows a style of definition that can be used +in {\bf .input} files. +Indentation is used to create \spadglossSee{blocks}{block}\texht{\/}{}: +sequences of expressions that are evaluated in sequence except as +modified by control statements such as \axiom{if-then-else} and \axiom{return}. +}{ +\begin{spadsrc}[\bound{permMat}] +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{spadsrc} +} +\xtc{ +This creates a four by four matrix that interchanges the second and third +rows. +}{ +\spadpaste{p := permMat(4,2,3) \free{permMat}\bound{p}} +} +\xtc{ +Create an example matrix to permute. +}{ +\spadpaste{m := matrix [[4*i + j for j in 1..4] for i in 0..3]\bound{m}} +} +\xtc{ +Interchange the second and third rows of m. +}{ +\spadpaste{permMat(4,2,3) * m \free{p m}} +} + +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. + +\xtc{ +This declares \userfun{t} to be a two-argument function that +returns a \spadtype{Float}. +The first argument is a function that takes one \spadtype{Float} +argument and returns a \spadtype{Float}. +}{ +\spadpaste{t : (Float -> Float, Float) -> Float \bound{tdecl}} +} +\xtc{ +This is the definition of \userfun{t}. +}{ +\spadpaste{t(fun, x) == fun(x)**2 + sin(x)**2 \free{tdecl}\bound{t}} +} +\xtc{ +We have not defined a \axiomFun{cos} in the workspace. The one from the +\Language{} library will do. +}{ +\spadpaste{t(cos, 5.2058) \free{t}} +} +\xtc{ +Here we define our own (user-defined) function. +}{ +\spadpaste{cosinv(y) == cos(1/y) \bound{cosinv}} +} +\xtc{ +Pass this function as an argument to \userfun{t}. +}{ +\spadpaste{t(cosinv, 5.2058) \free{t}\free{cosinv}} +} + +\Language{} also has pattern matching capabilities for +%-% \HDindex{simplification}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +simplification +%-% \HDindex{pattern matching}{ugIntroYouPage}{1.8.}{Writing Your Own Functions} +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: +\texht{$$\sqrt{a}\:\sqrt{b} \mapsto \sqrt{ab}, \quad +(\forall a)(\forall b)$$}{\axiom{sqrt(a) * sqrt(b) by sqrt(a*b)} for any \axiom{a} and \axiom{b}} +Note that such a transformation is not generally correct. +\Language{} never uses it automatically. + +\xtc{ +Give this rule the name \userfun{groupSqrt}. +}{ +\spadpaste{groupSqrt := rule(sqrt(a) * sqrt(b) == sqrt(a*b)) \bound{g}} +} +\xtc{ +Here is a test expression. +}{ +\spadpaste{a := (sqrt(x) + sqrt(y) + sqrt(z))**4 \bound{sxy}} +} +\xtc{ +The rule +\userfun{groupSqrt} successfully simplifies the expression. +}{ +\spadpaste{groupSqrt a \free{sxy} \free{g}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroVariablesTitle}{Polynomials} +\newcommand{\ugIntroVariablesNumber}{1.9.} +% +% ===================================================================== +\begin{page}{ugIntroVariablesPage}{1.9. Polynomials} +% ===================================================================== +\beginscroll +% + +Polynomials are the commonly used algebraic types in symbolic +computation. +%-% \HDindex{polynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +Interactive users of \Language{} generally only see one type +of polynomial: \spadtype{Polynomial(R)}. +This type represents polynomials in any number of unspecified +variables over a particular coefficient domain \axiom{R}. +This type represents its coefficients +\spadglossSee{sparsely}{sparse}: only terms with non-zero +coefficients are represented. +%-% \HDexptypeindex{Polynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} + +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. + +\xtc{ +The polynomial constructor most familiar to the interactive user +is \spadtype{Polynomial}. +}{ +\spadpaste{(x**2 - x*y**3 +3*y)**2} +} +\xtc{ +If you wish to restrict the variables used, +\spadtype{UnivariatePolynomial} +provides polynomials in one variable. +%-% \HDexptypeindex{UnivariatePolynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +}{ +\spadpaste{p: UP(x,INT) := (3*x-1)**2 * (2*x + 8)} +} +\xtc{ +The constructor +\spadtype{MultivariatePolynomial} provides polynomials in one or more +specified variables. +%-% \HDexptypeindex{MultivariatePolynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +}{ +\spadpaste{m: MPOLY([x,y],INT) := (x**2-x*y**3+3*y)**2 \bound{m}} +} +\xtc{ +You can change the way the polynomial appears by modifying the variable +ordering in the explicit list. +}{ +\spadpaste{m :: MPOLY([y,x],INT) \free{m}} +} +\xtc{ +The constructor +\spadtype{DistributedMultivariatePolynomial} provides +polynomials in one or more specified variables with the monomials +ordered lexicographically. +%-% \HDexptypeindex{DistributedMultivariatePolynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +}{ +\spadpaste{m :: DMP([y,x],INT) \free{m}} +} +\xtc{ +The constructor +\spadtype{HomogeneousDistributedMultivariatePolynomial} is similar except that +the monomials are ordered by total order refined by reverse +lexicographic order. +%-% \HDexptypeindex{HomogeneousDistributedMultivariatePolynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +}{ +\spadpaste{m :: HDMP([y,x],INT) \free{m}} +} + +More generally, the domain constructor +\spadtype{GeneralDistributedMultivariatePolynomial} allows the +user to provide an arbitrary predicate to define his own term ordering. +%-% \HDexptypeindex{GeneralDistributedMultivariatePolynomial}{ugIntroVariablesPage}{1.9.}{Polynomials} +These last three constructors are typically used in +\texht{Gr\"{o}bner}{Groebner} basis +%-% \HDindex{Groebner basis@{Gr\protect\"{o}bner basis}}{ugIntroVariablesPage}{1.9.}{Polynomials} +applications and when a flat (that is, non-recursive) display is +wanted and the term ordering is critical for controlling the computation. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroCalcLimitsTitle}{Limits} +\newcommand{\ugIntroCalcLimitsNumber}{1.10.} +% +% ===================================================================== +\begin{page}{ugIntroCalcLimitsPage}{1.10. Limits} +% ===================================================================== +\beginscroll +% + +\Language{}'s \axiomFun{limit} function is usually used to +evaluate limits of quotients where the numerator and denominator +%-% \HDindex{limit}{ugIntroCalcLimitsPage}{1.10.}{Limits} +both tend to zero or both tend to infinity. +To find the limit of an expression \axiom{f} as a real variable +\axiom{x} tends to a limit value \axiom{a}, enter \axiom{limit(f, x=a)}. +Use \axiomFun{complexLimit} if the variable is complex. +Additional information and examples of limits are in +\downlink{``\ugProblemLimitsTitle''}{ugProblemLimitsPage} in Section \ugProblemLimitsNumber\ignore{ugProblemLimits}. + +\xtc{ +You can take limits of functions with parameters. +%-% \HDindex{limit!of function with parameters}{ugIntroCalcLimitsPage}{1.10.}{Limits} +}{ +\spadpaste{g := csc(a*x) / csch(b*x) \bound{g}} +} +\xtc{ +As you can see, the limit is expressed in terms of the parameters. +}{ +\spadpaste{limit(g,x=0) \free{g}} +} +% +\xtc{ +A variable may also approach plus or minus infinity: +}{ +\spadpaste{h := (1 + k/x)**x \bound{h}} +} +\xtc{ +\texht{Use \axiom{\%plusInfinity} and \axiom{\%minusInfinity} to +denote $\infty$ and $-\infty$.}{} +}{ +\spadpaste{limit(h,x=\%plusInfinity) \free{h}} +} +\xtc{ +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. +}{ +\spadpaste{limit(sqrt(y**2)/y,y = 0)} +} +\xtc{ +As \axiom{x} approaches \axiom{0} along the real axis, \axiom{exp(-1/x**2)} +tends to \axiom{0}. +}{ +\spadpaste{limit(exp(-1/x**2),x = 0)} +} +\xtc{ +However, if \axiom{x} is allowed to approach \axiom{0} along any path in the +complex plane, the limiting value of \axiom{exp(-1/x**2)} depends on the +path taken because the function has an essential singularity at \axiom{x=0}. +This is reflected in the error message returned by the function. +}{ +\spadpaste{complexLimit(exp(-1/x**2),x = 0)} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroSeriesTitle}{Series} +\newcommand{\ugIntroSeriesNumber}{1.11.} +% +% ===================================================================== +\begin{page}{ugIntroSeriesPage}{1.11. Series} +% ===================================================================== +\beginscroll +% + +\Language{} also provides power series. +%-% \HDindex{series!power}{ugIntroSeriesPage}{1.11.}{Series} +By default, \Language{} tries to compute and display the first ten elements +of a series. +Use \spadsys{)set streams calculate} to change the default value +to something else. +%-% \HDsyscmdindex{set streams calculate}{ugIntroSeriesPage}{1.11.}{Series} +For the purposes of this book, we have used this system command to display +fewer than ten terms. +For more information about working with series, see +\downlink{``\ugProblemSeriesTitle''}{ugProblemSeriesPage} in Section \ugProblemSeriesNumber\ignore{ugProblemSeries}. + +\xtc{ +You can convert a functional expression to a power series by using the +operation \axiomFun{series}. +In this example, +\axiom{sin(a*x)} is expanded in powers of \axiom{(x - 0)}, +that is, in powers of \axiom{x}. +}{ +\spadpaste{series(sin(a*x),x = 0)} +} +\xtc{ +This expression expands +\axiom{sin(a*x)} in powers of \axiom{(x - \%pi/4)}. +}{ +\spadpaste{series(sin(a*x),x = \%pi/4)} +} +\xtc{ +\Language{} provides +%-% \HDindex{series!Puiseux}{ugIntroSeriesPage}{1.11.}{Series} +{\it Puiseux series:} +%-% \HDindex{Puiseux series}{ugIntroSeriesPage}{1.11.}{Series} +series with rational number exponents. +The first argument to \axiomFun{series} is an in-place function that +computes the \eth{\axiom{n}} coefficient. +(Recall that +the \axiomSyntax{+->} is an infix operator meaning ``maps to.'') +}{ +\spadpaste{series(n +-> (-1)**((3*n - 4)/6)/factorial(n - 1/3),x = 0,4/3..,2)} +} +\xtc{ +Once you have created a power series, you can perform arithmetic operations +on that series. +We compute the Taylor expansion of \axiom{1/(1-x)}. +%-% \HDindex{series!Taylor}{ugIntroSeriesPage}{1.11.}{Series} +}{ +\spadpaste{f := series(1/(1-x),x = 0) \bound{f}} +} +\xtc{ +Compute the square of the series. +}{ +\spadpaste{f ** 2 \free{f}} +} +\xtc{ +The usual elementary functions +(\axiomFun{log}, \axiomFun{exp}, trigonometric functions, and so on) +are defined for power series. +}{ +\spadpaste{f := series(1/(1-x),x = 0) \bound{f1}} +} +\xtc{ +}{ +\spadpaste{g := log(f) \free{f1}\bound{g}} +} +\xtc{ +}{ +\spadpaste{exp(g) \free{g}} +} +\xtc{ +Here is a way to obtain numerical approximations of +\axiom{e} from the Taylor series expansion of \axiom{exp(x)}. +First create the desired Taylor expansion. +}{ +\spadpaste{f := taylor(exp(x)) \bound{f2}} +} +\xtc{ +Evaluate the series at the value \axiom{1.0}. +As you see, you get a sequence of partial sums. +}{ +\spadpaste{eval(f,1.0) \free{f2}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroCalcDerivTitle}{Derivatives} +\newcommand{\ugIntroCalcDerivNumber}{1.12.} +% +% ===================================================================== +\begin{page}{ugIntroCalcDerivPage}{1.12. Derivatives} +% ===================================================================== +\beginscroll +% +Use the \Language{} function \axiomFun{D} to differentiate an +%-% \HDindex{derivative}{ugIntroCalcDerivPage}{1.12.}{Derivatives} +expression. +%-% \HDindex{differentiation}{ugIntroCalcDerivPage}{1.12.}{Derivatives} + +\texht{\vskip 2pc}{} +\xtc{ +To find the derivative of an expression \axiom{f} with respect to a +variable \axiom{x}, enter \axiom{D(f, x)}. +}{ +\spadpaste{f := exp exp x \bound{f}} +} +\xtc{ +}{ +\spadpaste{D(f, x) \free{f}} +} +\xtc{ +An optional third argument \axiom{n} in \axiomFun{D} asks +\Language{} for the \eth{\axiom{n}} derivative of \axiom{f}. +This finds the fourth derivative of \axiom{f} with respect to \axiom{x}. +}{ +\spadpaste{D(f, x, 4) \free{f}} +} +\xtc{ +You can also compute partial derivatives by specifying the order of +%-% \HDindex{differentiation!partial}{ugIntroCalcDerivPage}{1.12.}{Derivatives} +differentiation. +}{ +\spadpaste{g := sin(x**2 + y) \bound{g}} +} +\xtc{ +}{ +\spadpaste{D(g, y) \free{g}} +} +\xtc{ +}{ +\spadpaste{D(g, [y, y, x, x]) \free{g}} +} + +\Language{} can manipulate the derivatives (partial and iterated) of +%-% \HDindex{differentiation!formal}{ugIntroCalcDerivPage}{1.12.}{Derivatives} +expressions involving formal operators. +All the dependencies must be explicit. +\xtc{ +This returns \axiom{0} since \axiom{F} (so far) +does not explicitly depend on \axiom{x}. +}{ +\spadpaste{D(F,x)} +} +Suppose that we have \axiom{F} a function of \axiom{x}, +\axiom{y}, and \axiom{z}, where \axiom{x} and \axiom{y} are themselves +functions of \axiom{z}. +\xtc{ +Start by declaring that \axiom{F}, \axiom{x}, and \axiom{y} +are operators. +%-% \HDindex{operator}{ugIntroCalcDerivPage}{1.12.}{Derivatives} +}{ +\spadpaste{F := operator 'F; x := operator 'x; y := operator 'y\bound{F x y}} +} +\xtc{ +You can use \axiom{F}, \axiom{x}, and \axiom{y} in expressions. +}{ +\spadpaste{a := F(x z, y z, z**2) + x y(z+1) \bound{a}\free{F}\free{x}\free{y}} +} +\xtc{ +Differentiate formally with respect to \axiom{z}. +The formal derivatives appearing in \axiom{dadz} are not just formal symbols, +but do represent the derivatives of \axiom{x}, \axiom{y}, and \axiom{F}. +}{ +\spadpaste{dadz := D(a, z)\bound{da}\free{a}} +} +\xtc{ +You can evaluate the above for particular functional +values of \axiom{F}, \axiom{x}, and \axiom{y}. +If \axiom{x(z)} is \axiom{exp(z)} and \axiom{y(z)} is \axiom{log(z+1)}, then +this evaluates \axiom{dadz}. +}{ +\spadpaste{eval(eval(dadz, 'x, z +-> exp z), 'y, z +-> log(z+1))\free{da}} +} +\xtc{ +You obtain the same result by first evaluating \axiom{a} and +then differentiating. +}{ +\spadpaste{eval(eval(a, 'x, z +-> exp z), 'y, z +-> log(z+1)) \free{a}\bound{eva}} +} +\xtc{ +}{ +\spadpaste{D(\%, z)\free{eva}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroIntegrateTitle}{Integration} +\newcommand{\ugIntroIntegrateNumber}{1.13.} +% +% ===================================================================== +\begin{page}{ugIntroIntegratePage}{1.13. Integration} +% ===================================================================== +\beginscroll +% + +\Language{} has extensive library facilities for integration. +%-% \HDindex{integration}{ugIntroIntegratePage}{1.13.}{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. + +\xtc{ +We use a factorization-free algorithm. +}{ +\spadpaste{integrate((x**2+2*x+1)/((x+1)**6+1),x)} +} + +When real parameters are present, the form of the integral can depend on +the signs of some expressions. + +\xtc{ +Rather than query the user or make sign assumptions, \Language{} returns +all possible answers. +}{ +\spadpaste{integrate(1/(x**2 + a),x)} +} + +The \axiomFun{integrate} operation generally assumes that all +parameters are real. +The only exception is when the integrand has complex valued +quantities. + +\xtc{ +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: +}{ +\spadpaste{complexIntegrate(1/(x**2 + a),x)} +} + +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. + +\xtc{ +This one is the easy one. +The next one looks very similar +but the answer is much more complicated. +}{ +\spadpaste{integrate(x**3 / (a+b*x)**(1/3),x)} +} +\xtc{ +Only an algorithmic approach +is guaranteed to find what new constants must be added in order to +find a solution. +}{ +\spadpaste{integrate(1 / (x**3 * (a+b*x)**(1/3)),x)} +} + +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.'' \Language{} uses a +algorithm for integration. +that conclusively proves that an integral cannot be expressed in +terms of elementary functions. + +\xtc{ +When \Language{} returns an integral sign, it has proved +that no answer exists as an elementary function. +}{ +\spadpaste{integrate(log(1 + sqrt(a*x + b)) / x,x)} +} +\Language{} can handle complicated mixed functions much beyond what you +can find in tables. +\xtc{ +Whenever possible, \Language{} tries to express the answer using the functions +present in the integrand. +}{ +\spadpaste{integrate((sinh(1+sqrt(x+b))+2*sqrt(x+b)) / (sqrt(x+b) * (x + cosh(1+sqrt(x + b)))), x)} +} +\xtc{ +A strong structure-checking algorithm in \Language{} finds hidden algebraic +relationships between functions. +}{ +\spadpaste{integrate(tan(atan(x)/3),x)} +} +\noindent +%%--> Bob---> please make these formulas in this section smaller. +The discovery of this algebraic relationship is necessary for correct +integration of this function. +Here are the details: +\indent{4} +\beginitems +\item[1. ] +If \texht{$x=\tan t$}{\axiom{x=tan(t)}} and +\texht{$g=\tan (t/3)$}{\axiom{g=tan(t/3)}} then the following +algebraic relation is true: +\texht{$${g^3-3xg^2-3g+x=0}$$}{\centerline{\axiom{g**3 - 3*x*g**2 - 3*g + x = 0}}} +\item[2. ] +Integrate \axiom{g} using this algebraic relation; this produces: +\texht{$${% +{(24g^2 - 8)\log(3g^2 - 1) + (81x^2 + 24)g^2 + 72xg - 27x^2 - 16} +\over{54g^2 - 18}}$$}{\centerline{\axiom{(24g**2 - 8)log(3g**2 - 1) + +(81x**2 + 24)g**2 + 72xg - 27x**2 - 16/ (54g**2 - 18)}}} +\item[3. ] +Rationalize the denominator, producing: +\texht{\narrowDisplay{{8\log(3g^2-1) - 3g^2 + 18xg + 16} \over +{18}}}{\centerline{\axiom{(8*log(3*g**2-1) - 3*g**2 + 18*x*g + 16)/18}}} +Replace \axiom{g} by the initial definition +\texht{$g = \tan(\arctan(x)/3)$}{\axiom{g = tan(arctan(x)/3)}} +to produce the final result. +\enditems +\indent{0} + +\xtc{ +This is an example of a mixed function where +the algebraic layer is over the transcendental one. +}{ +\spadpaste{integrate((x + 1) / (x*(x + log x) ** (3/2)), x)} +} +\xtc{ +While incomplete for non-elementary functions, \Language{} can +handle some of them. +}{ +\spadpaste{integrate(exp(-x**2) * erf(x) / (erf(x)**3 - erf(x)**2 - erf(x) + 1),x)} +} + +More examples of \Language{}'s integration capabilities are discussed in +\downlink{``\ugProblemIntegrationTitle''}{ugProblemIntegrationPage} in Section \ugProblemIntegrationNumber\ignore{ugProblemIntegration}. + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroDiffEqnsTitle}{Differential Equations} +\newcommand{\ugIntroDiffEqnsNumber}{1.14.} +% +% ===================================================================== +\begin{page}{ugIntroDiffEqnsPage}{1.14. Differential Equations} +% ===================================================================== +\beginscroll +% +The general approach used in integration also carries over to the +solution of linear differential equations. + +\labelSpace{2pc} +\xtc{ +Let's solve some differential equations. +Let \axiom{y} be the unknown function in terms of \axiom{x}. +}{ +\spadpaste{y := operator 'y \bound{y}} +} +\xtc{ +Here we solve a third order equation with polynomial coefficients. +}{ +\spadpaste{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 \bound{e3}\free{y}} +} +\xtc{ +}{ +\spadpaste{solve(deq, y, x) \free{e3}\free{y}} +} +\xtc{ +Here we find all the algebraic function solutions of the equation. +}{ +\spadpaste{deq := (x**2 + 1) * D(y x, x, 2) + 3 * x * D(y x, x) + y x = 0 \bound{e5}\free{y}} +} +\xtc{ +}{ +\spadpaste{solve(deq, y, x) \free{e5}\free{y}} +} + +Coefficients of differential equations can come from arbitrary +constant fields. +For example, coefficients can contain algebraic numbers. + +\xtc{ +This example has solutions +whose logarithmic derivative is an algebraic function of +degree two. +}{ +\spadpaste{eq := 2*x**3 * D(y x,x,2) + 3*x**2 * D(y x,x) - 2 * y x\bound{eq}\free{y}} +} +\xtc{ +}{ +\spadpaste{solve(eq,y,x).basis\free{eq}} +} + +\xtc{ +Here's another differential equation to solve. +}{ +\spadpaste{deq := D(y x, x) = y(x) / (x + y(x) * log y x) \bound{deqi}\free{y}} +} +\xtc{ +}{ +\spadpaste{solve(deq, y, x) \free{deqi y}} +} + +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. + +\xtc{ +Let's solve a system of nonlinear first order equations and get a +solution in power series. +Tell \Language{} that \axiom{x} is also an operator. +}{ +\spadpaste{x := operator 'x\bound{x}} +} +\xtc{ +Here are the two equations forming our system. +}{ +\spadpaste{eq1 := D(x(t), t) = 1 + x(t)**2\free{x}\free{y}\bound{eq1}} +} +\xtc{ +}{ +\spadpaste{eq2 := D(y(t), t) = x(t) * y(t)\free{x}\free{y}\bound{eq2}} +} +\xtc{ +We can solve the system around \axiom{t = 0} with the initial conditions +\axiom{x(0) = 0} and \axiom{y(0) = 1}. +Notice that since we give the unknowns in the +order \axiom{[x, y]}, the answer is a list of two series in the order +\axiom{[series for x(t), series for y(t)]}. +}{ +\spadpaste{seriesSolve([eq2, eq1], [x, y], t = 0, [y(0) = 1, x(0) = 0])\free{x}\free{y}\free{eq1}\free{eq2}} +} + +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroSolutionTitle}{Solution of Equations} +\newcommand{\ugIntroSolutionNumber}{1.15.} +% +% ===================================================================== +\begin{page}{ugIntroSolutionPage}{1.15. Solution of Equations} +% ===================================================================== +\beginscroll +% + +\Language{} 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 \spadfun{solve} for +real roots and \spadfun{complexSolve} for complex roots. +In each case, you tell \Language{} how accurate you want your +result to be. +All operations in the \spadfun{solve} family return answers in +the form of a list of solution sets, where each solution set is a +list of equations. + +\xtc{ +A system of two equations involving a symbolic +parameter \axiom{t}. +}{ +\spadpaste{S(t) == [x**2-2*y**2 - t,x*y-y-5*x + 5]\bound{S1}} +} +\xtc{ +Find the real roots of \spad{S(19)} with +rational arithmetic, correct to within \smath{1/10^{20}}. +}{ +\spadpaste{solve(S(19),1/10**20)\free{S1}} +} +\xtc{ +Find the complex roots of \spad{S(19)} with floating +point coefficients to \spad{20} digits accuracy in the mantissa. +}{ +\spadpaste{complexSolve(S(19),10.e-20)\free{S1}} +} +\xtc{ +If a system of equations has symbolic coefficients and you want +a solution in radicals, try \spadfun{radicalSolve}. +}{ +\spadpaste{radicalSolve(S(a),[x,y])\free{S1}} +} +For systems of equations with symbolic coefficients, you can +apply \spadfun{solve}, listing the variables that you want +\Language{} 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''. +\xtc{ +A system of three equations in five variables. +}{ +\spadpaste{eqns := [x**2 - y + z,x**2*z + x**4 - b*y, y**2 *z - a - b*x]\bound{e}} +} +\xtc{ +Solve the system for unknowns \smath{[x,y,z]}, +reducing the solution to triangular form. +}{ +\spadpaste{solve(eqns,[x,y,z])\free{e}} +} +\endscroll +\autobuttons +\end{page} +% +% +\newcommand{\ugIntroSysCmmandsTitle}{System Commands} +\newcommand{\ugIntroSysCmmandsNumber}{1.16.} +% +% ===================================================================== +\begin{page}{ugIntroSysCmmandsPage}{1.16. System Commands} +% ===================================================================== +\beginscroll +% + +We conclude our tour of \Language{} with a brief discussion +of \spadgloss{system commands}. +System commands are special statements that start with a +closing parenthesis (\axiomSyntax{)}). They are used to control or +display your \Language{} environment, start the \HyperName{} +system, issue operating system commands and leave \Language{}. +For example, \spadsys{)system} is used +to issue commands to the operating system from \Language{}. +%-% \HDsyscmdindex{system}{ugIntroSysCmmandsPage}{1.16.}{System Commands} +Here is a brief description of some of these commands. +For more information on specific commands, see +\downlink{``\ugSysCmdTitle''}{ugSysCmdPage} in Appendix \ugSysCmdNumber\ignore{ugSysCmd}. + +Perhaps the most important user command is the \spadsys{)clear all} +command that initializes your environment. +Every section and subsection in this book has an invisible +\spadsys{)clear all} that is read prior to the examples given in +the section. +\spadsys{)clear all} gives you a fresh, empty environment with no +user variables defined and the step number reset to \axiom{1}. +The \spadsys{)clear} command can also be used to selectively clear +values and properties of system variables. + +Another useful system command is \spadsys{)read}. +A preferred way to develop an application in \Language{} is to put +your interactive commands into a file, say {\bf my.input} file. +To get \Language{} to read this file, you use the system command +\spadsys{)read my.input}. +If you need to make changes to your approach or definitions, go +into your favorite editor, change {\bf my.input}, then +\spadsys{)read my.input} again. + +Other system commands include: \spadsys{)history}, to display +previous input and/or output lines; \spadsys{)display}, to display +properties and values of workspace variables; and \spadsys{)what}. + +\xtc{ +Issue \spadsys{)what} to get a list of \Language{} objects that +contain a given substring in their name. +}{ +\spadpaste{)what operations integrate} +} + +%\head{subsection}{Undo}{ugIntroUndo} + +A useful system command is \spadcmd{)undo}. +Sometimes while computing interactively with \Language{}, 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 \spadgloss{undo} facility of +\Language{} helpful. + +System command \spadsys{)undo n} means ``undo back to step \axiom{n}''; it +restores the values of user variables to those that existed +immediately after input expression \axiom{n} was evaluated. +Similarly, \spadsys{)undo -n} undoes changes caused by the last +\axiom{n} input expressions. +Once you have done an \spadsys{)undo}, +you can continue on from there, or make a change and +{\bf redo} all your input expressions from the point +of the \spadsys{)undo} forward. +The \spadsys{)undo} is completely general: it changes the environment +like any user expression. +Thus you can \spadsys{)undo} any previous undo. + +Here is a sample dialogue between user and \Language{}. +\xtc{ +``Let me define +two mutually dependent functions \axiom{f} and \axiom{g} piece-wise.'' +}{ +\spadpaste{f(0) == 1; g(0) == 1\bound{u1}} +} +\xtc{ +``Here is the general term for \axiom{f}.'' +}{ +\spadpaste{f(n) == e/2*f(n-1) - x*g(n-1)\bound{u2}\free{u1}} +} +\xtc{ +``And here is the general term for \axiom{g}.'' +}{ +\spadpaste{g(n) == -x*f(n-1) + d/3*g(n-1)\bound{u3}\free{u2}} +} +\xtc{ +``What is value of \axiom{f(3)}?'' +}{ +\spadpaste{f(3)\bound{u4}\free{u3}} +} +\noOutputXtc{ +``Hmm, I think I want to define \axiom{f} differently. +Undo to the environment right after I defined \axiom{f}.'' +}{ +\spadpaste{)undo 2\bound{u5}\free{u4}} +} +\xtc{ +``Here is how I think I want \axiom{f} to be defined instead.'' +}{ +\spadpaste{f(n) == d/3*f(n-1) - x*g(n-1)\bound{u6}\free{u5}} +} +\noOutputXtc{ +Redo the computation from expression \axiom{3} forward. +}{ +\spadpaste{)undo )redo\bound{u7}\free{u6}} +} +\noOutputXtc{ +``I want my old definition of +\axiom{f} after all. Undo the undo and restore +the environment to that immediately after \axiom{(4)}.'' +}{ +\spadpaste{)undo 4\bound{u8}\free{u7}} +} +\xtc{ +``Check that the value of \axiom{f(3)} is restored.'' +}{ +\spadpaste{f(3)\bound{u9}\free{u8}} +} + +After you have gone off on several tangents, then backtracked to +previous points in your conversation using \spadsys{)undo}, you +might want to save all the ``correct'' input commands you issued, +disregarding those undone. +The system command \spadsys{)history )write mynew.input} writes a +clean straight-line program onto the file {\bf mynew.input} on +your disk. + +This concludes your tour of \Language{}. +To disembark, issue the system command \spadsys{)quit} to leave \Language{} +and return to the operating system. +\endscroll +\autobuttons +\end{page} +% |