The type function can be used to code a routine that does different things depending on the type of the input. For example, the DIFF routine below differentiates expressions which are polynomials in the given variable .
DIFF := proc(a,x) local u,v; if not type(a,algebraic) then ERROR(`1st argument must a formula`) fi; if not type(x,name) then ERROR(`2nd argument must be a name`) fi; if type(a,numeric) then 0 elif type(a,name) then if a = x then 1 else 0 fi elif type(a,`+`) then map( DIFF, a, x ) elif type(a,`*`) then u := op(1,a); v := a/u; DIFF(u,x)*v + DIFF(v,x)*u elif type(a,anything^integer) then u := op(1,a); v := op(2,a); v*DIFF(u,x)*u^(v-1) else ERROR(`don't know how to differentiate`,a) fi end;
Types are used in the DIFF procedure for two different purposes. The first usage is for type checking. The inputs must be an algebraic expression or a formula, and a name for the differentiation variable. The second usage is to examine the type of the input - is it a sum or product - and decide what differentiation rule is to be used. The DIFF example shows the use of the map function, a very useful function, which we will now explain. It has the following syntax
map( , , , ..., )
The meaning is to apply the function to the operands of the expression passing the additional arguments , ..., to . In our DIFF procedure, there is one additional argument x. Often, there are no additional arguments. Formally, this is equivalent to computing the sequence
seq( f( op(1,a), x1, ..., xn ), i=1..nops(a) );
and then creating from this sequence a value of the same type as the type of . Here are some examples
> p := x^3+2*x+1; 3 p := x + 2 x + 1 > map( F, p ); 3 F(x ) + F(2 x) + F(1) > map( x -> x^2, p ); 6 2 x + 4 x + 1 > map( degree, p, x ); 4
The DIFF function also shows the use of a structured type. The types anything, name, `+` and `*` are simple types. The type anything^integer is a structured type. It means that the value must be a power, and the base can be anything, i.e. any type, but the exponent must be an integer. It is equivalent to writing
if type(a,`^`) and type(op(2,a),integer) then
Structured types allow you to replace long type tests with concise tests. Let us illustrate another common case. Many routines take a set or list of names or equations as arguments. For example, the solve command allows one to solve a set of equations for a set of unknowns. For example
> solve( {x+y=2, x-y=3}, {x,y} ); {y = -1/2, x = 5/2}A set of zero or more equations can be tested with the type: set(equation), and as set of zero or more unknowns with the type set(name). But the solve command also allows a set of algebraic formulae which are implicitly equated to zero, i.e. the example above could have been input this way
> solve( {x+y-2, x-y-3}, {x,y} ); {y = -1/2, x = 5/2}
Hence the type should of the first argument should be either a set of equations, or a set of algebraic expressions, i.e. the type {set(algebraic),set(equation)}. Notice that this is not the same as set({algebraic,equation}). Why?
Further information about the various different types can be obtained from the on-line help system under ?type .