RE: OCL expression



RE: OCL expression

From: Waldin, Earl <Earl.Waldin_at_paranor.ch>
Date: Tue, 19 Dec 2006 12:38:38 +0100
Message-ID: <1DE41A26EA92CA4FB831A9449AB0841E5DC1AD@srv-par2.paranor.ch>
> -----Original Message-----
> From: puml-list-request@cs.york.ac.uk 
> [mailto:puml-list-request@cs.york.ac.uk] On Behalf Of Thomas Baar
> Sent: Monday, 18 December, 2006 18:15
> To: puml-list@cs.york.ac.uk
> Subject: Re: OCL expression
> 
> 
> Dear all,
> 
> Waldin, Earl wrote:
> 
> >
> >constraint as
> >  
> >
> >>"class A can not have any subclass"
> >>
> >>How can I express this constraint between: 
> >> 
> >>1. context A inv: self.inheritedMember->isempty()
> >>
> >>2. context A inv: self.generalization->size() = 0
> >>    
> >>
> >
> >These two constraints do not say what you want. The first essentially
> >says that the superclasses of A cannot have any members. The second says
> >that class A cannot itself be a subclass. Neither one prevents, say a
> >class B, from being a subclass of A.
> >
> >In UML 1.4 you could have
> >
> >  context A inv: self.isLeaf
> >  
> >
> Earl is also not completely right here, I'm afraid. The point is that /self/ represents in the context of
> class A  (the context is fixed by "context A inv:") an object of class 
> A. In the example constraints, however, /self/ is used as an instance of metatype "Class".
> 
> What you try to express here are so-called architectural constraints for your
> class diagram. OCL does not allow you to formulate architectural constraints
> directly in the class diagram but some systems (e.g. Topcased) are flexible enough
> to process architectural constraints on the metalevel.
> 
> For UML1.x you could add, for example, the following well-formedness rule to the
> metamodel:
> 
> context Class inv:
>     self.name = 'A' implies self.specialization->isEmpty()
> 
> Note that /self.specialization/ denotes all generalization arrows that come from subclasses
> (if the class with name 'A'  is not allowed to have any subclass, this set of
> generalization arrows must be empty).

Thomas is right here. It's so easy to get mixed up between levels! An OCL constraint at one level constrains instances at the next (lower) level. isLeaf is a property  of the metaclass Class. You can specify a *value* for isLeaf for an *instance* of metaclass Class at the model level. For example, using a UML 1.4 modeling tool you could specify that isLeaf = true for class A, just like you could specify that isAbstract = true. However, you *cannot* specify these values using OCL at the model level. To constrain these values at the model level using OCL you must put the OCL constraint at the metalevel as Thomas has done. I hope this makes sense.

You could also write

  context Class inv:
      self.name = 'A' implies self.isLeaf

which directly uses the metamodel concept for whether or not a class can be subclassed and aligns with the property that a UML 1.4 modeling tool would present to a user. It is also the property that a code generator would examine to generate the "final" keyword when generating Java from a class model.

> 
> 
> I don't know how to rephrase my constraint for UML2.0 :-(
> Do we have UML2.0 experts on this list?

Note that Thomas's constraint above for UML 1.4 works because the property in question, "specialization", is the role name of a bidirectional association in the metamodel. In fact, all associations in the UML 1.4 metamodel are bidirectional, which makes life easy for writing constraints at the metalevel. Unfortunately, almost all associations in the UML 2.0 metamodel are unidirectional! This makes it extremely difficult to write constaints at the metalevel if you respect the direction of navigation of associations. The modeling of generalization in UML 2.0 is nearly identical to that in UML 1.4, the only difference being the role names. However, the association is now unidirectional. You can't navigate in the direction of specialization. That's why I mentioned the allInstances hack. You could write:

 context Class inv:
    self.name = 'A' implies Class.allInstances() -> forAll(c | c.general -> excludes(self))

And given that the property isLeaf for metaclass Class no longer has the same meaning as in UML 1.4, you can't use my alternative constraint with isLeaf above. 

Regards

	-Earl

> 
> Best regards,
> Thomas
> 
> 
> 
> -- 
> Dr. Thomas Baar
> Software Engineering Laboratory
> School of Computer and Communication Sciences EPFL
> EPFL IC UP-LGL
> INJ 337 (Bātiment INJ)
> Station 14
> CH-1015 Lausanne, Switzerland
> Tel +41 21 693 2580, Fax +41 21 693 5079
> mailto:thomas.baar@epfl.ch   http://lgl.epfl.ch/members/baar/
> 
> 
> 
> 
> To remove yourself from this list please mail 
> puml-list-request@cs.york.ac.uk
> with a message containing the word "unsubscribe".
> 
> 
Received on Tue 19 Dec 2006 - 11:38:47 GMT