Home » Modeling » OCL » OCL expression evaluation as "LHS"
OCL expression evaluation as "LHS" [message #1252526] |
Fri, 21 February 2014 10:02 |
Kirsten M. Z. Messages: 132 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
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 11:23] Report message to a moderator
|
|
|
Re: OCL expression evaluation as "LHS" [message #1254664 is a reply to message #1252526] |
Sun, 23 February 2014 17:21 |
Ed Willink Messages: 7655 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 "LHS" [message #1254711 is a reply to message #1254664] |
Sun, 23 February 2014 18:25 |
Kirsten M. Z. Messages: 132 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 &quot;LHS&quot; [message #1255534 is a reply to message #1254711] |
Mon, 24 February 2014 14:50 |
Ed Willink Messages: 7655 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 &quot;LHS&quot; [message #1256289 is a reply to message #1255534] |
Tue, 25 February 2014 09:24 |
Kirsten M. Z. Messages: 132 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 09:25] Report message to a moderator
|
|
|
Re: OCL expression evaluation as &amp;quot;LHS&amp;quot; [message #1256332 is a reply to message #1256289] |
Tue, 25 February 2014 10:12 |
Ed Willink Messages: 7655 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;quot;LHS&amp;quot; [message #1256353 is a reply to message #1256332] |
Tue, 25 February 2014 10:36 |
Kirsten M. Z. Messages: 132 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.
|
|
|
Goto Forum:
Current Time: Thu Apr 18 05:56:53 GMT 2024
Powered by FUDForum. Page generated in 0.02017 seconds
|