Page tree

Date & Time

20:00 UTC Wednesday 20th July 2016 

GoToMeeting Details

Click here to see GoToMeeting joining information

Goals

  • Finalize the syntax for cardinality of relationship groups in Expression Templates
  • Discuss other template requirements that need to be considered

Agenda and Meeting Notes

Description
Owner
Notes

Welcome, introductions and apologies

 
Agenda reviewReview agenda for today's meeting
Finalize syntax for cardinality

What syntax should we use to define cardinality constraints?


  • [[@Procedure]]: [[ {} [1..2] @boris]] { ..... }
  • [[@Procedure]]: [[ {} [1..2] ]] { ..... }
  • [[@Procedure]]: [1..2 [ @boris]]  { [1..2 [ .....  ]]   ..... }
  • [[@Procedure]]: [1..2 [ ]]  { [1..2 [ .....  ]]   ..... }
  • [[@Procedure]]: {{1..2 @boris }} { ..... } - ECH, JLO, MLA, RHA, LBI
  • [[@Procedure]]: {{1..2 }} { ..... }
  • [[@Procedure]]: ~[1..2] @boris { ..... }
  • [[@Procedure]]: ~[1..2] { ..... }

  • [[@Procedure]]: #[1..2] @boris { ..... }
  • [[@Procedure]]: #[1..2]  { ..... }
  • [[@Procedure]]: %[1..2] @boris { ..... }
  • [[@Procedure]]: %[1..2]  { ..... }


  1. On a focus concept, an attribute or an attribute value - e.g. in the relevant slot [[ [1..*] < 123456 @slotName ]]
  2. On a relationship group - e.g. 123456 |concept|: ~[1..*] { .......}
    • Note: The syntax must clearly indicate that the cardinality on a relationship group does not appear in the concrete expression that is generated when the expression template is populated. This is needed to distinguish an Expression Template (with relationship group cardinalities) from an Expression Constraint Template (for which the relationship group cardinalities do appear in the populated version of the template).
    • In this example syntax, the "~" is being used to say "The following constraint needs to be removed when the template is populated."
    • For example, an expression template such as:
      • [[ @Procedure ]] : ~[1..2] @group1 { 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] }
    • may be populated to generate the following expression:
      • 71388002 |Procedure site - direct|:  { 405813007 |Procedure site - direct| = 66754008 |Appendix structure|, 260686004 |Method| = 129304002 |Excision - action| }
    • Note that the cardinality "[1..2]" is removed when generating the final expression.
Template syntax requirements

Are there any other template requirements that we haven't yet considered (e.g. additional concept authoring requirements)?

  • Currently being discussed internally within IHTSDO
  • Please send me any other functional requirements for templates that you know of - with examples of where and why it is needed.
Finalize draft template syntax
  •  Goal is to start drafting the template syntax for wider review, and input from IHTSDO Tooling and Content teams.
Confirm next meeting date/timeNext meeting to be held in 4 weeks on Wednesday 17th August

Meeting Files

  File Modified
JPEG File KB.jpg 2016-Jul-19 by Ed Cheetham
JPEG File outputImage.jpg 2016-Jul-19 by Ed Cheetham
JPEG File specimen.jpg 2016-Jul-19 by Ed Cheetham

  • No labels

