## Documentation Center |

Create an inactive copy of a function

This functionality does not run in MATLAB.

`freeze(``f`)

`freeze(f)` creates an inactive copy of the
function `f`.

`ff := freeze(f)` returns a function that is
an "inactive" copy of the argument `f`.
This means:

`ff`only evaluates its arguments, but does not compute anything else,`ff`is printed in the same way as`f`,symbolic

`ff`calls have the same type as symbolic`f`calls,if

`f`is a function environment, then`ff`has all the slots of`f`.

Note that `ff` evaluates its incoming
parameters even if the function `f` has the procedure option `hold`.

`freeze` can be used when many operations with `f` are
to be performed that require `f` only in its symbolic
form, but `f` need not be executed.

Neither `eval` nor `level` can
enforce the evaluation of an inactive function. See Example 2.

We create an inactive form of the function environment `int`:

_int := freeze(int): F := _int(x*exp(x^2), x = 0..1)

The inactive form of `int` keeps every information
that is known about the function `int`, e.g., the
output, the type, and the `"float"` slot for floating-point
evaluation:

F, type(F), float(F)

The original function environment `int` is not modified by `freeze`:

int(x*exp(x^2), x = 0..1)

Use `unfreeze` to reactivate the inactive function `_int` and
evaluate the result:

unfreeze(F), unfreeze(F + 1/2)

We demonstrate the difference between `hold` and `freeze`. The
result of the command `S := hold(sum)(...)` does
not contain an inactive version of `sum`, but the unevaluated identifier`sum`:

S := hold(sum)(1/n^2, n = 1..infinity)

The next time `S` is evaluated, the identifier `sum` is
replaced by its value, the function environment`sum`, and the procedure
computing the value of the infinite sum is invoked:

S

In contrast, evaluation of the result of `freeze` does
not lead to an evaluation of the inactive function:

S := freeze(sum)(1/n^2, n = 1..infinity)

S

An inactive function does not even react to `eval`:

eval(S)

The only way to undo a `freeze` is to use `unfreeze`,
which reactivates the inactive function in `S` and
then evaluates the result:

unfreeze(S)

Note that `freeze(f)` does not change the object `f` but
returns a copy of `f` in an inactive form. This means
that computations with the inactive version of `f` may
contain the original function `f`.

For example, if we create an inactive version of the sine function:

Sin := freeze(sin):

and expand the term `Sin(x+y)`, then the result
is expressed in terms of the (original) sine function `sin`:

expand(Sin(x + y))

The function `unfreeze` uses `misc::maprec` to
operate recursively along the structure of `object`.
For example, if `object` is an array containing inactive
functions, such as:

a := array(1..2, [freeze(int)(sin(x), x = 0..2*PI), freeze(sum)(k^2, k = 1..n)] )

then `unfreeze(a)` operates on the operands
of `a`:

unfreeze(a)

This means that for library domains, the effect of `unfreeze` is
specified by the method `"maprec"`. If the domain
does not implement this method, then `unfreeze` does
not operate on the objects of this domain. For example, we create
a dummy domain and an object containing an inactive function as its
operand:

dummy := newDomain("dummy"): o := new(dummy, freeze(int)(sin(x), x = 0..2*PI))

The function `unfreeze` applied to the object `o` has
no effect:

unfreeze(o)

If we overload the function `misc::maprec` in
order to operate on the first operand of objects of the domain `dummy`,
then `unfreeze` operates on `o` as
desired:

dummy::maprec := x -> extsubsop(x, 1 = misc::maprec(extop(x,1), args(2..args(0))) ): unfreeze(o)

`freeze` returns an object of the same type
as `f`. `unfreeze` returns the evaluation
of `object` after reactivating all inactive functions
in it.

Was this topic helpful?