org.eclipse.ocl.examples.impactanalyzer.deltaPropagation
Class PartialEvaluatorImpl

java.lang.Object
  extended by org.eclipse.ocl.examples.impactanalyzer.deltaPropagation.PartialEvaluatorImpl
All Implemented Interfaces:
PartialEvaluator
Direct Known Subclasses:
PartialEvaluatorNoAllInstances

public class PartialEvaluatorImpl
extends java.lang.Object
implements PartialEvaluator

Can evaluate an OCL expression when the model is in some state which just got modified by a change indicated by an event Notification such that the evaluation result is based on the state that the model was in before the modification occurred. This is similar to the @pre operator in OCL.

Additionally, if the expression to evaluate is a CallExp expression, the evaluation result of its source expression can be provided, cutting short the evaluation of this source expression. For this, it uses an adapted OCL evaluation environment. TODO need to be able to accept a set of variable definitions for the starting scope that are added to the initial evaluation environment on the OCL instance being used

Author:
Axel Uhl

Constructor Summary
  PartialEvaluatorImpl(org.eclipse.emf.common.notify.Notification atPre, OCLFactory oclFactory)
          Taking a Notification object such that an evaluation will be based on the state *before* the notification.
  PartialEvaluatorImpl(org.eclipse.emf.common.notify.Notification atPre, OppositeEndFinder oppositeEndFinder, OCLFactory oclFactory)
          Taking a Notification object such that an evaluation will be based on the state *before* the notification.
  PartialEvaluatorImpl(OCLFactory oclFactory)
          Uses a DefaultOppositeEndFinder to navigate hidden opposite properties and evaluates the model based on its current state.
  PartialEvaluatorImpl(OCLFactory oclFactory, OppositeEndFinder oppositeEndFinder)
          Constructs the OCL instance using OCLFactory.createOCL(OppositeEndFinder), passing the oppositeEndFinder provided.
protected PartialEvaluatorImpl(PartialEcoreEnvironmentFactory factory, OCLFactory oclFactory)
           
 
Method Summary
 java.lang.Object evaluate(java.lang.Object context, CallExp e, java.lang.Object valueOfSourceExpression)
          Evaluates e, assuming valueOfSourceExpression is the value to which e's source expression evaluates.
 java.lang.Object evaluate(java.lang.Object context, OCLExpression e)
          Performs a normal OCL evaluation of expression c.
 OCL.Helper getHelper()
           
 OCL getOcl()
           
 boolean hasNoEffectOnOverallExpression(OCLExpression e, java.lang.Object oldValue, java.lang.Object newValue, OperationBodyToCallMapper mapper)
          Determines if a change of e's value from oldValue to newValue may or may not have an effect on the overall expression by which e is used.
 java.util.Collection<Tuple.Pair<OCLExpression,java.util.Collection<java.lang.Object>>> transitivelyPropagateDelta(OCLExpression e, java.util.Collection<java.lang.Object> deltaForEValue, OperationBodyToCallMapper mapper)
          Tries to find a propagation strategy for the combination of the OCL expression e and a given delta for its evaluation result.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PartialEvaluatorImpl

public PartialEvaluatorImpl(OCLFactory oclFactory)
Uses a DefaultOppositeEndFinder to navigate hidden opposite properties and evaluates the model based on its current state.


PartialEvaluatorImpl

public PartialEvaluatorImpl(OCLFactory oclFactory,
                            OppositeEndFinder oppositeEndFinder)
Constructs the OCL instance using OCLFactory.createOCL(OppositeEndFinder), passing the oppositeEndFinder provided. A default PartialEcoreEnvironmentFactory is used, configured as well with the oppositeEndFinder provided here.


PartialEvaluatorImpl

protected PartialEvaluatorImpl(PartialEcoreEnvironmentFactory factory,
                               OCLFactory oclFactory)

PartialEvaluatorImpl

public PartialEvaluatorImpl(org.eclipse.emf.common.notify.Notification atPre,
                            OCLFactory oclFactory)
Taking a Notification object such that an evaluation will be based on the state *before* the notification. For example, if the notification indicates the removal of a reference from an element e1 to an element e2 across reference r then when during partial evaluation r is traversed starting from e1 then e2 will show in the results although in the current version of the model it would not.

A DefaultOppositeEndFinder is used for hidden opposite navigation.

Parameters:
atPre - if null, the constructor behaves the same as PartialEvaluatorImpl(OCLFactory)

PartialEvaluatorImpl