3 Comments

  1. Thanks.

    Three things from me...

    (1) I've lost track (again) of the difference  between an 'expression template' and an 'expression constraint template'. I dug out the 20151214 powerpoint slides which rather bundles 'expression constraint template' with 'conditional value set binding', but I'd appreciate a few more examples of which is which and when they are needed.

    (2) regarding the role group cardinality question, probably been discussed already, but is there a good reason why the whole role group clause can't be treated as a slot in its own right?:

    [[ @Procedure ]] : [[ [1..2] @group1 { 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] } ]]

    This is a bit like Daniel's #< ># scope markers - for the groups, anyway. For expression templates it could then be treated the same as the value slots in terms of "replace me, according to the rules I contain, with 'stuff' which conforms to the compositional-grammar, and then remove all trace of me (including the [[ ]] delimiters)".

    (3) Are there any other template requirements? - conditional operators

    (a) I appreciate that there's been a bit of back-and-forth with a 'rule language' (with recent discussions offloading much of this to the FHIR mapping syntax), but does the template syntax need a set of conditional/flow control operators (I know they are in examples but I haven't seen them for a while)?

    (b) some of these might be performed at MRCM level (e.g. no RG for a single role, introduce with 2 or more roles), but one I've been wondering about would relate to the (? 'shared variable') issue of testing that a particular value appears for > 1 attribute in a particular definition/expression. The example I can think of relates to specimens and their collection procedures, where we may want to be able to say either:

    "the 'specimen substance' value for a specimen should match the 'direct substance' value of its collection procedure (in this case 'urine' for MSSU):  

    Or "the 'specimen topography' value for a specimen should match the 'direct site' value of its collection procedure (in this case 'kidney' for a biopsy): 

     

    I'm sure there are exceptions, but it looks like something that could be managed/specified, and the template may be the layer to do it. It *may* be enough to say that the values for both should be populated from the same source field, but if not perhaps there is a need for a reciprocal check between slots. Whatever, this might also be handled by a conditional clause which says something like "IF specimen has a specimen topography AND a specimen procedure value, THEN the specimen procedure: procedure site direct=value ==  specimen: specimen topography=value"

    Ed

  2. Thanks Ed for your very thoughtful and helpful questions, comments and examples!

    I will reply to what I can here ... and we can discuss the rest at tomorrow's meeting.

    (1) The difference between an 'expression template' and an 'expression constraint template'

    • Expression Template = An expression with slots. 
      • I think of this as being a standardized pattern for a clinical meaning that will be represented as a SNOMED CT expression.
      • The result of populating the slots represents a single clinical meaning, and conforms to the Compositional Grammar syntax.
      • Use cases include - defining reusable patterns for precoordination and postcoordination, and terminology binding 
      • E.g. [[ @Procedure ]] : { 405813007 |Procedure site - direct| = [[ @bodySite ]], 260686004 |Method| = [[ @method ]] }
      • Populating the slots results in a CG expression, such as:
        • 71388002 |Procedure|:  { 405813007 |Procedure site - direct| = 66754008 |Appendix structure|, 260686004 |Method| =129304002 |Excision - action| }
    • Expression Constraint Template = An expression constraint with slots. 
      • You can think of this as a standardized pattern for a SNOMED CT 'query'.
      • The result of populating the slots represents a set of clinical meanings, and conforms to the Expression Constraint Language syntax.
      • Use cases include - Defining reusable patterns for terminology queries, and defining a constraint where the possible values depends on the value of another field (as per the Specimen example you provided)
      • E.g. < 17636008 |Specimen collection| 363701004 |Direct substance| = << [[ $substance ]]
        • Note: Thanks for the great example!
      • Populating the slots results in an ECL expression constraint, such as:
        • 17636008 |Specimen collection| 363701004 |Direct substance| = << 78014005 |Urine|
        • which (when substrate = SNOMED CT international edition) represents a set of around 24 concepts.

    (2) Regarding treating the whole role group clause as a slot ...

      • I don't think we have discussed this in detail, so happy to do so. However, I'm cautious about introducing any new notation into the templates unless it is clear as to the purpose it serves. I'm also cautious about re-using the same notation (in this case "[[..]]") to mean 2 different things. Lastly, we need the template to be very clear as to how an expression template should be processed to generate an expression.
      • The example you gave was:
        • [[ @Procedure ]] : [[ [1..2] @group1 { 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] } ]]
      • I agree that this provides a convenient way of re-using the same syntax for cardinality and names, as we are using for a slot.
      • However, does adding the "[[" around the whole refinement serve any purpose that the existing braces cannot serve? That is, what does:
        • T1: [[ @Procedure ]] : [[ [1..2] @group1 { 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] } ]]
        • say, that is diffierent from:
        • T2: [[ @Procedure ]] : [1..2] @group1 { 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] }
        • The only thing that I can see that is different is that T1 says that "[1..2]" does not literally appear in the final expression .... whereas, T2 says that "[1..2]" does literally appear in the final expression (because it is outside a slot). However, we could fix this by using a different syntax before the cardinality, such as "~[1..2]" or "%[1..2]" or "#[1..2]" or "\\[1..2]\\". By making this notation different to the slot notation, we can clearly distinguish that these two different parts of the template should be processed differently (see point below).
      • Reusing the "[[" notation around the role groups makes it more difficult to distinguish between the 'original slots', which are to be replaced with a single clinical meaning (of the form "cardinality @name #value_reference expression_constraint"), and the 'proposed type of slots' for which some of its contents will appear as 'literal strings' in the resulting expression (e.g. the braces, fixed attributes, equal signs etc). The only way of really distinguishing between these is the position of the 'slot' in the template - i.e. if the slot appears where you would expect a refinement to go, then it will include part of the literal expression; where as if it appears where you would expect a concept reference to go, then the statement inside is a constraint on the possible replacement values. However, this may quickly become a confusing distinction if we need to replace an attribute concept with an 'original slot', as we would need to check where the slot finishes (i.e. where the matching "]]" is) in order to know whether it contains a literal string, or a semantic constraint. Personally, this sounds pretty complicated to me - so I'd prefer not to add this confusion.
        • E.g. distinguishing between:
          • Proposed type of slot containing literal strings: 
            • 71388002 |Procedure| : [[  405813007 |Procedure site - direct| = [[ @bodySite ]] ]]
               
          • Original type of slot (that is completely replaced with a single clinical meaning): 
            • 71388002 |Procedure| [[ @procedureAttribute < 363704007 |Procedure site| ]] = [[ @bodySite ]]

    (3) Are there any other template requirements? - Conditional operators

      • I guess there are 2 extreme positions, and potentially a 'compromise' position in the middle (if we can find it): 
        • At one extreme, we could push all conditional and complex logic about how to populate a slot out of the template syntax, and require templates to be used in conjunction with some other language that does this.
        • At the other extreme, we could design a very complex language (or embed an existing one) that allows us to say all the complex things we need to be able to say.
        • The 'compromise' perhaps could be to allow simple conditional statements within the template .... and require anything more complex to be supported by an external language. Obviously, we would need to agree on what a 'simple conditional statement' is.
      • With respect to your example (interesting example by the way!), we could require that either the value of the |Specimen procedure|'s direct substance is the same as the value for |Specimen substance| or that the value of the |Specimen procedure|'s direct site is equal to the value of the |Specimen source topography| - using an Expression Template in the slot, similar to the one above in my EC example for (1). It could look something like:
        • 123038009 |Specimen|: 370133003|Specimen substance| = [[ @substance < 91720002 |Body substance| ]],
                 118171006 
          |Specimen procedure| = [[ @procedure < 17636008 |Specimen collection|:
                              ([0..0] 363701004 |Direct substance| != << [[ $substance ]] AND [0..0] 405813007 |Procedure site - Direct| != << [[ $bodySite ]] ) ]]
          ,
                  118169006 |Specimen source topography| = [[ @bodySite < 91723000 |Anatomical structure| ]]
        • This basically says that if the |Specimen procedure| value has a direct substance, then it must be a descendant or self of the |Specimen substance| AND if the |Specimen procedure| value has a direct site, then it must be a descendant or self of the |Specimen source topography value|. 
      • However, as you suggest, we may need a conditional statement to handle the cases in which there is no specimen substance or no specimen source topography.
        • To support this, we could agree to allow a simple IF-THEN-ELSE clause inside a slot
          • For example - IF (condition) THEN (EC1 | ECTemplate1 | NULL| IFTHENELSE) ELSE (EC2 | ECTemplate2 | NULL | IFTHENELSE), where 'condition' is of the form valueReference ("=" | "!=") (EC | ECTemplate | NULL) ?? 
          • And then anything that can't be said this simply, needs to be pushed into a more complete language (like the FHIR mapping language)
        • For example, the @procedure's slot condition could be written something like:
          • IF (($substance != NULL) AND ($bodySite != NULL))
            THEN (< 17636008 |Specimen collection|: 
            ([0..0] 363701004 |Direct substance| != << [[ $substance ]] AND [0..0] 405813007 |Procedure site - Direct| != [[ $bodySite ]] )
            ELSE (IF (($substance = NULL) AND ($bodySite !=NULL)) 
                         THEN (< 17636008 |Specimen collection|: [0..0] 405813007 |Procedure site - Direct| != [[ $bodySite ]] ) 
                         ELSE ( IF (($substance =!= NULL) AND ($bodySite = NULL)) THEN (< 17636008 |Specimen collection|: [0..0] 363701004 |Direct substance| != << [[ $substance ]]) ELSE (< 17636008 |Specimen collection|) ))

          • Note: This would be easier to say if we introduce "ELSEIF"s
        • For further discussion ....

    Thanks again! 

    Kind regards,
    Linda. 

     

  3. Hi everyone,

    As a reminder ... your homework over the next four weeks is to consider (and discuss by email) the following, in the context of the SNOMED CT Template Syntax:

    1. Ed's specimen example - Please propose your own solutions to this (see mine above)
    2. Should we introduce the "LET" notation?
      • If so, then what does it look like (with an example)
    3. Should we introduce "IF/THEN/ELSEIF/ELSE" statements?
      • And if so, then what does it look like (with an example)
      • Do we limit these to defining the constraint within a slot?
    4. Should we introduce a notation that 'looks inside' the definition of a concept, to refer to one of its defining attribute values
      • And if so, then what syntax do we use - for example:
        • 57617002 |Urine specimen procedure|.363701004 |Direct substance|
        • [[$procedure]].363701004 |Direct substance|
    5. Given that this week we agreed to the following notation for the cardinality of a relationship group:
      • [[@Procedure]]: {{1..2 @boris }} { 405813007 |Procedure site - direct| = [[ @bodySite ]], 260686004 |Method| = [[ @method ]] }
      • [[@Procedure]]: {{1..2 }} 405813007 |Procedure site - direct| = [[ @bodySite ]], 260686004 |Method| = [[ @method ]] }

    should we be consistent on the number of brackets used, when defining the cardinality of slots?

      • Previously, I was writing: 
        • [[@Procedure]]: 405813007 |Procedure site - direct| = [[ [1..1] @bodySite ]], 260686004 |Method| = [[ [1..1] @method ]] }
        • [[@Procedure]]: 405813007 |Procedure site - direct| = [[ [1..1] < 123037004 |Body structure| ]], 260686004 |Method| = [[ [1..1] < 129264002 |Action| ]] }
        • [[@Procedure]]: 405813007 |Procedure site - direct| = [[ [1..1] @bodySite < 123037004 |Body structure| ]], 260686004 |Method| = [[ [1..1] @<method < 129264002 |Action| ]] }
      •  Which works quite well in the second example, when the slot includes just a cardinality and an expression constraint. However, it is inconsistent with the {{1..2 boris }} notation agreed for constraint on the relationship group (which does not introduce additional square brackets around the square brackets)
      • To be consistent, we could either drop the square brackets on the cardinality in the slot - for example:
        • [[@Procedure]]: 405813007 |Procedure site - direct| = [[ 1..1 @bodySite ]], 260686004 |Method| = [[ 1..1 @method ]] }
        • [[@Procedure]]: 405813007 |Procedure site - direct| = [[ 1..1 < 123037004 |Body structure| ]], 260686004 |Method| = [[ 1..1 < 129264002 |Action| ]] }
        • [[@Procedure]]: { 405813007 |Procedure site - direct| = [[ 1..1 @bodySite < 123037004 |Body structure| ]], 260686004 |Method| = [[ 1..1 @<method < 129264002 |Action| ]] }
      • Or alternatively, add some square brackets to the cardinality of the relationship group - for example:
        • [[@Procedure]]: {{ [1..2] @boris }} { 405813007 |Procedure site - direct| = [[ @bodySite ]], 260686004 |Method| = [[ @method ]] }
        • [[@Procedure]]: {{ [1..2] }} 405813007 |Procedure site - direct| = [[ @bodySite ]], 260686004 |Method| = [[ @method ]] }
      • Thoughts?

    Thanks! Our next meeting will be held on Wednesday 17th August.

    Kind regards,
    Linda.