The type-specifier part of a declaration (that is, the second prompt in the s d command) can be a type symbol, an interval, or a vector consisting of zero or more type symbols followed by zero or more intervals or numbers that represent the set of possible values for the variable.
[ [ a, [1, 2, 3, 4, 5] ] [ b, [1 .. 5] ] [ c, [int, 1 .. 5] ] ]
Here a
is declared to contain one of the five integers shown;
b
is any number in the interval from 1 to 5 (any real number
since we haven't specified), and c
is any integer in that
interval. Thus the declarations for a
and c
are
nearly equivalent (see below).
The type-specifier can be the empty vector `[]' to say that
nothing is known about a given variable's value. This is the same
as not declaring the variable at all except that it overrides any
All
declaration which would otherwise apply.
The initial value of Decls
is the empty vector `[]'.
If Decls
has no stored value or if the value stored in it
is not valid, it is ignored and there are no declarations as far
as Calc is concerned. (The s d command will replace such a
malformed value with a fresh empty matrix, `[]', before recording
the new declaration.) Unrecognized type symbols are ignored.
The following type symbols describe what sorts of numbers will be stored in a variable:
int
numint
frac
rat
float
real
pos
nonneg
number
Calc uses this information to determine when certain simplifications
of formulas are safe. For example, `(x^y)^z' cannot be
simplified to `x^(y z)' in general; for example,
`((-3)^2)^1:2' is 3, but `(-3)^(2*1:2) = (-3)^1' is -3.
However, this simplification is safe if z
is known
to be an integer, or if x
is known to be a nonnegative
real number. If you have given declarations that allow Calc to
deduce either of these facts, Calc will perform this simplification
of the formula.
Calc can apply a certain amount of logic when using declarations.
For example, `(x^y)^(2n+1)' will be simplified if n
has been declared int
; Calc knows that an integer times an
integer, plus an integer, must always be an integer. (In fact,
Calc would simplify `(-x)^(2n+1)' to `-(x^(2n+1))' since
it is able to determine that `2n+1' must be an odd integer.)
Similarly, `(abs(x)^y)^z' will be simplified to `abs(x)^(y z)'
because Calc knows that the abs
function always returns a
nonnegative real. If you had a myabs
function that also had
this property, you could get Calc to recognize it by adding the row
`[myabs(), nonneg]' to the Decls
matrix.
One instance of this simplification is `sqrt(x^2)' (since the
sqrt
function is effectively a one-half power). Normally
Calc leaves this formula alone. After the command
s d x RET real RET, however, it can simplify the formula to
`abs(x)'. And after s d x RET nonneg RET, Calc can
simplify this formula all the way to `x'.
If there are any intervals or real numbers in the type specifier,
they comprise the set of possible values that the variable or
function being declared can have. In particular, the type symbol
real
is effectively the same as the range `[-inf .. inf]'
(note that infinity is included in the range of possible values);
pos
is the same as `(0 .. inf]', and nonneg
is
the same as `[0 .. inf]'. Saying `[real, [-5 .. 5]]' is
redundant because the fact that the variable is real can be
deduced just from the interval, but `[int, [-5 .. 5]]' and
`[rat, [-5 .. 5]]' are useful combinations.
Note that the vector of intervals or numbers is in the same format used by Calc's set-manipulation commands. See section Set Operations using Vectors.
The type specifier `[1, 2, 3]' is equivalent to `[numint, 1, 2, 3]', not to `[int, 1, 2, 3]'. In other words, the range of possible values means only that the variable's value must be numerically equal to a number in that range, but not that it must be equal in type as well. Calc's set operations act the same way; `in(2, [1., 2., 3.])' and `in(1.5, [1:2, 3:2, 5:2])' both report "true."
If you use a conflicting combination of type specifiers, the results are unpredictable. An example is `[pos, [0 .. 5]]', where the interval does not lie in the range described by the type symbol.
"Real" declarations mostly affect simplifications involving powers like the one described above. Another case where they are used is in the a P command which returns a list of all roots of a polynomial; if the variable has been declared real, only the real roots (if any) will be included in the list.
"Integer" declarations are used for simplifications which are valid only when certain values are integers (such as `(x^y)^z' shown above).
Another command that makes use of declarations is a s, when
simplifying equations and inequalities. It will cancel x
from both sides of `a x = b x' only if it is sure x
is non-zero, say, because it has a pos
declaration.
To declare specifically that x
is real and non-zero,
use `[[-inf .. 0), (0 .. inf]]'. (There is no way in the
current notation to say that x
is nonzero but not necessarily
real.) The a e command does "unsafe" simplifications,
including cancelling `x' from the equation when `x' is
not known to be nonzero.
Another set of type symbols distinguish between scalars and vectors.
scalar
vector
matrix
These type symbols can be combined with the other type symbols described above; `[int, matrix]' describes an object which is a matrix of integers.
Scalar/vector declarations are used to determine whether certain
algebraic operations are safe. For example, `[a, b, c] + x'
is normally not simplified to `[a + x, b + x, c + x]', but
it will be if x
has been declared scalar
. On the
other hand, multiplication is usually assumed to be commutative,
but the terms in `x y' will never be exchanged if both x
and y
are known to be vectors or matrices. (Calc currently
never distinguishes between vector
and matrix
declarations.)
See section Matrix and Scalar Modes, for a discussion of "matrix mode" and "scalar mode," which are similar to declaring `[All, matrix]' or `[All, scalar]' but much more convenient.
One more type symbol that is recognized is used with the H a d command for taking total derivatives of a formula. See section Calculus.
const
Calc does not check the declarations for a variable when you store
a value in it. However, storing -3.5 in a variable that has
been declared pos
, int
, or matrix
may have
unexpected effects; Calc may evaluate `sqrt(x^2)' to 3.5
if it substitutes the value first, or to -3.5 if x
was declared pos
and the formula `sqrt(x^2)' is
simplified to `x' before the value is substituted. Before
using a variable for a new purpose, it is best to use s d
or s D to check to make sure you don't still have an old
declaration for the variable that will conflict with its new meaning.