# Evaluating Constraints and Queries

In Parsing Constraints, we saw how to use the `OCL` Facade to parse a textual OCL constraint or query expressions to give its `ExpressionInOCL` compiled representation. Parsing constraints is interesting, but evaluating them using the `Query` API is much more useful.

### The OCL Query

The `Query` class wraps the minimal `ExpressionInOCL` parse result to provide evaluation capabilities.

The `Query` encapsulates an `EvaluationEnvironment` providing the run-time values of context variables to the OCL interpreter. These context variables are set and retrieved using the following methods:

- `add(TypedElement, Object)`: adds a TypedElement-to-value binding

- `replace(TypedElement, Object)`: replaces an existing binding

- `remove(TypedElement)`: removes a binding

- `getValueOf(TypedElement)`: obtains a binding value

.bq The Ecore/UML binding of Eclipse OCL used String rather than TypedElement to support name-to-value bindings. The use of TypedElement rather than String avoids whereby the same name refers to multiple Variables depending on context. .p

The context variables of primary interest are `self` and, in operation constraints, the variables corresponding to its parameters.

An important consideration for OCL evaluation is the `allInstances()` operation, which obtains the entire extent of a classifier. For data types, this is a simple problem: the extent of an `Enumeration` is well defined and the extents of other kinds of `DataType`s are undefined. For `Class` extents, the `OCL` handle references a `ModelManager` that provides access to the user’s models. The default `PivotModelManager` lazily computes the extent of a class from the EMF `ResourceSet` containing the context element of the evaluation.

So, after optionally setting values of context variables (other than `self`; the `Query` takes care of this) and an extent map, simply construct a query and use it to evaluate the expression or check the constraint:

[Text for cut and paste]

### Object representations

The example above uses `evaluateUnboxed()` so that the return value is unboxed and so compatible with the Classic Ecore/UML OCL binding.

The Pivot binding of OCL supports three distinct Java representations.

- boxed for internal use

- unboxed for traditional API compatibility

- Ecore for Ecore API compatibility

OCL | Unboxed | Ecore | Boxed
--- | --- | --- | ---
Boolean | Boolean | Boolean | Boolean
String | String | String | String
Integer | Integer/Long/BigDecimal | Integer/Long/BigDecimal | IntegerValue
Real | Float/Double | Float/Double | RealValue
Object | EObject | EObject | EObject
Type | EClassifier | EClassifier | TypeValue
null | null | null | null
invalid | InvalidValueException | InvalidValueException | InvalidValueException
Collection | Collection | EList | CollectionValue
Bag | Bag | EList | BagValue
Sequence | List | EList | SequenceValue
OrderedSet | OrderedSet | EList | OrderedSetValue
Set | Set | EList | SetValue

The boxed representation is used wherever the Java semantics of `Object.equals(Object)` is different to the OCL semantics of `OclAny::_'='(OclAny)`.

The unboxed representation is used when a similar representation to the Ecore/UML binding is required.

The Ecore representation is used for all interchange with Ecore EStructuralFeature values or EOperation arguments and returns.

### Multiple Evaluations

One of the advantages of the `Query` API is that a query’s evaluation environment can be reused for multiple evaluations, as above. The extent of any classifier is only computed once. For convenience, however, in situations where only a single evaluation is required, the `OCL` class provides shortcuts:

[Text for cut and paste]

### Succint Evaluations

The `Query` API also provides methods that work on multiple elements. The first example, above, could be written more succinctly as:

[Text for cut and paste]