OCL 2.1 RTF Avatar
  1. OMG Issue

OCL21 — Dynamic typing with allInstances()

  • Key: OCL21-292
  • Legacy Issue Number: 11097
  • Status: closed  
  • Source: Dassault Systemes ( Mr. Tomas Juknevicius)
  • Summary:

    I have an issue with OclAny::allInstances() method, as described in the
    11.2.5 section of the OCL2 spec (06-05-01.pdf).

    If I understand correctly, OCL is a statically typed language (e.g. as stated
    in the beginning of 8.2 section or 8.3 section OclExpression paragraph).
    Every expression has a type and this type can be statically determined by
    analyzing the expression and its context.

    Most of the concepts in the OCL spec follows this rule, however I have
    an issue with the allInstances() method, defined on OclAny. Specifically,
    the "Returns all instances of self. Type T is equal to self." statement is problematic.

    When allInstances is used on the literal type specifier, there is no problem.
    E.g.

    context classFoo inv:
    somepackage::classBar.allInstances()->size() < self.limit

    Here, return type of the expression "somepackage::classBar.allInstances()" can be determined
    by static analysis ("at compile time") - it is Set(classBar).

    However when allInstances is invoked on variable, calculated by some expression,
    and all the staticallity of OCL crumbles and the hell breaks loose .
    And there are no restrictions, on what objects allInstances() can be invoked, the only rules are
    that the object to be classifier and the instance set be finite.

    E.g.
    (singleton rule - all the classes must have at most 1 instance)
    context Class inv:
    self.allInstances()->size() <= 1

    Now, what is the type of the self.allInstances() expression? Well, it depends on what is the self object -
    and self object is supplied at run time. If we evaluate this constraint on classFoo,
    we see that type of "self.allInstances()" must be Set(classFoo), if we evaluate this constraint on
    classBar, type of expression must be Set(classBar). Hence the type of expression can not be determined
    at "compile time", it must be determined at "run time".

    E.g. we have 2 classes classFoo and classBar; classFoo has a field someField, classBar doesn't.

    context whatever inv:
    let s:Set(Classifier) = Set

    {classFoo, classBar} in
    s->allInstances()>any(true)>any(true).someField = someValue


    Now what is the type of s->allInstances()>any(true)>any(true) expression?
    We have:
    expression |expression type |expression value
    ---------------------------------------------------------------------------------
    s |Set(Classifier) |Set{classFoo, classBar}

    s->allInstances() |Set(Set(???)) |Set

    { Set_of_instances_of_classFoo, Set_of_instances_of_classBar}

    s->allInstances()->any(true) |Set(???) |either Set_of_instances_of_classFoo or Set_of_instances_of_classBar
    s->allInstances()>any(true)>any(true) |???? |either instance of classFoo or instance of classBar

    Now the question arises: can we access someField property?
    Here we must have a runtime introspection check in the OCL evaluation code -
    if s->allInstances()>any(true)>any(true) returned instance of classFoo,
    we can access the field, if instance of classBar - we must runtime-fail here.

    Please advise. Is this a problem of the spec or I am wrong somewhere?

    Granted, we are making jumps 2 levels down in metamodel hierarchy here
    (first from metamodel to model elements-classes, then from classes to instances of those classes),
    but there is nothing in the spec, what precludes this.

  • Reported: OCL 2.0 — Mon, 11 Jun 2007 04:00 GMT
  • Disposition: Resolved — OCL 2.1
  • Disposition Summary:

    No Data Available

  • Updated: Fri, 6 Mar 2015 20:58 GMT