Most of us had the same problem. Have a look at the first post again, Ian’s bit on Fabio’s problem in the tooling.
So a little bit of clarity + coffee for me this morning made me realise the following: if you have an RM class (eg. DV_TEXT) that can itself be concretely instantiated and also has a concretely instantiable child(ren) (e.g. DV_CODED_TEXT), to enable a constraint to enforce the runtime instance to conform to the parent class, we need an ability to constrain a node to an instance of ‘just this class’, i.e. no child class instances.
This is a generic OO model property, it’s not specific to openEHR in any way, as all the devs/tech people here will know perfectly well (i.e. the fact that you can easily have instantiable parent classes, not only abstract ones up the inheritance hierarchy).
To fix this, we need an additional constrainer flag on C_OBJECT in the AOM, something like ‘rm_type_fixed’. Now, that is more or less the ‘final’ keyword that @sebastian.iancu was suggesting, and I think someone suggested ‘frozen’ as well. @Seref and I were against this, but I now think the variant I am talking about i.e. ‘rm type fixed’ is needed - maybe ‘rm type frozen’ or ‘rm type final’ are better names (I would agree).
However… this doesn’t fix everything… see @pieterbos’s post (#16) above - you could still add another alternative, i.e. by this:
value matches {
DV_PLAIN_TEXT[id5] occurrences matches {0}
DV_CODED_TEXT[id4] occurrences matches {0}
DV_CODED_TEXT[id0.2]
}
We have another need: to be able to prevent the addition of any more ‘alternatives’ (single-valued attribute) or other children (container attribute). We do have this on ARCHETYPE_SLOT already, it’s called is_closed
, i.e. closed to more ‘filling’.
I think we need this kind of idea but on C_ATTRIBUTE. That would prevent the situation Pieter was talking about.
However, we are not done yet! @pieterbos thought of another case related to this, see SPECAM-59. The idea here is to prohibit instances of some specific RM type while allowing others. I don’t think this applies to our current case, since we don’t want to prevent instances of DV_CODED_TEXT, we want to prevent new constraints for that type, subverting the existing constraint. I just mention this here for completeness, in case anyone thinks it does apply.
So, I think to achieve everything @ian.mcnicoll and the clinical modellers want, we need to be able to write the following:
value closed matches {
DV_CODED_TEXT[id4] matches {<value set with or without bindings>}
DV_TEXT[id5] rm_type_final matches {<e.g. max 100 chars>}
}
Those two keywords ‘closed’ and ‘rm_type_final’ achieve what we need:
- no new alternative constraints e.g. in the template (or a child template) that could subvert the 2 constraints we have
- no redefining of the DV_TEXT into DV_CODED_TEXT.
I think this gets us out of needed any DV_PLAIN_TEXT. In any case, the above AOM capabilities can be justified with respect to any OO RM, so I think we should add them. If we still want DV_PLAIN_TEXT later, that will be another matter.
Obviously how we make this ‘easy to understand’ on a tool UI is a question for tool designers.
SEC: see if you can break this analysis; would be good if we can get @borut.fabjan to have a look as well.