Nesting / Sub-expressions in the ECL
Discussion about extending the ECL to support sub-expressions
Comments
Thanks very much for the feedback Michael! And good timing - as I was planning to finalize ECL v1.1 this week.
I will have a more detailed look at your suggestion over the next couple of days, and let you know my thoughts.
Kind regards,
Linda.
Hi Michael,
Could you please help me understand your requirements better. I think I got a bit lost when you explained why subtracting TPP (Trade Product Packs) removes the products with additional active ingredients (that weren't prescribed). Note 1: I understand that you are using existential restriction, and that subtypes may contain a larger set of active ingredients ... just not sure how subtracting "<< TPP" removes the products you don't want prescribed. Note 2: Imagine how much easier this would be if the prescribed concept used universal restriction.
I understood from your post that 'x' represents the specific MPP concept that was prescribed (e.g. |Amoxicillin 500 mg capsule [25 capsules]|), and I think TPP represents the class of product pack concepts that have a trade name? (e.g. |AMOXIL (Amoxicilin) 500 mg capsule (25 capsules)|) .... so I assume that << TPP is the set of TPP product concepts (i.e. same as "^ TPP" if TPP was a refset of Trade Product Pack concepts)? With this in mind, I'm a bit confused as to why '< x AND < CTPP' removes the products with more active ingredients than you need. Obviously I'm missing something here.
If subtracting '<< TPP' is actually what you're after, then could you please help me understand why "(< x AND < CTPP) MINUS << TPP" doesn't give you the same result as the ECL you are suggesting?
However, based on your explanation that (1) CTPP concepts are subtypes of TPP concepts, (2) TPP concepts are subtypes of MPP and that (3) x is an MPP, I would have expected the following ECL to find the appropriate CTPP concepts with the correct set of active ingredients:
(< x AND < CTPP) MINUS (< x : 127489000 |Has active ingredient| != (<< 105590001 |substance|:R 127489000 |has active ingredient| =x ))
or using the new 'syntactic sugar':
(< x AND < CTPP) MINUS (< x : 127489000 |Has active ingredient| != << (x .127489000 |has active ingredient|))
That is, the set of subtypes of x, which are CTPP (Containered Trade Product Pack) concepts, minus the concepts that have an active ingredient that is not in the set of x's active ingredients.
Kind regards,
Linda.
The problem
In the context of the Australian Medicines Terminology, there is a need to be able to query the terminology content to support the "dispense" use case.
This use case can be characterised as starting with a unbranded (MPP) medication concept (ie the prescribed medication), find all branded, container-ed concepts (CTPPs) that are compatible (ie candidate dispensable medications).
In AMT, CTPP isa TPP isa MPP and all the medication concepts have "containining" / "some" semantics. So multi-ingredient concepts are children of single ingredient concepts. Thus to write an ECL to find suitable CTPPs you need to be able to exclude multi-ingredient children.
In the older proposed query language you could do this with a query like:
Exclude( Descendants( x ), DescendantsAndSelf ( TPP ) )where 'x' is the prescribed (MPP) concept, which identifies the multi-ingredient MPPs whose CTPP descendants we want to exclude from the final result. We can express this in ECL
< x - << TPPBut then we need to write the complete query:
Exclude( Intersection(Descendants(x),Descendants(CTPP)), Descendants(Exclude(Descendants(x),DescendantsAndSelf(TPP))) )Transliterating this into ECL gives:
(< x AND < CTPP) - < (< x - << TPP)But this is not a valid ECL expression because we cannot apply operators like <, <<, <!, etc to expressions.
This lack of composability imposes a significant limitation on the expressive power of the language.
The proposal
Change the grammar rule:
simpleExpressionConstraint = [constraintOperator ws] focusConceptto
simpleExpressionConstraint = [constraintOperator ws] ( focusConcept / "(" expressionConstraint ")" )where the semantics is just to take the union of the results of applying the constraintOperator to each concept matching the expressionConstraint.