Reference

samuel(1)

symbolic interactive calculator

NAME

samuel - symbolic interactive calculator

SYNOPSIS

samuel [options]

DESCRIPTION

samuel is a simple algebraic calculator based on saml(3), the Simple Algebraic Math Library. It can be used interactively or, conversely, as a filter, so you can build shell scripts around it. The input can contain any of the following:

??

Lists all variables. The associated mref number is written in parentheses.

expr;

The expression is evaluated, and printed on standard output (unless it is an assignment). It is also stored in the special variable last. This variable will be clobbered by the next expression. Assignments are a special case of expressions, and are described below. All expressions must be semicolon-terminated.

<“filename”

Include (source) a file. From this point, samuel will read from the file indicated, and tokenize the input using the same rules as before. When an end-of-file condition is detected, samuel closes the file and reverts to the previous input stream. You can have up to 9 nested includes, that is, 10 input streams opened at once (including stdin).

Expressions

An expr can be any of the following:

integer

Any sequence of decimal digits; thus, always non-negative. They can be as big as you want.

\literal

An identifier preceded by a backslash represents a literal. In some cases, the backslash can be omitted; see the discussion below.

?variable

Read the value of a variable. In some cases, the question mark can be omitted, see below. If no such variable exists, an error is returned.

^variable

The current value of variable is returned, and then the variable is destroyed. If there was no variable with this name, an error is returned.

identifier

Return the value of the identifier. There is some magic involved here. In "normal" mode, the identifier is assumed to be a variable if there is one with this name, and a literal otherwise; moreover, subscripted identifiers will be handed to the induce(1) program, unless the option -i has been chosen. In "explicit-variables" mode, a naked identifier will always be interpreted as a literal.

tensorid!number

