## MathSolver User's Manual

This is a brief summary of MathSolver's syntax and capabilities as of September 11, 2000. Suggestions are always welcome. For further clarification, consult the example programs.

### Introduction

MathSolver is interpreted and uses Forth-like syntax. This means it behaves much like a ``RPN'' calculater:

```
7 6 + printn
```
```
(13)
```
It handles rational and real numbers:
```
2 3 / 4 + dup print " = " (1.0) * printn
```
```
(14/3) =  (4.666667)
```
More interesting, of course, are symbolic manipulations, like cubing a polynomial:
```
(a+2b) dup dup * * printn
```
```
(1 a^3 + 6 a^2 b + 12 a b^2 + 8 b^3)
```
or taking the derivative of a rational expression:
```
(x^2 + y) (x + y^2) / &x Deriv Printn
```
```
( (-1 x^2 + -2 x y^2 + 1 y) / (1 x^2 + 2 x y^2 + 1 y^4) )
```
Here, the program's output of ``+ -'' where a simple ``- '' would do is rather slovenly. I'm still working on the software, but cosmetics have low priority. (The mentioned problem is eliminated readily by running the standard tool ``sed "ss+ -s- sg"'' as a postprocess.)

### Syntax

A MathSolver program is a list of tokens separated by white space. Two types of token (STRING and EXPRESSION) may have embedded white space (spaces or tabs) but neither may span multiple lines (have embedded line feeds). The string ``//'' is a comment delimiter and causes the remainder of a line to be ignored. Input is case-insensitive: ``Print'', ``print'', ``PRINT'' or even ``pRiNt'' all specify the same command token. Some command words have synonyms: ``Printn,'' for example, can be replaced with just ``?''. A MathSolver program is terminated by EOF, or with an explicit ``Exit'' token.

In addition to certain pre-defined command words, a token may be

• (STRING). A character string, beginning and ending with ``"''. Newlines and tab characters may be inserted as in C syntax.
• (EXPRESSION). An algebraic expression, beginning with ``('' and ending with ``)''.
• (INTEGER). An integer, consisting of digits, optionally preceded by `+' or `-'.
• (USER WORD). A user-defined command word, which can be a program variable or the name of a subprocedure.
• (SET WORD). The character ``:'' followed by a user-defined word. This is used to set the word's value.
• (VARIABLE). The character ``&'' followed by the name of an algebraic variable.
• (PROCEDURE). The token ``begin'' (or simply ``{'') followed by a list of tokens, followed by the token ``end'' (or simply ``}'').

At present, nothing can be done with STRINGs except to print them, so that's what is done: the data stack is not affected.

Input EXPRESSIONs use algebraic notation and are parsed by a separate routine. Each EXPRESSION is turned into a single internal node which is pushed onto the stack. Some expressions can be printed and handled internally, but must be input in a roundabout way. For example, the expression ((3+i)x) is a single term with a complex coefficient, but must be entered as two terms: ``(3x + ix)''.

An INTEGER, like ``17'', should be equivalent to the EXPRESSION ``(17)''. Rational numbers can be built from INTEGERS: ``0 5 - 7 /'' is equivalent to ``(-5/7)''.

A USER WORD can be set to any token and, when invoked, is equivalent to that token.

An exception is STRING: since these are currently never pushed onto the stack, they cannot be popped off and assigned to a User Word. The same effect can be achieved however:

```
{ "Greetings Galaxy!\n" } dup :sayhello :say
```
Here we've created a procedure which does nothing but print a greeting. The above input, however, doesn't print the greeting, but just gives the procedure a name. (To illustrate the homogeneity of tokens, and the power of the ``dup'' command, we actually give the procedure two names.) Later the program input:
```
sayhello sayhello
```
will produce the output:
```
Greetings Galaxy!
Greetings Galaxy!
```

The SET WORD syntax was illustrated in the preceeding example. The input ``7 :Cnt'' is equivalent to the C executable statement ``Cnt = 7;'' and ``Cnt 2 - :Cnt'' is equivalent to ``Cnt -= 2''. Here, ``Cnt'' is used as program variable, but these are not to be confused with the algebraic variables used by MathSolver when it takes derivatives, etc. (Often it may seem convenient to bind, or conceptually equate, an algebraic variable with a program variable of the same name, but this is just a user mnemonic: MathSolver treats the two as of independent name spaces.)

A user word must be SET (with a ``:'' token) before it can be referenced; it is the first such SET which adds the word to an internal lookup table. In some cases this will be counterintuitive: say you define a procedure which uses a program variable, then set the variable; then invoke the procedure. This will fail: you must provide a dummy SET prior to the procedure definition.

