This wiki has undergone a migration to Confluence found Here

Datatypes R2 Issue 2

From HL7Wiki
Jump to navigation Jump to search

Data Types Issue 2: Add DRVQ mixin for Quantity

How does this relate with PQXF An extended form of the PQ data type for simple factors.? The latter was a harmonization proposal that passed. (Raising this doesn't mean I am against this one, just want it to be noted.) Gschadow 21:39, 11 January 2007 (CST)

Analysis

based on the skype thread after the old analysis

  • create EXP
  • can be evaluated anytime. must be safe to evaluate
  • define language
  • languages must be formally described by HL7 or an affiliate, and registered with INM
  • the PQXF proposal is a particular language for EXPR. We define in in the specification as an example for other definitions.

Old Analysis

This predated the skype thread below.

Grahame:

So, let's asusume that we have just one thing for both these proposals, and let's assume that we call it EXPR instead of DRVQ or PQXF. We may change our minds if it get's too complex, but, well, let' s try for both.

So, let's assume this as a definition:

template<QTY T>
type Expression<T> alias EXPR<T> specializes T {
  ED  expression;
  CS  language;
  CS  mood;
};

mood: below, Lloyd proposes that the expression may define how the value was calculated, or how it can be calculated. Since it may be ambiguous whether to evaluate the expression at any time, it might be safer to indicate the intention of providing the expression. Possible values:

  • UseExpressionAlways
  • UseExpressionIfVariablesAvailable (i.e. there is also a default value provided)
  • ExpressionForReferenceOnly

language: we have discussed before that you could infer language from mediatype, rather than coding it. Maybe this is possible, and maybe it's an ITS issue. The issues I see with it are that the mediatype is orthogonal to language. text/plain is perfectly suitable for OCL, for instance. And what would you do to fix the the language to OCL? would you have to allow for XMI, to allow OCL? I think it would be better to define language as a primary property of EXPR, but then in the ITS or notes provide some informative mappings to mediaTypes. Alternatively, we could leave it up to the ITS to decide whether to use mediatype as a primary, and make language a derived property. But if language is a CS, is it extensible? what are the extensibility rules?

expression: the direct expression. Obviously ED allows for reference, and that's good. We could invest in banning properties such as translation - but then again, maybe not. Does schematron count as a translation of OCL in terms of ED.translation? depends on the rules of that, which are still open. Expression can't be mandatory, because the model must allow EXPR<T> in case an expression is required.

other issues:

conformance - does the expression change null rules? The answer at the abstract level has to be no - if an expression is provided and the null rules are not met - or maybe whenever relevant, or maybe as guided by moodCode - the expression must be evaluated when evaluating some or all of the properties.

the main question is, how does this work. With what we have described, we could stop there, and say that we have provided the information structures required to make it work. But what we haven't done is explained how it actually works. For each language, we need to define:

  • how does the language address information from the context. (this is going to be language and ITS dependent)
  • how does the expression derive the value - all values are complex types (at least from the perspective of any language that is not wholly centered on the RIM and V3 datatypes). So how does the language derive a value for nullFlavor, for instance?

So, there is some problems there. We can duck our heads on this, but we couldn't claim that this is serving interoperability.

Finally, which languages do we support? It seems to me that the PQXF proposal is effectively an EXPR with a defined language, and this has the appeal of simplicity and is pretty much ITS independent. So I would propose that we define this language directly as a supported language in EXPR.

other languages we have considered:

  • OCL
  • MathML
  • Xpath
  • Gunther and Grahame's smost excellent HPath syntax

Introduction

Add a mixin that allows internal representation of the derivation of the value for a Quantity. The current approach of using derivationExpression requires implementers to look in two different places for the value of an attribute. It is also complex using derivationExpression to express the values of datatype properties.


Backward compatible: We will need to transition from any existing use of derivationExpression. In practice it has been used minimally if at all.

Pharmacy, Orders & Observations


Discussion

Added under Generic Type Extensions: Derived Quantity (DRVQ) specializes T

Definition: A generic data type extension that tags a derivation expression to any quantity datatype or datatype property. The expression provides a formula for how the value of the quantity was or is to be derived based on other parameters conveyed within the instance.

Definition xxx:

template<QUANTITY T>
type DerivedQuantity<T> alias CALC<T> specializes T {
   ST derivationExpression;
};
      

Derivation Expression (derivationExpression : ST)

Definition: The formula by which the value property of the type has been calculated or is to be calculated. <We need to decide what the language for derivationExpression should be>


XML Representation

 <gsd:templatename="DRVQ">
   <gsd:paramname="T" type="QUANTITY" />
   <xsd:complexType>
       <xsd:complexContent>
           <xsd:extension>
               <gsd:attributename="base" type="T" />
               <xsd:sequence>
                   <xsd:elementname="derivationExpression" ... />
               </xsd:sequence>
           </xsd:extension>
       </xsd:complexContent>
   </xsd:complexType>
 </gsd:template> 
   

Derivation Expression: ST

 <xsd:elementname="derivationExpression" minOccurs="0" maxOccurs="1" type=”ST”/>


We need to be able to “cascade” this to properties inside a type. For example, if I have a datatype of DRVQ<GTS>, that should mean I have derivationExpression available for each of the quantity properties inside the GTS. For example if the GTS is implemented via the intersection of IVL<TS> and PIVL, I should be able to put a derivation expression on the lower bound and width of the interval and the frequency of the PIVL.

No clue how best to handle this in UML though. Althernative is to put DRVQ into all internal datatype properties or to create DRVQ variants of all the datatypes with the necessary changes to the properties.

This may be freely used in Observation.value. Anywhere else it is required will necessitate a RIM change. Specific places where it will need to be introduced include:

  • SubstanceAdministration.doseQuantity URG<DRVQ<PQ>>
  • SubstanceAdministration.rateQuantity URG<DRVQ<RTO<PQ>>>
  • SubstanceAdministration.maxDoseQuantity URG<DRVQ<RTO<PQ>>>
  • Act.effectiveTime DRVQ<GTS>

Gunther and Grahame discussed this at Orlando. For exactly the same grounds as above, We were going to propose this mixin:

 type EXPR<T>  extends T {
   ED expression; 
   CS expressionLanguage; 
 }

Drop expressionLanguage. Describe supported Mime Types, general language binding information + possibly specific language information. No side effects

ExpressionLanguage would a controlled CS. Valid values we propose as a start are OCL and MathML.

Here’s an example syntax:

 <doseQty expr="250 mg/kg * $bodymass"/> 
 <substanceAdministration> 
   <doseQty xsi:type="EXPT_PQ" value="250" unit="mg/kg" exprLang="mathml"> 
     <expression mediaType="text/xml"> 
       <times ref="$bodymass"/> 
     </expression> 
   </doseQty> 
   <inputParameter> 
     <localVariableName>bodymass</localVariableName> 
     <subset code="MOST_RECENT"> 
     <observation moodCode="DEF"> 
        
     </observation> 
   </inputParamter> 
 </substanceAdministration>

Lloyd: I'm comfortable with this approach, but am not clear how it manages the cascading issue. If I define EXPR<GTS>, how does that propagate to the IVL<TS> or PIVL<TS>, etc. that make up the GTS instance?

Disposition

Status

Proposed

Links

Back to Data Types R2 issues


Skype thread

[9:44:28 AM] Grahame Grieve says: has anyone looked at the EXPR wiki page (proposal 2: http://informatics.mayo.edu/wiki/index.php/Datatypes_R2_Issue_2) [9:57:39 AM] Gunther Schadow says: Right now it does not seem to have converged to one proposal. [9:58:25 AM] Gunther Schadow says: I think the best would be a mixin where the expression can be an ST based syntax or an XML thing that just merges in by change of namespace (e.g., MathML). [9:58:37 AM] Grahame Grieve says: well, I thought that I could get it down to one proposal that covered all use cases. but there's multiple axes here. [9:58:47 AM] Grahame Grieve says: well, that's the one thing there seems to be agreement on [9:58:49 AM] Grahame Grieve says: but [9:58:57 AM] Grahame Grieve says: two questions for now: [9:59:15 AM] Grahame Grieve says: Lloyd proposes that the expression could record how the value was arrived at, or how to arrive at the value [9:59:36 AM] Grahame Grieve says: if this is the case, how do you know when to use the expression to get the value, and when you don't need to. [9:59:53 AM] Grahame Grieve says: or do we even care? I'd rather not carry the "this is how the value was arrived at case" [10:00:22 AM] Grahame Grieve says: second question - do we describe the language binding, or just ignore that, and assume that it will be taken up elsewhere, for each language. [10:00:26 AM] Grahame Grieve says: and two more questions [10:00:36 AM] Grahame Grieve says: do we delegate language to mediatype? [10:00:38 AM] Grahame Grieve says: and [10:00:52 AM] Gunther Schadow says: I don't like the word "mood" for this property that says how it is meant to be used. I think we need to learn from spreadsheets here. Whether to recompute the expression or use the stored value is up to the receiver. Clearly what is being sent to you is the value (if it, in fact, had been provided) so, re-evaluating the expression is at your own risk. I don't think a controlling attribute is needed at all. [10:01:14 AM] Grahame Grieve says: mood was to get your attention ;) [10:02:16 AM] Grahame Grieve says: actually, there was only 3 questions [10:03:21 AM] Grahame Grieve says: I'm not sure that spreadsheets is the right metaphor. The spreadsheet keeps track of dependencies in a forward manner, and automatically updates the value based on the formula [10:03:32 AM] Gunther Schadow says: I think we need to say something about the binding to the language to expose the overall issue. Clearly we must talk about accessing properties from this and neighboring objects and how higher level variables get bound into the evaluation scope (i.e.., the ActRelationship.localVariableName). You can say that for OCL (thus rendering this GELLO thing obsolete :) or we can describe it along the HPath line. We can also mumble about JScript or Java just to show people what could be done. [10:04:35 AM] Grahame Grieve says: my preferred solution is to lock this down. The only languages supported are the ones that we describe, used how we describe. If you have a good use case, you can get it into the spec. Otherwise, there'll be chaos. [10:05:10 AM] Gunther Schadow says: The spreadsheet may do that, but so would any reasonable general implementation of these formulas. You have to push from the other end of the dependency or else you can't make these things efficient. But even so, you can turn off the auto-update function of your spreadsheet program and have it wait until you press CTRL-R to recompute. [10:05:15 AM] Grahame Grieve says: the same for when to evaluate. It has to be clear. So my preferred solution is that if an expression is provided, it is to be used everytime any property is accessed [10:05:51 AM] Gunther Schadow says: Disagree. [10:05:57 AM] Grahame Grieve says: I mentioned the idea of a default value + mood in the wiki, but I don't like that idea. [10:06:05 AM] Grahame Grieve says: what do you disagree about? [10:06:10 AM] Gunther Schadow says: The other way: if value is provided, the expression is FYI only. [10:06:21 AM] Gunther Schadow says: If no value provided, you need to evaluate (if you can). [10:06:51 AM] Gunther Schadow says: About the supported languages I think we can be enabling without being restrictive. [10:07:08 AM] Gunther Schadow says: This is a great opportunity to have extensible plug and play interoperability. [10:07:19 AM] Grahame Grieve says: no I am afraid [10:07:22 AM] Grahame Grieve says: now I am afraid [10:07:42 AM] Gunther Schadow says: If the framework is right, then I can process your Java expressions just as long as you give me the code to evaluate them. Same with OCL or HPath. [10:07:59 AM] Gunther Schadow says: My concern is that the right expression language cannot be decided by committee. [10:08:32 AM] Grahame Grieve says: " if value is provided, the expression is FYI only". well, how do we express this in the abstract? does that mean that the value is a nullFlavor until evaluated? So we would need a special nullFlavor for evaluateMe? [10:08:43 AM] Lee Coller says: At some point we (being HL7 or affiliates) need to decide on the expression language(s). From a datatypes perspective I agree with Gunther that we can be enabling. [10:09:11 AM] Gunther Schadow says: I don't like OCL, think that JScript would be better. Of course I like HPath but without it having a status it will not be allowed. I think it's important to allow Arden Syntax. But how exactly that is done needs to be described in separate documents. [10:09:54 AM] Grahame Grieve says: so, we define what you need to do to make a language work, and leave it to others to publish those languages, and maybe publish something real simple to cover the PQXF use case ourselves? or do we leave that to pharmacy? [10:10:29 AM] Gunther Schadow says: Cool, yes, we publish the PQXF ourselves. [10:11:06 AM] Grahame Grieve says: ok, we'll write that up separately. For ballot this cycle? or does it stay informative? [10:12:10 AM] Gunther Schadow says: "" if value is provided, the expression is FYI only". well, how do we express this in the abstract? " --We have to say that the value of the expression can be fixed and if that is so, it will preempt the result of re-evaluation. The issue with reevaluation is that next time you evaluate you may not get the same result. So it's important to fix that value. [10:12:44 AM] Grahame Grieve says: so this is a property of the expression itself? [10:12:50 AM] Gunther Schadow says: PQXF can be put inline so that the description of what's involved for language binding becomes illustrated. [10:12:59 AM] Gunther Schadow says: What's a property? [10:14:22 AM] Grahame Grieve says: not sure. I'm having a problem visualising the exact abstract declaration of the expr thing, because as a mixin it can only adorn a thing. So if we take an EXPR<PQ>, as the most common case, in the xml, there would be no value attribute, there would be an expression element. That's pretty obvious. [10:15:14 AM] Grahame Grieve says: but in the abstract, what is this? PQ has either a value or it's null. we don't have the language to express the concept of a PQ that doesn't have a value until you evaluate and expression in a mixin [10:15:32 AM] Gunther Schadow says: We can do it this way: defined an operation EXPR<T> evaluate() which returns another instance of the same data type. The result of that evaluation is like ther original expression just with the newly computed value bound. So, if you ask for expr.value() you always get the result of the last evaluation. And when you say expr.evaluate() you get a new EXPR with the new value. [10:16:09 AM] Gunther Schadow says: An expression that has never been evaluated (has no value) is null until it is evaluated. [10:16:23 AM] Grahame Grieve says: state? we don't have state like this anywhere else [10:16:30 AM] Gunther Schadow says: Not state. [10:16:37 AM] Gunther Schadow says: Each time you evaluate you get a new thing. [10:16:47 AM] Grahame Grieve says: yes, but value() is stateful [10:17:01 AM] Gunther Schadow says: No it's frozen every time. [10:17:14 AM] Grahame Grieve says: since last time - that's stateful [10:17:15 AM] Gunther Schadow says: Only evaluate() may yield different values. [10:17:39 AM] Gunther Schadow says: No, one value stays the same. Evaluate does not bind the new computation to the original attribute. [10:18:44 AM] Grahame Grieve says: ok, so x : EXPR<PQ> what is the relationship between x and x.value()? are they the same thing? [10:19:05 AM] Grahame Grieve says: x.evaluate() is obviously something different [10:19:34 AM] Gunther Schadow says: If I say PQ bmi = thisBMIObservation.value I get whatever the BMI value was assigned to thisBMIObservation. But if I call PQ bmi2 = thisBMIObservation.value.evaluate I may get a different one, but thisBMIObservation is unchanged. [10:19:43 AM] Lee Coller says: So, if presumably we follow the same rules with the EXPR mixin as the others, it can only be enabled by committee, thus a model would have a PQ constrainted to EXPR<PQ>. If an EXPR<PQ> doesn't have a value, its null, so therefore it can't be mandatory in the model, In fact, it is always null. Now if I understood what Grahame said above ". So if we take an EXPR<PQ>, as the most common case, in the xml, there would be no value attribute, there would be an expression element." We would have an element in an instance that by definition would always be null, but would always have a computable value. [10:20:06 AM] Lee Coller says: That's broken, at least it hurts when I try and think about it. Maybe I'm just too simple [10:20:37 AM] Grahame Grieve says: Lee, it it hurts you, it is too complex by far, because then no one off this list will ever get it. but I think it's not as bad as it sounds at this time [10:21:14 AM] Grahame Grieve says: Actually, Gunther, I agree, but I believe that this solution excludes Lloyds "this is the formula that was used to derive this value, don't use it yourself" use case [10:21:15 AM] Gunther Schadow says: ok, so x : EXPR<PQ> what is the relationship between x and x.value()? are they the same thing? -- how 'bout this:

type EXPR<T> specializes T {

 T value;
 EXPR<T> evaluate(EvaluationCointext);

} [10:21:40 AM] Grahame Grieve says: so, not a mixin anymore? [10:22:03 AM] Grahame Grieve says: I think that it's a lot cleaner as not a mixin, because it has more control over it's own destiny, as it were. [10:22:20 AM] Gunther Schadow says: Just seeing it, value is unnecessary. [10:22:43 AM] Gunther Schadow says: Yes mixin. And it never changes. Only evaluate lets you recompute. [10:22:57 AM] Gunther Schadow says: But then you get a different one of those. [10:23:14 AM] Lee Coller says: Why is it EXPR<T> evaluate(EvaluationContext) not T evaluate(...)? [10:23:32 AM] Grahame Grieve says: I agree with Lee. But just to be clear: we are excluding Lloyd's use case? [10:23:49 AM] Gunther Schadow says: "Actually, Gunther, I agree, but I believe that this solution excludes Lloyds "this is the formula that was used to derive this value, don't use it yourself" use case" -- no it won't because the value you submit will not change. The formula is only for you to allow you to recompute if you so choose. It is not causing the result that you compute to replace what the sender told you. [10:24:05 AM] Lee Coller says: I think Lloyd's use case should fall outside data types and in the model, he's really providing a reason or justification for the value. [10:24:47 AM] Grahame Grieve says: agree Lee. The key question is, how do I know whether it's safe to reevaluate? whether this is intended? You've established how I can distinguish for myself waht I am doing, but now how I know what to do [10:25:02 AM] Grahame Grieve says: ... not how I know what to do, whoop [10:25:23 AM] Gunther Schadow says: It is EXPR<T> evaluate() not T evaluate() because that causes the formula to always be part and parcel with the value. Allows you to recompute again and again, but each time freezing the value so that you have a lock on it and you can sign it and say: this is what I found (if you reevaluate you may find something different, but that's because you circumstances may ne different.) [10:25:48 AM] Gunther Schadow says: It is never unsafe to reevaluate, because reevaluation is not a destructive operation. [10:26:05 AM] Gunther Schadow says: You get a new value and can do with it as you wish. It never changes the old value. [10:26:17 AM] Lee Coller says: We have three cases: 1) Value with Expr 2) Expr with No Value 3) Value with No Expr [10:26:32 AM] Gunther Schadow says: All handled the same way. [10:26:41 AM] Gunther Schadow says: Value always takes precedence. [10:27:03 AM] Grahame Grieve says: use case 2 - the value is null, right? [10:27:12 AM] Gunther Schadow says: Yes. [10:27:38 AM] Lee Coller says: Case 2, do I have to re-evaluate every time every time I need the value? [10:27:46 AM] Grahame Grieve says: So, Lloyd's use case is partially handled. I can assert how something was derived, as long as it is in a form that it would not be unsafe for you to re-evaluate [10:27:55 AM] Gunther Schadow says: Yes and no. [10:28:04 AM] Gunther Schadow says: Yes, you have to reevaluate if you access the same object. [10:28:12 AM] Gunther Schadow says: But in all likelyhood this will not be the case. [10:28:33 AM] Gunther Schadow says: expr w/o value will be in dictionaries and master files [10:28:47 AM] Grahame Grieve says: I'm not convinced that evaluate nees to return EXPR<T>, btw. because of your last point. [10:28:52 AM] Gunther Schadow says: when someone sends you data that you want to display, you will always have a value. [10:29:20 AM] Gunther Schadow says: evaluate does not need to return EXPR<T> and since EXPR<T> is a T it can. [10:30:30 AM] Gunther Schadow says: expr w/o value will also be in orders and statements of intent. In all these cases it can't be evaluated unless you bind free variables. [10:31:32 AM] Grahame Grieve says: ok. I can run with that. [10:31:42 AM] Grahame Grieve says: one issue left for me, I think [10:31:56 AM] Grahame Grieve says: language : CS => this is an extensible CS, a troublesome beast [10:32:47 AM] Gunther Schadow says: doesn't have to be extensible CS. Can make it CV too. [10:32:52 AM] Grahame Grieve says: But we can manage that if we define a simple registration procedure as part of the declaration of a language. Anyone see an issue with that? [10:34:12 AM] Lee Coller says: No, it's no different than URL scheme. [10:35:37 AM] Grahame Grieve says: no, sorry, one more question: expression - ED or ST? [10:36:17 AM] Gunther Schadow says: "But we can manage that if we define a simple registration procedure as part of the declaration of a language" -- that's a cool idea. It forces registration. I like that. [10:36:23 AM] Grahame Grieve says: I think it has to be ED, to allow references, translations, and xml based expression languages. I think we all agree, but Gunther made some reference above which was equivocal on this [10:36:35 AM] Gunther Schadow says: Must be ED. I don't like it. But it's convincing evidence. [10:37:19 AM] Grahame Grieve says: yep. agree. though a language binding would be able to lock this down. and the PQXF language would lock it down to ST with no translations [10:38:39 AM] Lee Coller says: Agree with Gunther. I'd define a flavor that locks it down to ST with no translations with a note on EXPR that there should be a really good reason for using the non-constrained one. I really don't wan't to have to support translations of expressions. [10:39:36 AM] Gunther Schadow says: What does "support" mean? I do support it out of the box. [10:39:39 AM] Gunther Schadow says: You know how? [10:39:49 AM] Gunther Schadow says: -> by picking the one that I can actually use.

[10:41:02 AM] Grahame Grieve says: I don't think it's too onerous to support translations. but it is a little onerous when you cast your eye over the whole lifecycle. [10:41:27 AM] Grahame Grieve says: so, we encourage language bindings to lock it down, but do not push too hard