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 floatingpoint
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 identifiersum
:
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 environmentsum
, 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)

A procedure or a function environment 
freeze
returns an object of the same type
as f
. unfreeze
returns the evaluation
of object
after reactivating all inactive functions
in it.