Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Derived attributes differ randomly
Derived attributes differ randomly [message #660764] Mon, 21 March 2011 13:59 Go to next message
Michael Schorer is currently offline Michael SchorerFriend
Messages: 6
Registered: June 2010
Junior Member
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 #660770 is a reply to message #660764] Mon, 21 March 2011 14:21 Go to previous messageGo to next message
Axel Uhl is currently offline Axel UhlFriend
Messages: 40
Registered: July 2009
Member
Hi Michael,

the console and your editor/view for the instance model may use different ResourceSets and therefore different copies of the resources, hence different versions of the model elements.

So, yes, to a degree, model element loading can be one reason for getting different results, particularly if your expression is using allInstances(). The value of allInstances() by default is computed by scanning the ResourceSet as it is for instances of the type requested (and subtypes thereof). Therefore, the value of allInstances() is affected by loading/unloading a resource into/from a resource set.

You may also post your derivation expressions here. Maybe it helps in identifying the cause of the problem.

Best,
-- Axel
Re: Derived attributes differ randomly [message #660778 is a reply to message #660764] Mon, 21 March 2011 14:53 Go to previous messageGo to next message
Michael Schorer is currently offline Michael SchorerFriend
Messages: 6
Registered: June 2010
Junior Member
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 #660986 is a reply to message #660778] Tue, 22 March 2011 14:45 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 4188
Registered: July 2009
Senior Member
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 15:47 Go to previous messageGo to next message
Michael Schorer is currently offline Michael SchorerFriend
Messages: 6
Registered: June 2010
Junior Member
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 #661078 is a reply to message #660994] Wed, 23 March 2011 01:34 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 4188
Registered: July 2009
Senior Member
Hi Michael
> 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).
No problem. The XText Console first appears as an option in 3.1.0M6
Examples.
>
> 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?
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 can see that there might be a problem if the nested property also
accesses the outer property before assignment.

I'm not sure that this applies to your problem.

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.

Regards

Ed Willink
Re: Derived attributes differ randomly [message #661440 is a reply to message #660764] Thu, 24 March 2011 16:42 Go to previous messageGo to next message
Michael Schorer is currently offline Michael SchorerFriend
Messages: 6
Registered: June 2010
Junior Member
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


Re: Derived attributes differ randomly [message #661459 is a reply to message #661440] Thu, 24 March 2011 17:57 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 4188
Registered: July 2009
Senior Member
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
>
>
>
Previous Topic:help with tools to use OCL from the beginning
Next Topic:UML profile / how to attach and evaluate OCL constraints
Goto Forum:
  


Current Time: Mon Dec 22 02:15:20 GMT 2014

Powered by FUDForum. Page generated in 0.01885 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software