Algebraic VARIABLES in MathSolver take names like ``a'', ``x'', ``x_3'', or ``y_17''. There are 500 possible such variables: 25 letters (`a' - `z') and 20 subscripts (`_0' - `_19'). The letters are case-insensitive, and `c' is a synonym of `c_0' and so on. The letter `i' is reserved: it is not a variable, but rather the constant square root of -1.

An expression may consist of just a variable, eg. ``(x_4)'' but when a MathSolver command requires specifically a variable, it must be input not as an expression, but specially, eg. ``&x_4''. For example, the following replaces ``b'' with ``c + 2'' in an expression, followed by the substitution ``c + 2i'':

```
(b^3 + b) dup dup ? (c + 2) &b substit ? (c + 2i) &b substit ?
```
```
(1 b^3 + 1 b)
(1 c^3 + 6 c^2 + 13 c + 10)
(1 c^3 + (0.000+6.000i) c^2 + -11.000 c + (0.000-6.000i))
```
(Note that, at present, MathSolver forces complex numbers into floating-point: I've been too lazy to add rational number support there.)

Finally, PROCEDUREs may be the most confusing part of MathSolver syntax. They can be given names:

```
{ whatever ... "Greetings Galaxy!\n" } :sayhello
```
executed if an expression is constant and positive:
```
{ whatever ... "Greetings Galaxy!\n" } Progvar If
```
or executed repeatedly as long as a popped expression is constant and positive:
```
{ whatever ... "Greetings Galaxy!\n" Progvar } Untilneg
```
Since the name of a procedure is executed rather than pushed onto the stack, it cannot be used with ``If'' or ``Untilneg'' unless encapsulated in another procedure, eg. as:
```
{ whatever } :Foo { Foo Progname } Untilneg
```
The usage of ``If'' and ``Untilneg'' is very clumsy, and I'd be happy to hear suggestions for improvement.

Do not confuse algebraic variables with user words (``program variables''). At present there is no way to bind an algebraic variable to a value, but any instance can be set with the ``Substit'' command.

In the following ``constant'' refers to an expression with no algebraic variable.

### List of Commands

• { ... } :-- A procedure token is built and pushed onto the stack.
• anytoken :any_username :-- The token is popped and retained in a separate named memory.
• any_username :-- The named memory is accessed. If it contains a procedure token, that procedure is executed. Any other token is simply pushed onto the stack.
• Pop :-- Remove and ignore the token at the top of the stack.
• Dup :-- Replicate the top token and push it onto the stack.
• Print :-- Remove the top token and print it on stdout.
• Printn :-- Same as ``Print'' but append a line-feed.
• Add (or ``+''); Subtract (or ``-''); Times (or ``*''); Quotient (or ``/'') :-- Remove the two top tokens from the stack; perform the indicated (symbolic) arithmetic, and push the result onto the stack. If both inputs are polynomials, the result of Add, Subtract or Times is also a polynomial, but the result of Quotient will be a rational expression. You can take the derivative of a rational expression, but not the integral.
• expr Exp :-- The expression, which must be a constant, is replaced with its natural antilogarithm.
• expr1 expr2 variable Substit :-- Pop the three top elements of the stack, pushing the result of substituting expr2 for variable in expr1.
• expression variable Deriv :-- Variable is popped and expression is replaced with its derivative with respect to that variable.
• expression variable Integral :-- Variable is popped and expression is replaced with its integral with respect to that variable.
• expression lbnd ubnd variable DefIntegral :-- Variable, ubnd and lbnd are popped and expression is replaced with its definite integral between lbnd and ubnd.
• expr1 expr2 expr3 Condi :-- Pop the three top elements from the stack, pushing a spline-like expression, with meaning similar to the C syntax ``expr1 > 0 ? expr2 : expr3''. Such an expression can be printed with Print, but cannot be input using the normal ``(...)'' MathSolver syntax.
• 1 BBVheuristic :-- Taking a multiple definite integral of a ``Condi'' spline can get complicated, and MathSolver isn't very smart. In some problems, including Example 4 of the sample program input, the problem particulars mean that, as a complicated integral is expanded, whenever the lower bound is variable the upper bound is constant. When ``1 BBVheuristic'' is specified, MathSolver knows that any integral with Both Bounds Variable (``BBV'') can be ignored. The correct answer would be obtained without specifying this heuristic, but much more slowly. (I know how to fix this, at least for Example 4, but it is cumbersome to program.)
• 0 BBVheuristic :-- Disable that special heuristic. (This is the default.)
• integer Maxvar :-- Specify the number of recognized algebraic variables. If the value is set to 8, for example, the variables `a' - `h' are admissable. If the value is 33, then `a' - `z' are admissable (except `i'), along with `a_1' - `h_1'. `a_0' is a synonym for `a' and so on. The advantage of smaller Maxvar is speed and memory savings.
• 1 Varnamemode :-- This changes the ordering of algebraic variables from `a', `b', ... where `a_1' is the 26'th variable to `a', `a_1',` a_2', ..., `a_19', `b', ... The relevance of the ordering is as to which variable names are admissable when Maxvar has less than its maximum setting of 500.
• expr1 expr2 Equal :-- The equation ``expr1 = expr2'' is entered into a system of equations for subsequent solution.
• expr Zero :-- This is equivalent to ``expr 0 Equal''.
• Linprint :-- Print said system.
• Linsolve :-- Simplify the equations previously entered with ``Equal''. This is useless except insofar as a subsequent `Linprint' is issued. The equations need not be linear equations; on the other hand we don't undertake to simplify them maximally. Running Linsolve two or more times may simplify the system further. We'll call this a feature instead of a bug.
• Linclear :-- Destroy the equation system accesed by `Equal,' `Zero,' `Linsolve,' `Linprint' either to save memory or to allow the specification of a new system of equations.
• a b Bincoeff :-- Replace a and b, which must be constant integers, with the number of ways to choose b items from a set of size a.
• integer Permsize :-- Set the size of permutation vectors.
• integer ... integer Permu :-- ``Permsize'' number of integers are popped and placed into a special permutation token which is pushed on to the stack. The integers should contain one instance each of 0, 1, ..., Permsize-1.
• permutation Pbasis :-- At present this, and Print or Printn, are the only operations supported on permutations. Pbasis enters the permutation into a basis array to define a permutation group.
• Cycix :-- Compute the cyclic index polynomial of the group defined by the basis array, and push it onto the stack as a MathSolver expression.
• Pbclear :-- Clear the basis array, to allow inputting a new basis.
• { whatever } expr If :-- Execute whatever if expr is constant and non-negative, popping both from the stack.
• { whatever } Untilneg :-- Execute whatever and pop an expression from the stack when it concludes. Repeat this process until that expression is non-constant or negative.