Documentation |
Map a function to subexpressions of an expression
This functionality does not run in MATLAB.
misc::maprec(ex, selector = funci, …, <PreMap | PostMap>, <NoOperators>, <Unsimplified>)
misc::maprec(ex, selector=funci) maps the function funci to all subexpressions of the expression ex that satisfy a given criterion (defined by selector) and replaces each selected subexpression s by funci(s).
Several different functions may be mapped to subexpressions satisfying different selection criteria.
misc::maprec(ex, selector_{1} = funci_{1}, …, selector_{n} = funci_{n}) does two steps: it tests whether ex meets a selection criterion defined by some selector selector_k (and, if yes, replaces ex by funci_k(ex)); and it applies itself recursively to all operands of ex. The order of these steps is determined by the options PreMap and PostMap.
Selectors are applied from left to right; if the expression meets some selection criterion, no further selectors are tried.
selector can have two forms. It can be a set {t_{1}, …, t_{n}}. Here a subexpression s of ex is selected if type(s1) is one of the types t_{1}, …, t_{n}. If it is not a set, a subexpression s of ex is selected if p(s) returns TRUE. As every MuPAD^{®} object may be applied as a function to s, p may be of any type in the latter case.
In order not to select a subexpression, the selector need not return FALSE; it suffices that it does not return TRUE.
If neither the option PreMap nor the option PostMap is given, then PreMap is used.
Use a misc::breakmap command inside funci in order to stop the recursive mapping. See the help page of misc::breakmap for an example.
Note: Only subexpressions of domain type DOM_ARRAY, DOM_EXPR, DOM_LIST, DOM_SET, and DOM_TABLE are mapped recursively, as well as domain elements of a domain T for which a slot T::enableMaprec exists and equals TRUE; a slot T::map working properly must then exist, too. To subexpressions of other types, selector is applied, but misc::maprec is not mapped to their operands. (This is to avoid unwanted substitutions.) If you want to recurse on them, either add an enableMaprec-slot, or use a selector that selects such subexpressions, and make funci initiate another recursive mapping. |
misc::maprec is overloadable. If the domain of a subexpression has a method "maprec", then this method is called with the subexpression and the other arguments of the call.
In the following example every integer of the given expression a+3+4 is substituted by the value 10. Since 10(n) returns 10 for every integer n, it suffices to write 10 instead of n -> 10 here.
misc::maprec(hold(a+3+4), {DOM_INT} = 10)
In the example above, we used hold to suppress the evaluation of the expression because otherwise a+3+4 is evaluated to a+7 and we get the result:
misc::maprec(a+3+4, {DOM_INT} = 10)
The simplification of the resulting 10 + 10 to 20 can be avoided by using the option Unsimplified:
misc::maprec(hold(a+3+4), {DOM_INT} = 10, Unsimplified)
Now we give an example where the selector is a function. We want to eleminate all the prime numbers from an expression.
misc::maprec(hold(_plus)(i $ i=1..20), isprime= null(), PostMap)
Here isprime returns TRUE for every prime number between 1 and 20. Every prime number between 1 and 20 is replaced by null() (since null()(p) gives null()) which means the above call computes the sum of all non-prime numbers between 1 and 20.
Normally, misc::maprec recurses also into the operators of subexpressions. This may be unwanted in many cases:
misc::maprec(a+b, {DOM_IDENT}= (x -> x.1))
We just wanted to replace the summands, but not the operator. Using the option NoOperators helps:
misc::maprec(a+b, {DOM_IDENT}= (x -> x.1), NoOperators)
PreMap |
For each subexpressions s of ex, the selector is applied to it after visiting all of its subexpressions; s may have changed at that time due to substitutions in the subexpressions. |
PostMap |
For each subexpressions s of ex, the selector is applied to it before visiting its subexpressions. If s is selected by selector, it is replaced by funci(s), and misc::maprec is not recursively applied to the operands of funci(s); otherwise, misc::maprec is recursively applied to the operands of s. |
NoOperators |
The selector is not applied to the operator of ex. |
Unsimplified |
The resulting expressions are not further simplified. |