Derived attributes differ randomly [message #660764] |
Mon, 21 March 2011 09:59  |
Eclipse User |
|
|
|
Hey there,
I'm encountering a strange behavior with embedded OCL in an EMF model.
The values of my derived reference are changing randomly after I close and open the instance model file.
This reference is partially computed by evaluating another derived reference.
When I check the OCL expressions in the OCL console, they are always computing the correct values.
Can this be a problem with the EMF editor? Does it load the model elements in an arbitrary order which influences the derivations? Does any of the EMF properties (transient, volatile,..) affect the derivation?
Best regards
Michael
|
|
|
|
|
Re: Derived attributes differ randomly [message #660986 is a reply to message #660778] |
Tue, 22 March 2011 10:45   |
Eclipse User |
|
|
|
Hi Michael
Your observation that results change randomly is a little vague.
Do you mean that you get a different result each time you load the
model, rather than while you are using the model.
You OCL includes a number of Sets, flatten, asSequences, and firsts. I
suspect that you may be experiencing unpredictable results from the
accidental ordering of hashCodes which may not be repeatable.
You might find the OCL easier to understand and the problem easier to
debug by introducing intermediate properties.
transient, volatile etc should not have an effect.
You didn't specify which versions you were using. If you're using the
new Interactive Xtext OCL Console, you could be using the new evaluator
that fixes a number of corner case evaluations for the stable
observation, and the old LPG driven evaluator for the unstable observ
ations.
I suspect that any further investigation will require a full repro.
Regards
Ed Willink
On 21/03/2011 07:53, Michael Schorer wrote:
> Hi,
>
> my derivation are rather complex. But I'll try to explain them.
> I don't use allInstances(), though.
>
> The main concept of the statements is to compute a tree structure from
> a set of so called integration steps, based on a non-containment
> reference named"has_components". The children of each integration
> step are the steps which have a subset of the integration step's
> components.
> The integration steps are contained in a so called schedule.
>
> children:
> in_schedule.consists_of_integration_steps->excluding(self)-
> >select(step:vi_integration_step|self.has_components->includesAll(step.has_components)
> and self.has_components->notEmpty())
> ->reject(step:vi_integration_step|
> in_schedule.consists_of_integration_steps->excluding(self)-
> >excluding(step)->exists(step2:vi_integration_step|
> step2.has_components->includesAll(step.has_components) and
> step2.has_components->symmetricDifference(step.has_components)-
> >size() <
> self.has_components->symmetricDifference(step.has_components)- >size()))
> ->asOrderedSet()
>
> The reference parent is the opposite of the children reference.
> parent:
> in_schedule.consists_of_integration_steps->select(children-
> >includes(self))->asSequence()->first()
>
> The last derived reference is the one which causes the said behavior.
> The components have dependencies on other components. The derivation
> shall find the integration steps which has the components to satisfy
> the dependencies. Therefore it collects all components on which the
> step's components are depending inside of the step's tree branch and
> selects the "closest" step which satisfies the dependency.
>
> dependency_on_step:
> self.has_components->collect(comp:vi_general_component|comp.has_dependency_on-
> >reject(comp3:vi_general_component|
> comp3.is_part_of_integration_step->includes(self))->
> collect(comp2:vi_general_component|comp2.is_part_of_integrat ion_step-
> >asSet()->intersection(self->closure(parent)->asSet())
> ->sortedBy(comp2.is_part_of_integration_step->closure(parent)-
> >size())->first() ))->asBag()->flatten()
>
>
> I hope I could describe it well enough..
>
> Best regards
> Michael
|
|
|
Re: Derived attributes differ randomly [message #660994 is a reply to message #660764] |
Tue, 22 March 2011 11:47   |
Eclipse User |
|
|
|
Hi Ed,
I am using OCL version 3.0.2. I am sorry but I don't know if this is the new Xtext Interactive Console (It only says Interactive OCL when I'm opening the console).
The error is only present when I open the model and look at its derived references. When I use the OCL interactive console and compute the values with the same ocl statements, that I have in my ecore, I will ALWAYS get the correct values.
Is there any information on how the order of the computation of the derivations is performed? Can it be influenced?
In my case, if the derivation which depends on a second derivation's values is performed before the second derivation, it would compute wrong values, wouldn't it?
Simple example (OCLinEcore style):
class my_object {
property a_reference : my_third_object[?];
attribute X : ecore_0::EInt[?] {
derivation:
a_reference->size();
}
}
class my_second_object{
attribute Y: ecore_0::EInt[?] {
derivation:
a_second_reference->size()+self.X;
}
property a_second_reference : my_object[1];
}
The attribute Y will only have the correct values, if the derivation for X is computed first, right?
Best regards,
Michael
|
|
|
|
|
Re: Derived attributes differ randomly [message #661459 is a reply to message #661440] |
Thu, 24 March 2011 13:57  |
Eclipse User |
|
|
|
Hi Michael
You have two approaches that give different results. I was hoping that
you could insert println's in each getXXX so that we could trace the
execution flow for the two different approaches and so get some insight
into where they differ. Instrumenting just the final result as you have
only eliminates the slightly unlikely possibility that the result
observation was faulty.
Eliminating laziness shouldn't make any difference, since my suspicion
is that somehow a recursive access is recursing inappropriately.
Performing the access eagerly will just get the wrong result sooner.
[My example was illustrating how the two phases of starting and
completing recursing evaluation might interleave wrongly.]
I'm afraid that if you want help, you must either provide us with a
repro or assist us by instrumenting your own code so that we can get
close enough to figure it out.
Regards
Ed Willink
On 24/03/2011 09:42, Michael Schorer wrote:
> Hi Ed,
>
> I'm not sure if I understood your last post correctly.
> I added some printlns to the getters in the impls of the model
> elements (I have no setters since those properties are read-only).
> I get the same (wrong) outputs as I would get inside of my editor.
>
> Quote:
>> The derived property is computed lazily, so provided there is no
>> circular reference
>>
>> an outer property starts to be resolved
>> a nested property starts to be resolved
>> a nested property value is assigned
>> an outer property value is assigned
>
> I don't fully understand what you mean by that. Will the derived
> property also trigger the computation of another derived property when
> it is accessed?
> I guess I don't kown enough about the internal OCL/EMF structures to
> tackle the problem...
> Is there a way to make the computation non-lazy?
>
> Quote:
>> If I had the repro, I would insert some println's in the questionable
>> setXXX methods and compare the console logs from the two cases.
>> Perhaps you could do this.
>
> With "two cases", do you mean the printlns and the values in the editor?
> Best regards
> Michael
>
>
>
|
|
|
Powered by
FUDForum. Page generated in 0.25252 seconds