## `misc::maprec` -- map a function to subexpressions of an expression

#### Introduction

`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.

#### Call(s)

`misc::maprec(ex, selector=funci)`
`misc::maprec(ex, selector=funci, PreMap)`
`misc::maprec(ex, selector=funci, PostMap)`
`misc::maprec(ex, selector=funci, PreMap, PostMap)`
`misc::maprec(ex <, selector=funci... > <, PreMap> <, PostMap>)`

#### Parameters

`ex` | - | any MuPAD object
`selector` | - | any MuPAD object
`funci` | - | any MuPAD object

#### Options

`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`.

#### Returns

`misc::maprec` may return any MuPAD object.

#### Related Functions

`map`, `mapcoeffs`, `misc::breakmap`

#### Details

- `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 t1, ...,tn. Here a subexpression `s` of `ex` is selected if type(s1) is one of the types t1, ...,tn. 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`.
- The options `PreMap` and `PostMap` can also be given together; in this case, operands of not selected expressions are visited for a second time.
- 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.

- Only subexpressions of domain type `DOM_ARRAY`, `DOM_EXPR`, `DOM_LIST`, `DOM_SET`, and `DOM_TABLE` are mapped recursively. 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, 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 the method `"maprec"`, then this method is called with the subexpression and the other arguments of the call.

  The subexpression is replaced by the result, but `misc::maprec` is not mapped to its operands; such recursive mapping must be done by the domain method if desired.

- The operators of expressions (`op(expression, 0)`) are also mapped recursively like all the other operands.

### Overloadable:

`ex`

#### Example 1

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)

                                      a + 20

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)

                                      a + 10

#### Example 2

Now we demonstrate the usage of the options `PreMap` and `PostMap`.

    >> misc::maprec(hold(3+4), {DOM_INT} = 10)

                                        10

Here `misc::maprec` was used without an option, this means the default option `PreMap` was used. So why did we get a result of 10 instead of the (possibly expected) 20? Because pre-mapping is used by default, `misc::maprec` first applies itself to the integers 3 and 4. They are replaced by the value 10 each such that we get an intermediate result of 20. After that, `misc::maprec` tests the selection criterion for the expression as a whole. This one equals the integer 20 by now, hence it is replaced by 10. Instead, when using the `PostMap` option we get:

    >> misc::maprec(hold(3+4), {DOM_INT} = 10, PostMap )

                                        20

Here, the expression `3+4` was tested at first -- it is not an integer. Then, `misc::maprec` was applied to the operands, and both were replaced by 10.

#### Example 3

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)

                                        133

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 call above computes the sum of all composite numbers between 1 and 20..

#### Changes

- used to be called `maprec`

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000