Evaluate

Revision as of 19:21, 22 August 2016 by Bbecane (talk | contribs)


Evaluate(t)

Evaluate expects a text value «t», and evaluates it as though it were an expression in a definition. It returns the value resulting from evaluating the expression. For example:

Evaluate('10M /10') → 1M

If «t» contains any syntax errors, Evaluate returns Null; it will not flag a syntax error.

One use for Evaluate is to convert (coerce) a text representation of a number into the number itself, for example:

Evaluate('100M') → 100M

Like most other functions, it returns the deterministic (Mid) or probabilistic value, according to the context in which it is called. Evaluate is powerful, and useful for a variety of purposes, but, it has some subtle aspects. Consider:

Variable A := 99
Variable B := (VAR A := 0; Evaluate('A + 1'))
B → 100

The Variable A in the evaluated text 'A + 1' refers to the global A, not the local A defined in B. More generally:

  • Evaluate(t) creates its own context for parsing «t» (at evaluation time), which is quite separate from the context of the expression in which the Evaluate(t) appears.e.g., the definition of B above.
  • So, text «t» cannot refer to local variables, indexes, or function parameters defined in the context in which the Evaluate(t) function appears.
  • If the text value of «t» refers to any global variables—e.g., A in the definition of B above—these will not appear as Inputs of B, nor will any changes to A cause automatic re-evaluation of B.
  • Text «t» may itself define local Variables and indexes, and refer to them, but these will not be available outside «t».
  • When Evaluate references another variable, Analytica will not be able to track the dependency. For example:
B := A + 1
C := Evaluate('A + 1')

When A changes, Analytica will automatically ensure that B is updated, but it has no way of knowing C should also be recomputed.

Text «t» may itself be an expression that creates a text value to be evaluated by Evaluate. This text expression appears in the definition of V and is not subject to the above limitations, so, for example:

Variable V :=(Var x:= ’10’; Evaluate(x & x))
V → 1010

When to Use

The cases in which you should use Evaluate are rare. You should be very reluctant to use it due to the caveats listed in the previous section.

Legitimate cases that do occasionally occur:

  • Parsing numbers or simple expressions.
  • (advanced) Use in Meta-Inference algorithms where you are manipulating handles to objects in your model.
  • (rare) Cases where you really do wish to by-pass dependency maintenance. You want it to compute something the first time the result is requested after the model is first loaded, but not update when parent values are changes.

Non-text Parameters

A non-text value can also be passed to Evaluate, which can be of use in some Meta-Inference applications. You need to keep in mind that the parameter to evaluate is evaluated BEFORE the function itself gets it, so evaluating a non-text value is only meaningful when the evaluated parameter is itself something that can still be evaluated. One instance of this that is often useful is the case of a varTerm, i.e., a handle to an object.

For example, suppose

Variable A := 2 + 3
Variable TheVar := VarTerm(A)

In the more general case, you might have a Meta-Inference algorithm that identifies a single variable object through some computation. Having identified the object, TheVar now holds a handle to the object. You then may want to access values or properties of the object pointed to by TheVar, rather than just values or properties of TheVar itself. Evaluate serves this purpose:

TheVar → A { A -- i.e., a handle to the object A }
Evaluate(TheVar) → 5 { evaluates A }

It is worth nothing that an alternative method also exists for evaluating a varTerm. If you assign an existing varTerm (handle to an object) to a local variable, that variable becomes an alias for the object identifier. If that local variable then appears in a value context, this also returns the value of the target variable:

Var x := TheVar Do x → 5 { x is an alias for A, so "x" in the body is the value of A }

When accessing attributes of an object in a Meta-Inference algorithm, where your algorithm has a handle to an object (again, say it is in TheVar), you can access the attribute using e.g.,

Description Of Evaluate(TheVar) → "Description of A"
Description Of TheVar → "Description of TheVar"

(the result of using TheVar alone is shown for comparison).

Invoking Functions

Given a handle to a function object, you can use Evaluate to call the function. If the function expects N parameters, you would provide N+1 parameters to Evaluate -- the first parameter being the handle to the function, and the remaining parameters being the values passed to the function. Example:

MetaVar fn := If opt = 1 then Handle(Max) else if opt = 2 then Handle(Min) else Handle(Sum);
Evaluate(fn, A, I)

Parameters to the function being called are always passed by position, i.e., you cannot use a named-parameter calling syntax as you might if you were calling the function directly.

If the function being called contains repeated (or variable number of) parameters, and you need to include a parameter that follows the repeated parameter, then you must place brackets around the repeated parameters. For example,

Function Fu1(x; y: repeated; z: optional) := ...
 
Evaluate(fn, 1, 2, 3, 4) →
Equivalent to Fu1(1, 2, 3, 4), where [2, 3, 4] are values for y and z is omitted
Evaluate(fn, 1, [2, 3], 4) →
Equivalent to Fu1(1, 2, 3, y: 4), where [2, 3] are values for y, and z is 4.

However, there is a limitation that the first supplied parameter (i.e., the second parameter to Evaluate) cannot be placed inside brackets. Likewise, you cannot pass an literal list by specifying the first parameter as a bracketed list. This is because the repeated-parameter syntax applies equally to Evaluate. If you specify the first parameter to Evaluate in brackets, those become the parameters to the function, i.e.,:

Evaluate(Handle(F), [1, 2, 3, 4]) →
Equivalent to F(1, 2, 3, 4)

Several common built-in functions, including Sum, Max, and Min, allow a variable number of indexes, so that you can use Sum(A, I, J, K) to sum over 3 dimensions in a single call. These functions also have optional parameters, such as «ignoreNonNumbers», so that if you need to specify these optional parameters, you will need to place brackets around the index(es), even if only one (or zero) index is specified. For example, the following examples show how to to specify «ignoreNonNumbers» as true to Sum, when summing over a single index, and when summing over the implicit dimension:

Evaluate(Handle(Sum), A, [I], true)
Var x := [3, 2, 'a', 'b', 6] do Evaluate(Handle(Sum), x, [], true)

Notice that if you don't need to specify the optional «ignoreNonNumbers» parameter (or any parameters that follow the repeated index parameters), then it is more natural to omit the brackets:

Evaluate(Handle(Sum), A, I)
Var x := [3, 2, 5, 3, 6] do Evaluate(Handle(Sum), x)

See Also

Comments


You are not allowed to post comments.