4

Suppose you have an excerpt of a larger profile for cars:

Profile Excerpt for Cars

Now i want to define some constraints for a Car, say one of those constraints states, that if attrA is true, then attrB must be false like this using OCL:

Context UML::Core::Class inv:
self
  .stereotype
  .name='Car'
implies
  self.attrA=true
  implies
    self.attrB=false

My question is: If the Mercedes stereotype specializes the Car stereotype do I stick to the same constraints, in other words: is the stereotype Car still applied for classes that have the Mercedes stereotype applied?

I would suppose that self.stereotype.name='Car' return false if the applied stereotype is Mercedes.

This is interesting because I want to have the same attributes on a Mercedes as on a Car, but i want to change the previously stated constraint.

Tilman Zuckmantel
  • 643
  • 1
  • 6
  • 18
  • yes Mercedes (also) inherits constraints from Car – bruno Nov 03 '20 at 14:26
  • @bruno The question is whether `self.stereotype.name='Car'` evalutes to `true` for `Mercedes`(I would think so but I don't know). – qwerty_so Nov 03 '20 at 15:58
  • 1
    @qwerty_so ah yes I read to fast the question. For me evaluates to `false` and I put an answer – bruno Nov 03 '20 at 18:36
  • I don't know your business domain but creating a stereotype which is actually a car's brand seem strange, to say the least. – qwerty_so Nov 03 '20 at 22:07

2 Answers2

4

I would suppose that self.stereotype.name='Car' return false if the applied stereotype is Mercedes.

Yes you are right.

Mercedes inherits the constraint as it is, so self.stereotype.name='Car' is false for a class stereotyped Mercedes rather than Car because 'Mercedes' and 'Car' are two different strings.


If you want to have the first implies active for the metaclasses specializing Car directly or indirectly you can get all the generalizations of the stereotype more itself to search for one named 'Car', also checking the name of the profile of the stereotype and may be its URI. So for instance replace self.stereotype.name='Car' by :

self.stereotype.profile.name = 'Cars' and
-- self.stereotype.profile.URI= '...' and
self.stereotype.generalization()
  ->closure(general.generalization).general()
    ->including(self.stereotype)
      ->select(name = 'Car')
        ->notEmpty()

or with an alone profile named Cars and an alone stereotype in it named Car :

self.stereotype.oclIsKindOf(Profile.allInstances()
                              ->any(name = 'Cars') -- may be check also URI
                                 .ownedStereotype->any(name = 'Car'))

Additional notes :

  • in your proposal you suppose only your stereotype is named Car among all the stereotypes of all the profiles, of course that can be false. You can also check the name of the profile and may be its URI like:

    self.stereotype.name='Car'
    and self.stereotype.profile.name='Cars'
    -- and self.stereotype.profile.URI= '...'
    
  • in your diagram the arrow head is wrong because it must be a filled triangle rather than < (probably you use PlantUML) :

enter image description here

bruno
  • 32,421
  • 7
  • 25
  • 37
  • Thx for the detailed answer. I was wondering, when looking at the metamodel of UML i find that stereotypes are associated with classes using an extension association (UML 2.5.1 Ref Chp 12.3.2 [Link to Reference](https://www.omg.org/spec/UML/2.5.1/PDF)). Extension goes to ExtensionEnd and ExtensionEnd to Stereotype. So wouldn't the appropriate way to obtain a stereotype in OCL be to navigate through this associations ? Maybe it is worth opening a new question. – Tilman Zuckmantel Nov 04 '20 at 17:36
  • 1
    @TilmanZuckmantel I am not sure to understand you, as me you do `xx.stereotype` to access the stereotype of *xx*, and that way is also used 4 times in [Object Constraint Language formal/2014-02-03](http://www.omg.org/spec/OCL/2.4) for instance §12.5.1 – bruno Nov 04 '20 at 17:47
  • 1
    @TilmanZuckmantel I also got the way to compute the set comprising a stereotype and all its generalizations from the definition given at the top of the page 32 of the same document (in case you have a doubt on that way) – bruno Nov 04 '20 at 17:51
  • The ocl specification itself might do it, but unfortunately it fails to define this mechanism. And in reality it can't work. Every element can have multiple applied stereotypes. So, what is the meaning of self.stereotype? It would be a set of stereotypes. Then self.stereotype.name="Car" could not be evaluated, because the types of the elements on both sides are not compatible. So I guess, the only way is to go through extension end (which has its own problems) - or some tool specific enhancements. – Axel Scheithauer Nov 09 '20 at 19:17
  • Finding all generalizations of a stereotype is not necessary. Since the constraint is inherited, it applies to all specializations. Just delete the first line `self.stereotype.name="Car"` if you don't want to limit it to "Car". – Axel Scheithauer Nov 09 '20 at 19:22
  • @AxelScheithauer when I see OP code I had the same thinking about the unique/multiple stereotype and I check in the OCL formal to know if the *stereotype* is a collection and found for instance `self.constraint.stereotype.name = ‘definition’`. So the norm says *explicitly* `xx.stereotype.name="yy" ` is right – bruno Nov 09 '20 at 19:29
  • @AxelScheithauer about your second remark you forgot the scope : `Context UML::Core::Class` and the goal is to apply the constraint about *attrA* and *attrB* **only** to classes stereotyped by something inheriting *Car* => `self.stereotype.name="Car"` must be done – bruno Nov 09 '20 at 19:33
  • @bruno Well, the ocl specification has many holes. If a Constraint had an attribute `stereotype`, I would expect to find a definition of this attribute, not just a usage example. And the multiplicity of applied stereotypes makes it impossible to work. It this working in your ocl-tool? How? – Axel Scheithauer Nov 09 '20 at 21:05
  • @AxelScheithauer I do not have own OCL tool. I did as I could from the UML OCL standard. – bruno Nov 09 '20 at 21:21
  • @bruno You are right, I forgot the context. However, a Metaclass cannot be the context of a Constraint, since the context must own the Constraint. So, I assumed that Stereotype «Car» was the context. In this case, it applies to all applications of this Stereotype and its specializations. There is no need to check for the stereotype, except when you want to treat specializations differently. – Axel Scheithauer Nov 09 '20 at 21:21
  • @AxelScheithauer in my first comment to this responsei thought about referencing the stereotypes by the extension association of the Classifier Class. One can see this in Chp 12.3.2 of the 2.5 UML Ref. Just use the link above. Here one would get a collection of extensions. I want to differentiate between the specialization since i want all classes to have the same tagged values, but different constraints on them. Besides, this multicited paper uses the context just like i did: [UML Profiles](https://www.researchgate.net/publication/245346983_An_introduction_to_UML_profiles) – Tilman Zuckmantel Nov 18 '20 at 13:30
3

If you think about it, what you ask is unreasonable.

Suppose your system already has the over-enthusiastic constraint that a Car's FuelType is PETROL. You are in big trouble trying to define a derived Car whose FuelType is DIESEL; it would not be a Car wrt to the modelled definition of Car.

You could try to workaround the problem with mixins, but the number of permutations would be intolerable for any practical production Car.

Instead you can take the approach of loopholes adopted by the UML specification exemplified by the Namespace.isDistinguishable helper that determines whether unique names are required or not (multiple unnamed Constraints are permitted).

Therefore for Car you could define the getAcceptableFuelTypes() helper that can be overridden to create a loophole for derived classes; implement your base constraint as getAcceptableFuelTypes()->includes(fuelType).

Ed Willink
  • 1,205
  • 7
  • 8
  • I'm confused. Your answer seems to suggest, that FuelType could be a meaningful Stereotype Attribute. A Stereotype defines a language concept, like Class and Association. While I might speak of some Class beeing the Mercedes of the Classes in my model, I wonder what it would mean to say that its FuelType is PETROL? An instance of a Stereotype is still a model element (on m1) and not a Car (on m0). – Axel Scheithauer Nov 09 '20 at 21:38