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.