Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Checking an OCL constraint before actually setting the value
Checking an OCL constraint before actually setting the value [message #1129273] Tue, 08 October 2013 13:17 Go to next message
Thomas Steinbach is currently offline Thomas SteinbachFriend
Messages: 13
Registered: March 2013
Junior Member
Hello,

is there a way to check an OCL constraint before you actually set the value?

Example: (or see the exported project as zip)
You have a class Person
- with the attribute age and
- a reference father to another person.
- Of course a father should be older than his child

in pseudo-code:
Person child = new Person(age=60)
Person father = new Person(age=50)

Constraint con = Person.getFatherIsOlderConstraint()
con.testIfWouldBeAccepted(child, father)


As far as I got with code to try checking at all:
(with help of http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.ocl.doc%2Fhelp%2FOCLInterpreterTutorial.html)
private void validateBeforeSet(Person p) throws ParserException {

		OCL ocl = OCL.newInstance();
		OCLHelper helper = ocl.createOCLHelper();
		helper.setContext(SimplemodelPackage.Literals.PERSON);
		
		
		Constraint invariant = (Constraint) helper.createInvariant("father.age < age");
		
		Query invEval = ocl.createQuery(invariant);
		invEval.getEvaluationEnvironment().add("father", p.getFather());
		
		Object result = invEval.evaluate(p);
		
		System.out.println(result);
	}


But the result is always "invalid", even if I change the invariant to "father.age > age"

Eclipse:
Version: Kepler Release
Build id: 20130614-0229
OCL End User SDK 4.1.1.v20130916-1423
OCL Examples and Editors 3.3.1.v20130916-1423

Thank you for your time and help,
Tom
  • Attachment: SimpleOCL.zip
    (Size: 43.46KB, Downloaded 116 times)

[Updated on: Tue, 08 October 2013 13:54]

Report message to a moderator

Re: Checking an OCL constraint before actually setting the value [message #1129308 is a reply to message #1129273] Tue, 08 October 2013 13:59 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

If you want to test a hypothetical state, you will need to create that
hypothetical state. Possibly by creating a deep clone and then applying
your mutation.

A deep clone can be very expensive and may have unexpected side effects.

If your hypothesis is limited to a couple of features you could
re-implement getXXXX to conditionally return your hypothetical value.

If you want to have many changes, it may be possible to have your model
extend HypothesizedEObject in which you re-implement some part of the
eGet() flow; this could work withe the OCL interpreter but would fail
with the OCL to JHava Code Generator that generates duirect getXXX
rather that eGet(XXX) accesses.

Much the easiest would be to do the real change live and perhaps
roll-back, possibly with the help of EMFt, but I can see that in many
scenarios this might be unacceptable.

When I finally get round to implementing @pre for accurate postcondition
execution, the difficulties of maintaining a smart system copy for @pre
and maintaining a smart system copy for a hypothesis might not be so
very different, so please raise an enhancement Bugzilla. I'm afraid that
the response may be over a year away.

Regards

Ed Willink

On 08/10/2013 14:17, Thomas Steinbach wrote:
> Hello,
>
> is there a way to check an OCL constraint before you actually set the value?
>
> Example: (or see the exported project as zip)
> You have a class Person
> - with the attribute age and
> - a reference father to another person.
> - Of course a father should be older than his child
>
> in pseudo-code:
> Person child = new Person(age=60)
> Person father = new Person(age=50)
>
> Constraint con = Person.getFatherIsOlderConstraint()
> con.testIfWouldBeAccepted(child, father)
>
> As far as I got with code to try checking at all:
> private void validateBeforeSet(Person p) {
>
> OCL ocl = OCL.newInstance();
> OCLHelper helper = ocl.createOCLHelper();
> helper.setContext(SimplemodelPackage.Literals.PERSON);
>
>
> Constraint x = null;
> try {
> x = (Constraint) helper.createInvariant("father.age > age");
> } catch (ParserException e) {
> e.printStackTrace();
> }
>
> Object r = ocl.check(p, x);
> System.out.println(r);
> }
>
>
> Thank you for your time and help,
> Tom
Re: Checking an OCL constraint before actually setting the value [message #1129335 is a reply to message #1129308] Tue, 08 October 2013 14:26 Go to previous messageGo to next message
Thomas Steinbach is currently offline Thomas SteinbachFriend
Messages: 13
Registered: March 2013
Junior Member
Thank you for this fast answer,

so as far as I could understand, (sorry if I don't have the right naming/terms)
internally a "Constraint" doesn't use a kind of "parameter" where I could "bind" my "TestValue"

Example in pseudo-code:

Constraint FatherIsOlder
     checks if Person father is older than Person child
     -> so it uses 2 parameters:
     parameter1: father
     parameter2: child

con1 = new FatherIsOlder()
con1.setFather(person1)
con1.setChild(person2)

-> expecting result
result = con1.validate();


I'm sorry if you feel this as repeating, it's only because I am not sure if I did understand your answer right or if I could explain my aim.

Thank you,
Tom
Re: Checking an OCL constraint before actually setting the value [message #1129374 is a reply to message #1129335] Tue, 08 October 2013 15:08 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

A Constraint is an invariant on the current state. So to use a
constraint you must have the requisite current state.

You can of course write you own operations with whatever arguments you
like with OCL bodies to compute any query that you are interested in.

Regards

Ed Willink

On 08/10/2013 15:26, Thomas Steinbach wrote:
> Thank you for this fast answer,
>
> so as far as I could understand, (sorry if I don't have the right
> naming/terms)
> internally a "Constraint" doesn't use a kind of "parameter" where I
> could "bind" my "TestValue"
>
> Example in pseudo-code:
>
> Constraint FatherIsOlder
> checks if Person father is older than Person child
> -> so it uses 2 parameters:
> parameter1: father
> parameter2: child
>
> con1 = new FatherIsOlder()
> con1.setFather(person1)
> con1.setChild(person2)
>
> -> expecting result
> result = con1.validate();
>
> I'm sorry if you feel this as repeating, it's only because I am not
> sure if I did understand your answer right or if I could explain my aim.
>
> Thank you,
> Tom
how a newbie (mis)interpretes OCL [message #1129463 is a reply to message #1129374] Tue, 08 October 2013 16:52 Go to previous messageGo to next message
Thomas Steinbach is currently offline Thomas SteinbachFriend
Messages: 13
Registered: March 2013
Junior Member
maybe I misinterprete OCL, because the above solution would mean to have the condition twice, first in the constraint where needed and second in the operation you mentioned before, in order to check if setting the value would be allowed?

What I've expected is the following (in words, see my try with code below and the corresponding markers):

Quote:
- The framework creates something out of the pure OCL-String "father.age > self.age",
maybe a generated class which contains the code representing the condition "father.age > self.age" (* Code 1)

- this "element" knows _how_ to determine if the result is true or not,
but just needs the two parameters father and self

- now I can provide several objects for the parameter father and ask this "condition"-element for its result (* Code 2)



Is the code below going in this direction, or did I misunderstand it at all?
	OCL ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
	OCLHelper helper = ocl.createOCLHelper();
	helper.setContext(SimplemodelPackage.Literals.PERSON);
		
		
	Constraint condition = (Constraint) helper.createInvariant("father.age < age");  <--- (* Code 1)
		
	Query invEval = ocl.createQuery(invariant);
	invEval.getEvaluationEnvironment().add("father", p.getFather()); 	<--- (*Code 2), bind the Condition element to the current father-parameter
		
	Object b = invEval.evaluate(p);   <--- evaluate if this father-element would match the condition

--> System.out.println(b); results in "invalid"

With best regards,
Tom

[Updated on: Tue, 08 October 2013 17:04]

Report message to a moderator

Re: how a newbie (mis)interpretes OCL [message #1129477 is a reply to message #1129463] Tue, 08 October 2013 17:14 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

I cannot really follow your message beyond the complaint about duplication.

Operations are a common approach to support reuse.

You can provide an operation that performs the hypothetical validation
with custom parameters and code the invariant to invoke the same
operation with state values.

Regards

Ed Willink


On 08/10/2013 17:52, Thomas Steinbach wrote:
> maybe I misinterprete OCL, because the above solution would mean to
> have the condition twice, first in the constraint where needed and
> second in the operation you mentioned before, in order to check if
> setting the value would be allowed?
>
> What I expected is the following (in words, see my try with code below
> and the corresponding markers):
>
> Quote:
>> - The framework creates something out of "father.age > self.age",
>> maybe a generated class which contains the code representing the
>> condition "father.age > self.age" (* Code 1)
>> - this "element" knows _how_ to determine if the result is true or not,
>> but just needs the two parameters father and self
>>
>> - now I can provide several objects for the parameter father and ask
>> this "condition"-element for its result (* Code 2)
>
>
>
> Is the code below going in this direction, or did I misunderstand it
> at all?
>
> OCL ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
> OCLHelper helper = ocl.createOCLHelper();
> helper.setContext(SimplemodelPackage.Literals.PERSON);
>
>
> Constraint condition = (Constraint)
> helper.createInvariant("father.age < age"); <--- (* Code 1)
>
> Query invEval = ocl.createQuery(invariant);
> invEval.getEvaluationEnvironment().add("father",
> p.getFather()); <--- (*Code 2), bind the Condition element to the
> current father-parameter
>
> Object b = invEval.evaluate(p); <--- evaluate if this
> father-element would match the condition
>
>
> With best regards,
> Tom
Previous Topic:getStereotype() always return "invariant"
Next Topic:Using OCL for creating (temporary) object
Goto Forum:
  


Current Time: Thu Apr 25 01:55:35 GMT 2024

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

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

Back to the top