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.

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

7 6 + printn

(13)

2 3 / 4 + dup print " = " (1.0) * printn

(14/3) = (4.666667)

(a+2b) dup dup * * printn

(1 a^3 + 6 a^2 b + 12 a b^2 + 8 b^3)

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

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:

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{ "Greetings Galaxy!\n" } dup :sayhello :say

sayhello sayhello

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

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

executed if an expression is constant and positive:{ whatever ... "Greetings Galaxy!\n" } :sayhello

{ whatever ... "Greetings Galaxy!\n" } Progvar If

{ whatever ... "Greetings Galaxy!\n" Progvar } Untilneg

{ whatever } :Foo { Foo Progname } Untilneg

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.

**{ ... } :--**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.

Go back to my home page.