Incomplete Static Models
- 1 Introduction
- 2 Rationale
- 3 Maximum and Minimum Models
- 4 Incomplete Classes
- 5 Methodology consequences
- 6 Examples
- 7 Further Discussion
In order to use static models for templates, we need to be able to have incomplete static models. An incomplete static model is a model that leaves some content open.
Usually a static model is complete - any content not described by the model is disallowed. For normal static models - D-MIMs, R-MIMs, CMETs - this makes complete sense. But when it comes to templates, such completeness is often not appropriate.
A typical case is the use case for a template that says that this observation must have a snomed code associated with it. A simple static model would therefore have a single Act Class, with classCode <= OBS, and a constraint on the code to say that there must be a term from snomed.
(It's not the focus of this page, but assuming that the oid for the snomed code system is [snomed_oid], then the constraint might look something like this in OCL:
This fragment depends on some decorations on CD, but that's not what this page is about)
The problem with the simple static model described above is that it says that the observation cannot have anything else on it - only a classCode and a code, and no associations. Not very useful.
An alternative is to add every attribute, and also to add every possible association. This includes all the classes that might be encountered, including at the very least the entire RIM backbone - but this is all getting very difficult. At the least we can say that the conceptual problems this brings up can be ignored since no one would ever bother writing such a template for a simple statement.
The solution to this is to allow a static model to say something, and refrain from making rules about some content. This is known as an incomplete static model.
Maximum and Minimum Models
The first option that we (LM,GG) considered was maximum and minimum models. This is a concept that is used with stubs to describe what possible models can be bound to the stub. The model that is bound must be between the two models, minimum and maximum.
This concept works when a model is compared to minimum and maximum models (at least for some usages), but doesn't work with instances. It's relatively easy to figure out how cardinality works with minimum and maximum models, but fixed values is a problem. If you tried to capture the case above using a min/max approach, it turns out the min model is irrelevant, and the max model must make the rule - and it turns out to be the same model as the full model with the backbone etc above.
So this is not useful.
A workable approach is to add a flag to classes in static models. The flag on the class is called "incomplete". If this is flag is set, then any attributes and associations that are not mentioned are not constrained in any fashion. Any attributes or associations that are defined carry the normal meaning.
The default value for the flag is false - classes are always complete by default.
This flag can only be set to true in a LIM. If a model is to be used as a CMET, Message, Document etc, then the flag must be false. (All sorts of problems if you tried to allow incompleteness in these kinds of artifacts).
To prohibit an attribute in an incomplete class, set the cardinality to [0..0]? You cannot prohibit an attribute if it is mandatory in the model from which this is derived, of course.
Like attributes, associations are prohibited by setting the cardinality to [0..0]. Since associations are not distinguished by name, but by their data content (at least not when used as templates), what is prohibited is the existence of any association that meets the criteria specified by the constraints on the class that the association points to.
- Derivation - [no consistent existing understanding or definition]
- Constraint/Extension - models may be constraints or extensions of other models. (models may also be incompatible)
- Templates may be derived from a particular model, and may be related to other models as identical, constraints, extensions, or incompatible
- Incomplete templates are always *derived* from the RIM and are also always constraints on the RIM.
- A model may be applied as a template on another model if it is either a constraint or an extension (or, most usefully, both) but not if it is incompatible.
- Only LIMs are allowed to contain incomplete classes (for now).
- Incomplete templates cannot be used as expressed models
[Note that there is an pending outstanding hot topic that Lloyd will create that will further discuss the relationship between derivation, constraint and extension, but for now these rules are adopted in the interim period)
The flag will be shown on the model as a ? (bright purple border? snazzy picture?)
The flag will be shown as the text "Incomplete" in italics and bold in the table views.
The flag will be stored in the MIF as a boolean attribute with a default value of false on the Class type.
In order to fully support this model, the following things are needed in the various tooling
Static Model Designer
- support for a "model is extension" flag - setting, storing and displaying
- support for a "class is incomplete" flag - setting, storing and displaying
- support for entry points on any class
- MIF validation routines that know about these new rules
- template validation that understands incompleteness.
Ideally the visio tooling could be extended to at the very least have rudimentary support for the two flags. This would allow us to start exploring how these new template features allow us to capture the existing CDA templates as static models.
Use snomed codes
This example is based on the use case discussed in the introduction to this document. Making this into a template:
- define a static model with a single class.
- Set the incomplete flag to true
- set the classCode <= OBS
- add the snomed constraint from above (inv: code->hasCodeSystem([snomed_oid]))
- leave all the other attributes off.
This was presented in MnM Wed Q3 May 2007. There was strong pushback to the idea of using models for extension, but there was general agreement on the need for incomplete classes in templates and entry points on any classes. A motion was passed on this point
(Grahame to get this out of MnM minutes once they are posted--GrahameGrieve 11:12, 3 May 2007 (CDT))
There was much discussion concerning the difference between models and delta models, and applying templates as models without considering their derivation heirarchy. This was not conclusive.
This leaves Lloyd and Grahame to work on the methodological approach that supports the desired outcome.
Keith is writing a document on the subject of mathematical operations on models as sets. This may assist in the further development of the subject. Grahame to link here -> <- when Keith posts the document to the wiki.
The question for discussion is whether we can say what needs to be said for incomplete models.
Take, as an example, the following cases from CCD:
- (220.127.116.11.2): A policy Act
- SHALL contain exactly one Act / performer [@typeCode=”PRF”]
- SHALL contain exactly one Act / participant [@typeCode=”COV”]
- MAY contain exactly one Act / participant [@typeCode=”HLD”]
In a complete model, we can say this no problems. But in an incomplete model, how does this work. The issue arises with the last one - we say that this *might* exist, and if it does, it has the following properties. ok, but we also say - being an incomplete model - that anything else might exist. So if two participations exist with typeCode "HLD", is the second legal or not? In the case of that particular CCD example, the answer is probably no - that it shouldn't exist.
So that probably works ok.
But what if the intent was that the policy Act
- MAY contain an Act / participant [@typeCode=”HLD”] with an role code of "XXX"
How do you differentiate, in an incomplete model, between saying (1) that there can be 0..1 participations with a type code of HLD, and these have to have a role code of XXX, and (2) there can be any number of participations, but that there could be one with a type code of HLD and a role code of XXX, and *if there is*, then the following rules apply.... (insert rules of choice here)
A corollary: if HLD had a specialization called "PHLD" (primary holder (I should have picked a better example ;-)). Does the rule "MAY contain exactly one Act / participant [@typeCode=”HLD”]" include PHLD too? Kneejerk reaction: depends whether the model is = "HLD" or <= "HLD". But in the case of ="HLD" does that mean, this excludes "PHLD" from being in the model, or that it doesn't make a rule about whether "PHLD" is in the model
An aside that arose from looking through CCD:
CONF-123: CCD SHOULD contain exactly one and SHALL NOT contain more than one Functional status section (templateId 2.16.840.1.113818.104.22.168.5).
This constraint is ambiguous - do we only make a rule here about the presence of a section with the appropriate templateId, or do we also make a rule about the number of sections with loinc code 47420-5 (see CONF-125).
- you can't make a rule about template id in UV Visio at this time....
- again, how do you differentiate between conditions and rules - is the code being fixed conditional on the template id or absolute (same issue as above)
CONF-189: The family history section SHALL NOT contain Section / subject.
Another CCD issue. You can't contain a subject - but can you contain a Participation with typeCode = SBJ? This is potentially a mistake in CCD - or not? Let's *assume* that it's not - this is a variation of the first case - you can't have a subject that conforms to these rules and claims to be a primary subject, but you could have a subject...
or maybe not. Guess we'll write that off as a mistake in CCD caused by ambiguity in CDA....?
The issue arises with collections, effectively: how do we differentiate between the constraints that establish a rule for the context, and the ones that establish the context for the rule. Such a dichotomy doesn't arise in complete models. The examples here are all focused on associations, but that's only because we don't do constraints inside data types. If we did, then such issues would arise. And the probably could if we wanted to start making rules about multiple types of data type flavors in, say, a list of names
To identify associations to a type of class as "not permitted", use the conformance property and set it to "NP". If the classes referenced are "closed", this will only prevent a reference to a class that looks exactly like the specified class. However, if the classes are "open", it will prevent a reference to a class that looks anything like the "not permitted" classes.
To convey a requirement of "exactly one", a model needs to do two things: Convey that one must be present, and convey that others must not be present. This is done through a "max 1" cardinality "required" association to a class with the desired characteristics to be present and a "max *" cardinality "not permitted" association with the characteristics desired to be present only once.
This solution will require exposing "not permitted" within the tool.
Motion: Lorrain/Rene (3/0/1) Incorporate documentation of the above in the "advanced" section of Core Principles and provide the requirement to the Tooling Committee that declaration of "Not Permitted" be allowed as a conformance, at least for attributes and associations from classes marked as "Open".