Aql: clarify types supported by relational operators

I think to have a good solution in the spec, we need to go back to the core of this issue: comparing primitive/assumed types.

IMO we need to revisit this model [1]:

[1] https://specifications.openehr.org/releases/BASE/latest/foundation_types.html#_overview_2

Some comments:

  1. Any has an is_equal() method, should we say exactly what “is equal” for each type?
  2. In the UML, the methods of Any don’t appear.
  3. Most operators are defined with the keyword “infix”, I don’t think that is valid UML.
  4. All operators defined as “infix” could be defined as a normal method in the UML.
  5. Then if some implementation needs to map those methods to an infix operator, it could be done, but not all implementations need that.
  6. Seems all Numeric classes are Ordered, so why not inherit Numeric from Ordered instead of having the Ordered_Numeric class?
  7. Ordered seems to be more an interface than an abstract class, since it only has a method.
  8. Numeric seems also to be more an interface than a class.
  9. Ordered has the lowerThan() defined as “infix <”, I think we need to define how that works for all the ordered types.

With this considered, mainly points 1. and 9. we would have a good base to define is_equals() and lower_than() for other types, like “numeric DVs”.

In theory we should do that.

In that particular view, they don’t, but they are visible here.

It isn’t, that is some old text I should fix that was imported from the manual diagrams. The methods should be defined with proper names like less_than(), is_equal() etc. UML doesn’t have meta-model to include operator aliases, so I’ll need to find another way to put them in.

We could do that. I followed (probably 15y ago) the type design of the Eiffel libraries which happened to have them separate (back then most other languages had not sorted out basic types beyond things like int, long, etc). These types aren’t implemented of course, they just enabled the assumed semantics of the assumed primitive types to be formalised.

These classes are defined as abstract classes rather than interfaces because they theoretically provide implementation of the relevant routines, they just aren’t directly instantiable. An ‘interface’ is strictly no implementation. Again, these distinctions are not that important in this part of the model.

Point 9 is also correct, and I can easily build a revised version of this model with the appropriate cleaning up.

The other option is to say “we delegate this logic to any programming language used as implementation technology”, but if we go that way, different languages might have a different criteria for = and < I would prefer to spend some time defining all the basic semantics inside the spec to give a solid semantic base to the rest of the RM. That way we avoid leaving things open to interpretation at this base level.

Thinking of is_equal or lower_than, I think an abstract class can’t provide the implementation because that will depend on the specific type, that is why I mentioned the interface thing.

The way the functions less_than(), greater_than(), less_than_or_equal() and greater_than_or_equal() work is that you leave less_than() abstract, and define it in concrete descendants, but the other 3 you can implement in the abstract class, and they will work correctly in all the others. Although in today’s languages I guess you will be forced to manually rewrite the signatures because you don’t have anchored types (‘like T’, including ‘like self’), but nevertheless, the implems from Any will still be correct.

Also, there is no in-principal reason why a class like Any or any other abstract class should not contain implementation, whereas an ‘interface’ class is in principle just that.

I have only used UML interfaces in the UML to indicate service interfaces, i.e. APIs, mainly in the abstract platform service spec.