Defining simplification rules
Yacas has a simple and easy to use pattern matching scheme
for simplifying expressions. Examples can be found in for instance
the files "standard", "stdfuncs", "deriv" and "solve" that
come with the Yacas distribution.
As an example, consider the following lines:
IsPositiveInteger(_n) <-- IsInteger(n) And n>0;
10 # f(0) <-- 1;
20 # f(n_IsPositiveInteger) <-- n*f(n-1);
|
IsPositiveInteger is actually defined in the standard
distribution, so it is not necessary. The other two lines obviously
define a factorial function n*(n-1)*...*1.
The <-- assigns a rule to be applied to a specific
function. The _n in rule specifies that any object
can be matched, and the local variable n is assigned to it.
The 0 should match perfectly. n_IsPositiveInteger is
the same as _n with the proviso that IsPositiveInteger(n) should return True
otherwise the pattern is not matched. Some rules have a number followed
by a # in front of them. This number defines an ordering
for the pattern matching rules. 0 is the lowest allowed
value, and will be tried first. Multiple rules can have the same number.
This just means that it doesn't matter what order these patterns are
tried in. If no number is supplied, 0 is assumed.
Additional predicates can be specified too. IsPositiveInteger could also have been defined as:
10 # IsPositiveInteger(n_IsInteger)_(n>0) <-- True;
20 # IsPositiveInteger(_n) <-- False;
|
Where the first rule specifies that if n is an integer, and greater than
zero, the predicate is true, and the second rule states that the
predicate is false otherwise. The (n>0) clause is added
after the pattern, and implies that this predicate should return true also,
if this pattern is to match. This is useful for defining predicates involving
more than one argument.
Some other examples:
_x + 0 <-- x;
_x - _x <-- 0;
ArcSin(Sin(_x)) <-- x;
|
Yacas will first try to match the pattern, like a template. It will then
assign the relevant variables, and try the predicates as stated in the
pattern. The post-predicate (defined after the pattern) is tried after
all these matched.
There is a slightly more complex way of defining rules, using the RuleBase
and Rule functions, but these are generally not necessary.