org.eclipse.ocl.examples.impactanalyzer.instanceScope
Class TracebackCache

java.lang.Object
  extended by org.eclipse.ocl.examples.impactanalyzer.instanceScope.TracebackCache

public class TracebackCache
extends java.lang.Object

During the navigation of a NavigationStep tree, starting from an EObject, navigation steps may be reached several times with the same EObject at hand. To avoid endless recursion and to accelerate the computation, an object of this class is passed through an evaluation of a NavigationStep tree.

In addition to remembering traceback navigation results, this cache also stores variable values inferred during the traceback. Those can be used for partial evaluations, e.g., when trying to determine if a subexpression may be reached at all based on the current variable values.

Variable values are valid only in a scope, called a "dynamic scope." While syntactically the variable's static scope is limited to a certain OCLExpression, e.g., the in expression of a let expression for the variable defined by the let expression, the same expression may be evaluated several times during the evaluation of some other expression. Each evaluation of the static scope expression represents a dynamic scope for the variables whose static scope is being evaluated.

When the unused function is trying a partial evaluation and is missing a variable to complete the evaluation, we check if the missing variable is a let variable. If not, the unused evaluation request is stored in this cache together with the values of all variables known at that time, as well as the unknown variable that caused the evaluation to fail. If the missing variable is a let variable, we also try to evaluate the corresponding initialization expression. If that fails too, we store a nested unused evaluation request which has as its unknown variable the one from the let variable's initialization expression. If that variable's value is inferred, the initialization expression is evaluated again. If successful (either deferred or immediately), this triggers the inner request which will then have its unknown let variable set to the result of evaluating the initialization expression.

When during traceback a variable's value is inferred, the unused evaluations that have this variable as their unknown variable can be given another try, based on the variable values remembered, as well as the freshly-inferred value for the variable whose value was formerly unknown. If the evaluation succeeds and proves that the expression for which unused was evaluated is actually not used, the traceback can be stopped immediately and simply return an empty set. If the evaluation fails again for another variable with unknown value, the procedure is repeated: the freshly-inferred value is added to the known variable values for the unused evaluation request, and the variable whose value now is unknown is remembered with the request such that when it's value is inferred by the traceback procedure, the unused evaluation can be attempted again.

When the traceback function leaves an expression that is the static scope of an unknown variable, the corresponding unused evaluation requests are canceled because we cannot hope for the traceback process to ever infer it anymore. Which scopes are left when moving from one expression to the next can be a bit tricky. For example, when jumping from an iterator variable expression to the LoopExp's source expression, all kinds of in-between expressions that are containers to the iterator variable expression are left as well. Therefore, the common container of the from/to expressions needs to be determined, and all variables whose static scope is any of from, or any of from's direct or transitive containers that are still contained (directly or transitively) in the common container of from/to, are considered out of scope.

Author:
Axel Uhl (D043530)

Constructor Summary
TracebackCache()
           
 
Method Summary
 java.util.Set<AnnotatedEObject> get(NavigationStep step, AnnotatedEObject from)
          Looks up a previously entered result for the step where navigation started at the from object.
 void put(NavigationStep step, AnnotatedEObject from, java.util.Set<AnnotatedEObject> result)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TracebackCache

public TracebackCache()
Method Detail

get

public java.util.Set<AnnotatedEObject> get(NavigationStep step,
                                           AnnotatedEObject from)
Looks up a previously entered result for the step where navigation started at the from object. If not found, null is returned.


put

public void put(NavigationStep step,
                AnnotatedEObject from,
                java.util.Set<AnnotatedEObject> result)