Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » OCL expression evaluation as "LHS"
OCL expression evaluation as "LHS" [message #1252526] Fri, 21 February 2014 05:02 Go to next message
Kirsten M. Z. is currently offline Kirsten M. Z.
Messages: 131
Registered: July 2010
Senior Member
Hi there,

I know, that this is maybe a strange question, but if my idea is possible, it would save a lot of work. I wanna ask, if OCL (some library available for Eclipse) supports a special mode, where expressions are not evaluated completely, i.e., I don't get the values of attributes, but the "attributes themselves"? This way, expressions could be used as "LHS" (left-hand-side).

I will explain using an example. Please consider the following model.

Meta:

<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="test" nsURI="xyz" nsPrefix="xyz">
  <eClassifiers xsi:type="ecore:EClass" name="Person">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="first_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="PersonList">
    <eStructuralFeatures xsi:type="ecore:EReference" name="plist" unique="false" upperBound="-1"
        eType="#//Person" containment="true"/>
  </eClassifiers>
</ecore:EPackage>


<xyz:PersonList
    xmi:version="2.0"
    xmlns:xmi="http://www.omg.org/XMI"
    xmlns:xyz="xyz">
  <plist first_name="Mike"/>
  <plist first_name="Steve"/>
  <plist first_name="Sarah"/>
</xyz:PersonList>


Now, consider you are in context of person 'Mike'. The following OCL expression

first_name


simply results in 'Mike'.

I want to change/switch the evaluation in order that the attribute 'first_name' of person 'Mike' is returned. So basically, I need two results: the context (EObject) and the attribute (EAttribute). Afterwards, I can evaluate myself or use the result as "LHS".

Let's consider something more sophisticated in the context of the person list object:

plist->select(first_name.size() > 4).first_name


normally results in the list ('Steve', 'Sarah'). However, in "LHS mode" I expect the result 'first_name' (EAttribute) in the context of 'Steve' and 'Sarah' (list of EObject).

Of course, OCL expressions are restricted and have to "select an attribute" then (e.g. no return of constants, operations etc.)

I hope, that you get, what I am looking for and give me some hint how to achieve this. Thanks a lot!


[Updated on: Fri, 21 February 2014 06:23]

Report message to a moderator

Re: OCL expression evaluation as &quot;LHS&quot; [message #1254664 is a reply to message #1252526] Sun, 23 February 2014 12:21 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4014
Registered: July 2009
Senior Member
Hi

I think that you're looking for reflection for which the PIvot version
of Eclipse OCL has some preliminary support; oclType() returns a Class
so you can use ownedAttribute() to get to Property instances. However it
is only preliminary.

Regards

Ed Willink


On 21/02/2014 10:02, Kirsten M. Z. wrote:
> Hi there,
>
> I know, that this is maybe a strange question, but if my idea is
> possible, it would save a lot of work. I wanna ask, if OCL (some
> library available for Eclipse) supports a special mode, where
> expressions are not evaluated completely, i.e., I don't get the values
> of attributes, but the attributes (meta level higher) themselves? This
> way, expressions could be used as "LHS" (left-hand-side).
>
> I will explain using an example. Please consider the following model.
>
> Meta:
>
> <ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="test"
> nsURI="xyz" nsPrefix="xyz">
> <eClassifiers xsi:type="ecore:EClass" name="Person">
> <eStructuralFeatures xsi:type="ecore:EAttribute" name="first_name"
> eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
> </eClassifiers>
> <eClassifiers xsi:type="ecore:EClass" name="PersonList">
> <eStructuralFeatures xsi:type="ecore:EReference" name="plist"
> unique="false" upperBound="-1"
> eType="#//Person" containment="true"/>
> </eClassifiers>
> </ecore:EPackage>
>
> <xyz:PersonList
> xmi:version="2.0"
> xmlns:xmi="http://www.omg.org/XMI"
> xmlns:xyz="xyz">
> <plist first_name="Mike"/>
> <plist first_name="Steve"/>
> <plist first_name="Sarah"/>
> </xyz:PersonList>
>
> Now, consider you are in context of person 'Mike'. The following OCL
> expression
>
> first_name
>
> simply results in 'Mike'.
>
> I want to change/switch the evaluation in order that the attribute
> 'first_name' of person 'Mike' is returned. So besically, I need two
> results: the context (EObject) and the attribute (EAttribute).
> Afterwards, I can evaluate myself or use the result as "LHS".
>
> Let's consider something more sophisticated in the context of the
> person list object:
>
> plist->select(first_name.size() > 4).first_name
>
> normally results in the list ('Steve', 'Sarah'). I need the result
> 'first_name' (EAttribute) in the context of 'Steve' and 'Sarah'.
>
> Of course, OCL expressions are restricted and have to 'select and
> attribute' then (e.g. no return of constants, operations etc.)
>
> I hope, that you get what I am looking for and give me some hint how
> to achieve this. Thanks a lot!
>
Re: OCL expression evaluation as &quot;LHS&quot; [message #1254711 is a reply to message #1254664] Sun, 23 February 2014 13:25 Go to previous messageGo to next message
Kirsten M. Z. is currently offline Kirsten M. Z.
Messages: 131
Registered: July 2010
Senior Member
> Hi
>
> I think that you're looking for reflection for which the PIvot version
> of Eclipse OCL has some preliminary support; oclType() returns a Class
> so you can use ownedAttribute() to get to Property instances. However it
> is only preliminary.
>
> Regards
>
> Ed Willink

Yes, I can use the meta model to retrieve EAttribute/Property instances. This is even possible with OCL and oclType(), I know. After retrieving the EAttribute/Property instances, I would need a second OCL, which selects the objects for which I want to apply new values for the previously selected attribute.

However, this is not the way I want to go. In a programming language this is also not how a programmer wants to work.

An example in the world of "normal programming". This is how things work in programming (LHS and RHS are something "different"):

myObject.x := myObject.x * 2;


This is not how I want to do it:

set new value (myObject.x * 2) to attribute (x) of (myObject)


So as I explained in my original post, it would be nice, if there is some support for interpreting an OCL expression as LHS, i.e., there is no evaluation as final step. Instead, the structural feature und object(s) are returned (which would be used for evaluation).

Re: OCL expression evaluation as &amp;quot;LHS&amp;quot; [message #1255534 is a reply to message #1254711] Mon, 24 February 2014 09:50 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4014
Registered: July 2009
Senior Member
Hi

Perhaps all you need to do is create an OCL query for the LHS which will
be an ExpressionInOCL whose body is a PropertyCallExp.

Evaluating the source of the PropertyCallExp will give you the victim
object. The referredProperty will identify the feature.

Alternatively you could create an extended grammar with something
similar to a QVTc PropertyAssignment.

Assignment ::=
[“default”] SlotOwnerOCLExpr“.”PropertyName “:=” ValueOCLExpr

Although OCL is side-effect free the Pivot API supports mutation for
derived languages such as QVT.

See DomainProperty::initValue(@NonNull Object object, @Nullable Object
unboxedValue);

Regards

Ed Willink


On 23/02/2014 18:25, Kirsten M. Z. wrote:
>> Hi
>>
>> I think that you're looking for reflection for which the PIvot
>> version of Eclipse OCL has some preliminary support; oclType()
>> returns a Class so you can use ownedAttribute() to get to Property
>> instances. However it is only preliminary.
>>
>> Regards
>>
>> Ed Willink
>
> Yes, I can use the meta model to retrieve EAttribute/Property
> instances. This is even possible with OCL and oclType(), I know. After
> retrieving the EAttribute/Property instances, I would need a second
> OCL, which selects the objects for which I want to apply new values
> for the previously selected attribute.
>
> However, this is not the way I want to go. In a programming language
> this is also not how a programmer wants to work.
>
> An example in the world of "normal programming". This is how things
> work in programming (LHS and RHS are something "different"):
>
> myObject.x := myObject.x * 2;
>
> This is not how I want to do it:
>
> set new value (myObject.x * 2) to attribute (x) of (myObject)
>
> So as I explained in my original post, it would be nice, if there is
> some support for interpreting an OCL expression as LHS, i.e., there is
> no evaluation as final step. Instead, the structural feature und
> object(s) are returned (which would be used for evaluation).
>
>
Re: OCL expression evaluation as &amp;quot;LHS&amp;quot; [message #1256289 is a reply to message #1255534] Tue, 25 February 2014 04:24 Go to previous messageGo to next message
Kirsten M. Z. is currently offline Kirsten M. Z.
Messages: 131
Registered: July 2010
Senior Member
Well, I've started enhancing the EvaluationVisitorImpl and it was not that difficult. If a LHS shall be evaluated, I have to use this visitor instead of the standard one. It returns a pair of structural feature and object(s). As you said, I have to consider (outermost) PropertyCallExp, but also IteratorExp, if the attribute of multiple objects is selected (call of "collect"). I hope I considered everything then, but at least a good start.

Therefore, I have to override two methods. Without error handling (e.g. checking casts before casting) and other details:

	@Override
	public Object visitPropertyCallExp(
			PropertyCallExp<EClassifier, EStructuralFeature> pc) {

		// special behavior in LHS mode for outermost expression
		if (pc.eContainer() == null) {

			// evaluate source
			OCLExpression<EClassifier> source = pc.getSource();
			EObject context = (EObject) source.accept(getVisitor());

			return new Pair<EStructuralFeature, List<EObject>>(
					pc.getReferredProperty(),
					Arrays.asList(new EObject[] { context }));

		}

		// regular processing
		return super.visitPropertyCallExp(pc);

	}

	@Override
	public Object visitIteratorExp(IteratorExp<EClassifier, EParameter> ie) {

		// special behavior in LHS mode for outermost expression
		if (ie.eContainer() == null) {

			assert (ie.getSource().getType() instanceof PredefinedType<?>)
					&& (ie.getBody() instanceof PropertyCallExp)
					&& OCLStandardLibraryUtil.getOperationCode(ie.getName()) == PredefinedType.COLLECT))

			// evaluate source
			Object sourceValue = ie.getSource().accept(getVisitor());

			// retrieve result list
			List<EObject> resultList = new ArrayList<EObject>();
			for (Object obj : (Collection<?>) sourceValue)
				resultList.add((EObject) obj);

			return new Pair<EStructuralFeature, List<EObject>>(
					((PropertyCallExp<EClassifier, EStructuralFeature>) ie.getBody())
							.getReferredProperty(), resultList);

		}

		// regular processing
		return super.visitIteratorExp(ie);

	}

[Updated on: Tue, 25 February 2014 04:25]

Report message to a moderator

Re: OCL expression evaluation as &amp;amp;quot;LHS&amp;amp;quot; [message #1256332 is a reply to message #1256289] Tue, 25 February 2014 05:12 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4014
Registered: July 2009
Senior Member
Hi

I was suggesting rewriting the parsed AST so that you could use the
standard evaluator.

I think that using collect() for l-values is totally unsound. How do you
handle a custom operation myCollect(...) that happens to produce the
same r-value?

But then I obviously don't understand your use case.

Regards

Ed Willink

On 25/02/2014 09:24, Kirsten M. Z. wrote:
> Well, I've started enhancing the EvaluationVisitorImpl and it was not
> that difficult. If a LHS shall be evaluated, I have to use this
> visitor instead of the standard one. It returns a pair of structural
> feature and object(s). As you said, I have to consider (outermost)
> PropertyCallExp, but also IteratorExp, if the attribute of multiple
> objects is selected (call of "collect"). I hope I considered
> everything then, but at least a good start.
>
> Therefore, I have to override two methods. Without error handling
> (e.g. checking casts before casting) and other details:
>
> @Override
> public Object visitPropertyCallExp(
> PropertyCallExp<EClassifier, EStructuralFeature> pc) {
>
> // special behavior in LHS mode for outermost expression
> if (pc.eContainer() == null) {
>
> // evaluate source
> OCLExpression<EClassifier> source = pc.getSource();
> EObject context = (EObject) source.accept(getVisitor());
>
> return new Pair<EStructuralFeature, List<EObject>>(
> pc.getReferredProperty(),
> Arrays.asList(new EObject[] { context }));
>
> }
>
> // regular processing
> return super.visitPropertyCallExp(pc);
>
> }
>
> @Override
> public Object visitIteratorExp(IteratorExp<EClassifier,
> EParameter> ie) {
>
> // special behavior in LHS mode for outermost expression
> if (ie.eContainer() == null) {
>
> assert (ie.getSource().getType() instanceof
> PredefinedType<?>)
> && (ie.getBody() instanceof PropertyCallExp)
> &&
> OCLStandardLibraryUtil.getOperationCode(ie.getName()) ==
> PredefinedType.COLLECT))
>
> // evaluate source
> Object sourceValue = ie.getSource().accept(getVisitor());
>
> // retrieve result list
> List<EObject> resultList = new ArrayList<EObject>();
> for (Object obj : (Collection<?>) sourceValue)
> resultList.add((EObject) obj);
>
> return new Pair<EStructuralFeature, List<EObject>>(
> ((PropertyCallExp<EClassifier,
> EStructuralFeature>) ie.getBody())
> .getReferredProperty(), resultList);
>
> }
>
> // regular processing
> return super.visitIteratorExp(ie);
>
> }
>
Re: OCL expression evaluation as &amp;amp;quot;LHS&amp;amp;quot; [message #1256353 is a reply to message #1256332] Tue, 25 February 2014 05:36 Go to previous message
Kirsten M. Z. is currently offline Kirsten M. Z.
Messages: 131
Registered: July 2010
Senior Member
> I think that using collect() for l-values is totally unsound. How do you
> handle a custom operation myCollect(...) that happens to produce the
> same r-value?

Yes, you are probably right, it is unsound. On the other side, collect is something very special, which is why OCL supports the often used shortcut for it. And using this shortcut, it totally looks like a LHS (and basically can be used as such).

I have to think about it...

> I was suggesting rewriting the parsed AST so that you could use the
> standard evaluator.

This is what I would do, if I need to parse a complete assigment expression (including ":=" and rhs) as QVTc does. However, I only need the LHS, because the RHS is provided in another way. If changing the grammar would also be helpful here (no code changes of the visitor and better error detection), ok, but I haven't reflected about that completely.
Previous Topic:OCL Tuples in pivot
Next Topic:USE_TYPE_CACHES and DYNAMIC_DISPATCH break basic OCL operations?
Goto Forum:
  


Current Time: Fri Aug 01 22:39:59 EDT 2014

Powered by FUDForum. Page generated in 0.02387 seconds