public PartialEvaluatorImpl(org.eclipse.emf.common.notify.Notification atPre,
                            OppositeEndFinder oppositeEndFinder,
                            OCLFactory oclFactory)
Taking a Notification object such that an evaluation will be based on the state *before* the notification. For example, if the notification indicates the removal of a reference from an element e1 to an element e2 across reference r then when during partial evaluation r is traversed starting from e1 then e2 will show in the results although in the current version of the model it would not.

Parameters:
atPre - if null, the constructor behaves the same as PartialEvaluatorImpl(OCLFactory, OppositeEndFinder)
Method Detail

getOcl

public OCL getOcl()
Specified by:
getOcl in interface PartialEvaluator

getHelper

public OCL.Helper getHelper()
Specified by:
getHelper in interface PartialEvaluator

evaluate

public java.lang.Object evaluate(java.lang.Object context,
                                 CallExp e,
                                 java.lang.Object valueOfSourceExpression)
Description copied from interface: PartialEvaluator
Evaluates e, assuming valueOfSourceExpression is the value to which e's source expression evaluates. This means that during e's evaluation the evaluator won't attempt to evaluate the source expression but uses the value provided in valueOfSourceExpression instead.

Specified by:
evaluate in interface PartialEvaluator
Parameters:
context - a value for self can optionally be provided here. If null is specified, a ValueNotFoundException will be thrown upon trying to fetch the self value.

evaluate

public java.lang.Object evaluate(java.lang.Object context,
                                 OCLExpression e)
Description copied from interface: PartialEvaluator
Performs a normal OCL evaluation of expression c. If the context object is not currently known, it's ok to pass null for context. The evaluation may fail with a ValueNotFoundException in case a variable that is accessed hasn't been defined yet. The e expression may therefore be some subexpression of a containing expression. To set variable values for the initial evaluation scope, use PartialEvaluator.getOcl(). OCL.getEvaluationEnvironment(). EvaluationEnvironment.add(String, Object).

Specified by:
evaluate in interface PartialEvaluator

hasNoEffectOnOverallExpression

public boolean hasNoEffectOnOverallExpression(OCLExpression e,
                                              java.lang.Object oldValue,
                                              java.lang.Object newValue,
                                              OperationBodyToCallMapper mapper)
Determines if a change of e's value from oldValue to newValue may or may not have an effect on the overall expression by which e is used. If this methods returns true then this guarantees that the change has no effect. If it returns false this only means that the absence of an effect could not be proven and that it is still possible that the change had no effect.

The method first applies partial evaluation along chains of CallExp and operation calls. If the computation of the full value based on old and new source value reaches the end of such a chain of CallExp and operation body/operation call constructs, #transitivelyPropagateDelta(OCLExpression, Collection) tries to propagate the delta between old and new value further. If the result of this delta propagation is empty for all expressions to which it propagates then this proves that the original change indicated by oldSourceValue and newSourceValue has no effect on the overall expression.

Parameters:
mapper - needs to be able to map an operation body in which callExp is used to the calls of that operation, as well as all operation calls in which those calls appear (transitively) to the calls of those operations, and so on, for the overall expression for which the effect of the change is to be analyzed.

transitivelyPropagateDelta

public java.util.Collection<Tuple.Pair<OCLExpression,java.util.Collection<java.lang.Object>>> transitivelyPropagateDelta(OCLExpression e,
                                                                                                                         java.util.Collection<java.lang.Object> deltaForEValue,
                                                                                                                         OperationBodyToCallMapper mapper)
Tries to find a propagation strategy for the combination of the OCL expression e and a given delta for its evaluation result. If no such strategy is found, the pair of e and delta is returned. Otherwise, the strategy is applied, and the delta is mapped to a delta for another expression using e. The result of this step is recursively passed to this method so that propagation terminates when no propagation strategy can be found for an expression.

When the object collection returned in the b component of the result is empty then this means that the overall expression in which e occurs will not be affected by the delta of e's value.

Postcondition: this.getDeltaPropagationStrategy(result.getA()) == null

Parameters:
deltaForEValue - may be null, empty or a valid non-empty collection specifying a delta in e's evaluation result
mapper - needs to be able to map an operation body in which callExp is used to the calls of that operation, as well as all operation calls in which those calls appear (transitively) to the calls of those operations, and so on, for the overall expression for which the effect of the change is to be analyzed.
Returns:
zero or more pairs with a non-null, non-empty b component which is a collection specifying the delta to which delta maps for the expression returned as the a component of the pair contained in the collection returned. If the collection returned is empty this means that the delta of e's value has no effect on the overall expression in which e appears.