Defines a tensor of order one with one coordinate (this will work only if you have enabled tensors via the -t option; otherwise, you'll get type conflict errors very quickly). You can add and multiply these basic blocks to obtain tensors of any order. The tensorid can be any identifier (even bracketed or subscripted) and the number must be a small non-negative integer representing the coordinate number.

lvalue = expr

The value of expr is stored into the lvalue and returned; as in C, assignments are a special case of expressions. The lvalue can be a variable (if no such variable existed, it is created, otherwise the previous value is overwritten), but also a file or a pipe, with similar semantics:

“filename” and “|command”

Any sequence of characters between double quotes. It is assumed to be a pipe if the first character is a `|', and a file otherwise. If they appear in the right-hand side of an expression, the file (or the output of the command) is read and parsed, and some value is returned. If they appear as the left-hand side of an assignment, the value of the right-hand side will be copied into the file or the pipe.

function(expr, expr...)

A function can be any C identifier; the arguments are evaluated, and are passed as command-line arguments to the external program called `fn_function' (it must be in your path). The output of the program is then read and parsed, and some value is returned. For instance, `foo(-n,x+1)' is equivalent to

    "|fn_foo '-n' '+1+x'"

in an expression. The program fn_foo can be anything, but you should be extremely careful if it is a shell script; for instance, echo "$1" will not give `-n' (as you might expect) in this example.

expr bop expr

Where bop can be any of `+' (addition), `-' (substraction), `*' or `.' (multiplication), `/' (division), `&' (greatest common divisor). The result of the operation is returned.

uop expr

Where uop can be `+' or `-'.

(expr, subst, subst...)

Applies a list of substitutions to expr. Each substitution has the form `unary to expr', where unary is any expression which evaluates to a unary monomial, and to is either `->' for a simple substitution, or `>>' for a repeated substitution (we apply it until we reach a fixed point); for instance `x^2.y -> (x-z)*2' is a valid substitution. The list of substitutions can be empty, in this case you simply get the value of the parenthesised expression.

Another kind of substitution, which only applies to tensors, is `tensorid1 => tensorid2'; it maps the first tensorid to the second one, maybe causing a contraction. If the first tensorid doesn't appear in expr, an error is returned.

expr^number

Raises the expression to a non-negative power. Feature: 0^0 returns one.

expr:elit

Differentiates expr with respect to elit, where elit is any expression which evaluates to a literal.

~elit(expr,expr)

Returns the resultant of the two polynomials with respect to elit; this can be used to eliminate a literal between two equations.

| expr, expr... |

The number of expressions between the bars must be a perfect square. If there are n^2 of them, samuel will consider them as the elements of a n*n matrix, and will return the determinant of this matrix.

expr ~~ (expr,elit)

Computes the remainder of the first expression modulo the second one, with respect to some literal. For now, this construction is only syntactic sugar for modulo(E1,E2,L) so it will fail if fn_modulo is not in your path.

Precedence of Operators

All operators are left-associative, except the assignment which is right-associative. Here is the list of priorities, from the highest to the lowest:

(1)

power `^' and derivation `:';

(2)

unary plus and minus;

(3)

multiplication and division;

(4)

binary plus and minus;

(5)

greatest common divisor `&';

(6)

modulo `~~'

(7)

assignment `='.

Interpolation of subscripted identifiers

Samuel accepts three kinds of identifiers:

(1)

C identifiers, i.e., any sequence of letters, digits and underscores, the first character being a non-digit.

(2)

Subscripted C identifiers; as above, followed by a comma-separated list of integers between brackets, like `foo_bar[-1,3]'.

(3)

Bracketed identifiers, a la FORM: any sequence of characters between brackets; opening and closing brackets must match, like `[foo[bar]+2]'.

Without the -i and -e options, subscripted C identifiers are handed to the induce(1) program. They will be replaced ("interpolated") in the input stream by the appropriate pipe. For instance, the following substitution would take place:

    foo[-1,3] --> "|induce -q foo[-1,3]"

Note that it only affects "naked" identifiers, i.e. not preceded by a backslash or a question mark (nor in the LHS of an assignment); still, this behaviour can be undesirable; you can disable it with the -i option.

Interpolation is also disabled in "explicit-variables" mode, i.e., when the -e option is set. You don't want this kind of magic in batch mode, for obvious reliability reasons.

Variables and Literals

It is perfectly possible for a variable and a literal to have the same name, so there must be some way to distinguish them. You can prepend a \ or a ? before every identifier to remove ambiguity, but usually it's not needed; the naked identifier will be "correctly" interpreted. This interpretation depends on the mode samuel is running in:

(1)

Normal mode. If the identifier contains subscripts, it will be interpolated. Otherwise, if there's a variable with this name, its value will be returned. Otherwise, it's assumed to be a literal.

(2)

Normal mode without interpolation. This is what you get with the -i option. Like (1) but with interpolation disabled.

(3)

Explicit-variables mode. Activated by the -e option. A naked identifier will always represent a literal. This is the only way to ensure that samuel will run in a reliable and deterministic way with expressions containing arbitrary literals. Without this precaution, there might be name clashes between literals and temporary variables.

OPTIONS

-b, --batch

Batch mode; this is equivalent to -eq.

-e, --explicit-variables

Enter "explicit-variables" mode. See above. In some sense, this option implies -i.

-i, --no-induce

Disable interpolation of subscripted names.

-q, --quiet

Quiet mode; this is the default mode when the standard output is not a tty. Only error messages will be written to stderr.

-v, --verbose

Verbose mode; this is the default mode when the standard output is a tty.

--help, --usage

Prints a small usage summary on standard output, and exits successfully.

--version, --copyright

Prints the samuel version string, a copyright message, and exits successfully. This manpage documents version 1.10. A version string ending with "r" means that samuel has been compiled with readline(3) support.

--post, --post-processor program

Instead of displaying expressions on standard output, post-process them through program, where program is any string which means something for the shell; it will be executed for each displayed expression. You can for instance use the colorize(1) utility to reformat and colorize the output.

-Q, --rationals

Equivalent to -m0 (see below). With this option, samuel works on polynomials with rational coefficients. This mode is the default when the environment variable MODULUS is not set.

-Z, --integers

Equivalent to -m1 (see below). If this option is specified, samuel will use polynomials with integer coefficients. This modifies the semantics of some operations: divisions will truncate their results (towards zero), and gcd's will be computed over Z[X1...Xn] instead of Q[X1...Xn], so the results can differ by a multiplicative constant. In particular, the gcd of two constant polynomials will be the gcd of the constants (as one might expect), whereas it would be 1 over the rationals.

-m, --modulo number

If number is an integer greater than one, all calculations will be made modulo this integer, i.e., polynomials have their coefficients in Z/numberZ. The special values 0 and 1 mean that the base ring is Q or Z, respectively. The modulus cannot exceed 2^32-1; greater moduli will be (silently) clamped to this value. See also the BUGS section.

-c, --condition X,A0,A1...An

Take the coefficients in K[X]/(P) where P is the polynomial with integer coefficients A0...An. An element of the splitting field like 3+X-X^2 will be written as (3,1,-1). The unfortunate thing is that samuel can not parse this notation. Also, you can't have more than one condition.

-r, --rational-functions

It does not work yet. Don't use.

-t, --tensors

With this option, samuel will use tensors with polynomial coordinates instead of polynomials. This option is orthogonal to the previous ones, which simply select the type of the coefficients of polynomials.

-n, --nice adjust

Adds adjust to the niceness of the process, as symbolic calculations can be very CPU-intensive.

--sparse

Use polynomials of type ST_POLY; this can be more efficient when the set of literals is very sparse.

--dense

Use polynomials of type ST_APOLY. This is the default, and usually more efficient than ST_POLY. It assumes, however, that the set of literals in each polynomial is reasonably dense.

ENVIRONMENT

The following variables are relevant to samuel:

MODULUS

Contains the default modulus; if this variable doesn't exist, the default modulus is 0. This variable is set by samuel and inherited by all its subprocesses. Therefore, it is possible to call samuel recursively and have the same modulus in all its invocations.

LITERALS

This variable, if present, can contain either dense or sparse (other values are ignored) and overrides the builtin preference (dense) between dense and sparse polynomials. It will be overriden by the corresponding command-line options. Here again, this variable is set by samuel and inherited by all its subprocesses.

SPID

Contains the process id of the latest invocation of samuel(1) or induce(1). Can be used to create temporary files which are private to this invocation.

PATH

This path is used to spawn induce(1), commands in pipes, and external functions.

EXIT CODE

samuel returns 2 on usage errors, 1 if the input contained syntax errors, and 0 otherwise. Run-time errors are not reported.

BUGS

The lexer is too laxist about identifiers; it shouldn't allow bracketed literals containing whitespace or nested brackets. If you save an expression containing such an identifier into a file, samuel will be unable to reread this file.

Divisions in Z/nZ, with n a composite number, are almost guaranteed to return rubbish. Also, samuel should issue a warning (or more) when the modulus is out of range, instead of clamping it silently.

There should be a way to trap SIGINT so that you could kill a child process with ^C without killing samuel at the same time. For now, you have to switch to another tty (or suspend samuel) and kill the subprocess.

SEE ALSO

colorize(1), induce(1), readline(3), saml(3)

AUTHOR

Thierry Bousch ([email protected])