]>
To move beyond functions defined in one line, we introduce in this section functions that are defined piece-by-piece. That is, we say ``use this definition when the argument is such-and-such and use this other definition when the argument is that-and-that.''
There are many other ways to define a factorial function for nonnegative integers. You might function:piece-wise definition say piece-wise function definition factorial of is , otherwise factorial of is times factorial of . Here is one way to do this in Axiom.
Here is the value for .
Here is the value for . The vertical bar ``|'' means ``such that''. such that
What is the value for ?
What is the value for ?
Now for a second definition. Here is the value for .
Give an error message if .
Here is the value otherwise.
What is the value for ?
What is the value for ?
To see the current piece-wise definition of a function, use )display value.
In general a piece-wise definition of a function consists of two or more parts. Each part gives a ``piece'' of the entire definition. Axiom collects the pieces of a function as you enter them. When you ask for a value of the function, it then ``glues'' the pieces together to form a function.
The two piece-wise definitions for the factorial function are examples of recursive functions, that is, functions that are defined in terms of themselves. Here is an interesting doubly-recursive function. This function returns the value for all positive integer arguments.
Here is the first of two pieces.
And the general case.
Compute , the infinite stream of values of .
What is the value at ?
What is the Axiom's definition of ?
Here are the details about how Axiom creates a function from its pieces. Axiom converts the -th piece of a function definition into a conditional expression of the form: if then . If any new piece has a that is identical (after all variables are uniformly named) to an earlier , the earlier piece is removed. Otherwise, the new piece is always added at the end.
If there are pieces to a function definition for , the function
defined is:
if then else
. . .
if then else
error "You did not define f for argument <arg>."
You can give definitions of any number of mutually recursive function definitions, piece-wise or otherwise. No computation is done until you ask for a value. When you do ask for a value, all the relevant definitions are gathered, analyzed, and translated into separate functions and compiled.
Let's recall the definition of eleven from the previous section.
A similar doubly-recursive function below produces for all negative positive integers. If you haven't worked out why or how eleven works, the structure of this definition gives a clue.
This definition we write as a block.
Define to be the sum of plus and minus ``eleven'' functions divided by . Since , we define to be .
And the general term.
What are the first ten values of ?
Axiom can create infinite streams in the positive direction (for example, for index values ) or negative direction (for example, for ). Here we would like a stream of values of that is infinite in both directions. The function below returns the -th term of the infinite stream Its definition has three pieces.
Define the initial term.
The even numbered terms are the for positive . We use ``quo'' rather than ``/'' since we want the result to be an integer.
Finally, the odd numbered terms are the for negative . In piece-wise definitions, you can use different variables to define different pieces. Axiom will not get confused.
Look at the definition of . In the first piece, the variable was used; in the second piece, . Axiom always uses your last variable to display your definitions back to you.
Create a series of values of applied to alternating positive and negative arguments.
Evidently for all . Check it at .
We have already seen some examples of function:predicate predicates predicate:in function definition (ugUserPieceBasic ). Predicates are Boolean-valued expressions and Axiom uses them for filtering collections (see ugLangIts ) and for placing constraints on function arguments. In this section we discuss their latter usage.
The simplest use of a predicate is one you don't see at all.
Here is a longer way to give the ``opposite definition.''
Try it out.
Explicit predicates tell Axiom that the given function definition piece is to be applied if the predicate evaluates to true for the arguments to the function. You can use such ``constant'' arguments for integers, function:constant argument strings, and quoted symbols. constant function argument The Boolean values true and false can also be used if qualified with ``'' or ``'' and Boolean. The following are all valid function definition fragments using constant arguments.
If a function has more than one argument, each argument can have its own predicate. However, if a predicate involves two or more arguments, it must be given after all the arguments mentioned in the predicate have been given. You are always safe to give a single predicate at the end of the argument list.
A function involving predicates on two arguments.
This is incorrect as it gives a predicate on before the argument is given.
It is always correct to write the predicate at the end.
Here is the rest of the definition.
Try it out.