Sponsored links: Algebra eBooks

Help Index



























The Maxima on-line user's manual

Algebra Calculator


Tellsimpafter Calculator


Function: tellsimpafter (<pattern>, <replacement>) Defines a simplification rule which the Maxima simplifier applies after built-in simplification rules. <pattern> is an expression, comprising pattern variables (declared by matchdeclare) and other atoms and operators, considered literals for the purpose of pattern matching. <replacement> is substituted for an actual expression which matches <pattern>; pattern variables in <replacement> are assigned the values matched in the actual expression.

posintp(n):=is(integerp(n) and n>0);

<pattern> may be any nonatomic expression in which the main operator is not a pattern variable; the simplification rule is associated with the main operator. The names of functions (with one exception, described below), lists, and arrays may appear in <pattern> as the main operator only as literals (not pattern variables); this rules out expressions such as aa(x) and bb[y] as patterns, if aa and bb are pattern variables. Names of functions, lists, and arrays which are pattern variables may appear as operators other than the main operator in <pattern>.

There is one exception to the above rule concerning names of functions. The name of a subscripted function in an expression such as aa[x](y) may be a pattern variable, because the main operator is not aa but rather the Lisp atom mqapply. This is a consequence of the representation of expressions involving subscripted functions.

Simplification rules are applied after evaluation (if not suppressed through quotation or the flag noeval). Rules established by tellsimpafter are applied in the order they were defined, and after any built-in rules. Rules are applied bottom-up, that is, applied first to subexpressions before application to the whole expression. It may be necessary to repeatedly simplify a result (for example, via the quote-quote operator or the flag infeval) to ensure that all rules are applied.

Pattern variables are treated as local variables in simplification rules. Once a rule is defined, the value of a pattern variable does not affect the rule, and is not affected by the rule. An assignment to a pattern variable which results from a successful rule match does not affect the current assignment (or lack of it) of the pattern variable. However, as with all atoms in Maxima, the properties of pattern variables (as declared by put and related functions) are global.

The rule constructed by tellsimpafter is named after the main operator of <pattern>. Rules for built-in operators, and user-defined operators defined by infix, prefix, postfix, matchfix, and nofix, have names which are Lisp identifiers. Rules for other functions have names which are Maxima identifiers.

The treatment of noun and verb forms is slightly confused. If a rule is defined for a noun (or verb) form and a rule for the corresponding verb (or noun) form already exists, the newly-defined rule applies to both forms (noun and verb). If a rule for the corresponding verb (or noun) form does not exist, the newly-defined rule applies only to the noun (or verb) form.

The rule constructed by tellsimpafter is an ordinary Lisp function. If the name of the rule is $foorule1, the construct :lisp (trace $foorule1) traces the function, and :lisp (symbol-function $foorule1 displays its definition.

tellsimpafter quotes its arguments. tellsimpafter returns the list of rules for the main operator of <pattern>, including the newly established rule.

See also matchdeclare, defmatch, defrule, tellsimp, let, kill, remrule, and clear_rules.


<pattern> may be any nonatomic expression in which the main operator is not a pattern variable.

          (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
          (%i2) tellsimpafter (sin (ll), map (sin, ll));
          (%o2)                 [sinrule1, simp-%sin]
          (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
                              1  sqrt(2)  sqrt(3)
          (%o3)              [-, -------, -------, 1, 0]
                              2     2        2
          (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
          (%o4)                  [^rule1, simpexpt]
          (%i5) [a, b, c]^[1, 2, 3];
                                          2   3
          (%o5)                      [a, b , c ]
          (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
          (%o6)                   [foorule1, false]
          (%i7) foo (bar (u - v));
          (%o7)                    bar(foo(u - v))

Rules are applied in the order they were defined. If two rules can match an expression, the rule which was defined first is applied.

          (%i1) matchdeclare (aa, integerp);
          (%o1)                         done
          (%i2) tellsimpafter (foo (aa), bar_1 (aa));
          (%o2)                   [foorule1, false]
          (%i3) tellsimpafter (foo (aa), bar_2 (aa));
          (%o3)              [foorule2, foorule1, false]
          (%i4) foo (42);
          (%o4)                       bar_1(42)

Pattern variables are treated as local variables in simplification rules. (Compare to defmatch, which treats pattern variables as global variables.)

          (%i1) matchdeclare (aa, integerp, bb, atom);
          (%o1)                         done
          (%i2) tellsimpafter (foo(aa, bb), bar(aa=aa, bb=bb));
          (%o2)                   [foorule1, false]
          (%i3) bb: 12345;
          (%o3)                         12345
          (%i4) foo (42, %e);
          (%o4)                 bar(aa = 42, bb = %e)
          (%i5) bb;
          (%o5)                         12345

As with all atoms, properties of pattern variables are global even though values are local. In this example, an assignment property is declared via define_variable. This is a property of the atom bb throughout Maxima.

          (%i1) matchdeclare (aa, integerp, bb, atom);
          (%o1)                         done
          (%i2) tellsimpafter (foo(aa, bb), bar(aa=aa, bb=bb));
          (%o2)                   [foorule1, false]
          (%i3) foo (42, %e);
          (%o3)                 bar(aa = 42, bb = %e)
          (%i4) define_variable (bb, true, boolean);
          (%o4)                         true
          (%i5) foo (42, %e);
          Error: bb was declared mode boolean, has value: %e
           -- an error.  Quitting.  To debug this try debugmode(true);

Rules are named after main operators. Names of rules for built-in and user-defined operators are Lisp identifiers, while names for other functions are Maxima identifiers.

          (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
          (%o1)                   [foorule1, false]
          (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
          (%o2)              [foorule2, foorule1, false]
          (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
          (%o3)         [foorule3, foorule2, foorule1, false]
          (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
          (%o4)                   [+rule1, simplus]
          (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
          (%o5)                  [*rule1, simptimes]
          (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
          (%o6)                  [^rule1, simpexpt]
          (%i7) rules;
          (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
          (%i8) foorule_name: first (%o1);
          (%o8)                       foorule1
          (%i9) plusrule_name: first (%o4);
          (%o9)                        +rule1
          (%i10) remrule (foo, foorule1);
          (%o10)                         foo
          (%i11) remrule ("^", ?\^rule1);
          (%o11)                          ^
          (%i12) rules;
          (%o12)        [foorule2, foorule3, +rule1, *rule1]

A worked example: anticommutative multiplication.

          (%i1) gt (i, j) := integerp(j) and i < j;
          (%o1)           gt(i, j) := integerp(j) and i < j
          (%i2) matchdeclare (i, integerp, j, gt(i));
          (%o2)                         done
          (%i3) tellsimpafter (s[i]^^2, 1);
          (%o3)                 [^^rule1, simpncexpt]
          (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
          (%o4)                   [.rule1, simpnct]
          (%i5) s[1] . (s[1] + s[2]);
          (%o5)                    s  . (s  + s )
                                    1     2    1
          (%i6) expand (%);
          (%o6)                      1 - s  . s
                                          2    1
          (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
          (%o7) 100 (s  + s  + s  + s  + s  + s  + s  + s  + s  + s )
                      9    8    7    6    5    4    3    2    1    0

(%o1)                                true

Tellsimpafter Example

Related Examples