Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
In this section, we explain how the SNOMED CT template syntax can be applied to the computable languages to create template languages. In particular, we combine the Template Syntax with Compositional Grammar to create the Expression Template Language. A similar process can be used to combine the Template Syntax with the Expression Constraint Language to create an Expression Constraint Template Language.
SNOMED CT template languages are created by:
Combining the base language (to which the slots are added) with the SNOMED CT template syntax;
Adding any additional rules referenced by the SNOMED CT template syntax (e.g. the Expression Constraint Language to represent slot value constraints);
Removing any duplicate rules (e.g. rules that are repeated in both the base language and the expression constraint language;
Adding references to the template syntax in the appropriate rules of the base language to support the inclusion of slots. This involves:
Renaming the first rule in the base language to add the word "Template" (e.g. from "expression" to "expressionTemplate");
Adding the rule tokenReplacementSlot as an alternative wherever a token is referenced (e.g. "definitionStatus / tokenReplacementSlot");
Adding the rules conceptReplacementSlot
For an example of how this process is applied to SNOMED CT compositional grammar to create expression templates, please refer to the syntax in the next section.
Adding the rule concreteValueReplacementSlot as an alternative attributeValue; and
Adding the rule templateInformationSlot before each focus concept, each attribute group and each attribute name value pair.
SNOMED CT is a clinical terminology with global scope covering a wide range of clinical specialties and requirements. The use of SNOMED CT expressions in electronic health records (EHRs) provides a standardized way to represent clinical meanings captured by clinicians and enables the automatic interpretation of these meanings. SNOMED CT expression constraints provide a computable rule that can be used to define a bounded set of clinical meanings for the purpose of constraining the contents of a data element in an electronic health record (EHR), intensionally defining a concept-based reference set, querying SNOMED CT content in a machine processable way, or restricting the range of an attribute defined in the SNOMED CT concept model.
In some situations, however, the specific concepts or values are not known at the time of authoring. In these cases, one or more slots may be used within an expression or expression constraint to create an expression template or expression constraint template (respectively). S lots provide a placeholder in the expression or expression constraint, whose specific value can be completed at a subsequent time using a concept recorded within an information model, entered into a data entry form, or sourced by some other means. When each slot in the template has been replaced with a specific value, the result should be a syntactically correct expression or expression constraint. SNOMED CT templates can be used for a number of purposes, including to define reusable patterns for authoring and validating precoordinated concept definitions and postcoordinated expressions.
The SNOMED CT Template Syntax (v1.0) was first published in July 2017. In 2020, the syntax was updated (v1.1) to support boolean attribute values.
The purpose of this document is to define and describe a consistent mechanism for SNOMED CT templates, which can be used to convert any computable SNOMED CT language into a SNOMED CT template language. For example, by using the syntax provided in this document, SNOMED CT compositional grammar can be used as an expression template language, and the SNOMED CT expression constraint Language can be used as an expression constraint template language. This guide also provides examples and guidance to assist in the processing of templates.
This document presents the specification of a SNOMED CT template syntax, which can be used together with other formal SNOMED CT languages to develop SNOMED CT Templates. The SNOMED CT Template Syntax is part of a consistent set of computer processable language syntaxes designed to support a variety of use cases involving the use of SNOMED CT. Other computable SNOMED CT languages that are either complete or under development include:
: designed to represent SNOMED CT expressions;
designed to represent a bounded set of clinical meanings represented using SNOMED CT; and
This document provides a specification, examples and general guidance to assist in the representation and processing of SNOMED CT templates.
However, this document does not include a full description of how to implement a template parser or interpreter. It does not describe how to transform a template into other languages (such as OWL, SPARQL or SQL), or how to determine whether two templates are equivalent. It also does not describe how to implement a terminology server or an EHR which uses templates to constrain or query its content.
The target audiences of this document include:
SNOMED International National Release Centres;
SNOMED CT designers and developers, including designers and developers of EHR systems, information models, data entry interfaces, storage systems, decision support systems, retrieval and analysis systems, communication standards and terminology services;
SNOMED CT terminology developers, including concept model designers, content authors, map developers, subset and constraint developers and release process managers.
It should be noted that this document contains both technical and non-technical content. In particular, the detailed logical model and formal syntax is specifically focussed at more technical readers. Less technical readers are encouraged to read the introductory material and examples.
This document defines the SNOMED CT template syntax and describes how and where it may be implemented. Chapter 2 begins by describing some key use cases in which SNOMED CT templates can be used. Chapter 3 then describes the requirements used to guide the definition of this syntax. In Chapter 4, the logical model of the template syntax is presented, while Chapter 5 defines the ABNF serialisation of the logical model. Chapter 6 explains how to apply the SNOMED CT template syntax to other computable languages, and provides the syntax for the expression template language (ETL). In chapter 7, we explain the steps involved in processing an expression template to create a set of populated expressions. And finally, in chapter 8, we present some examples of SNOMED CT expression templates that conform to the syntaxes defined in Chapters 5 and 6.
The formal syntax for SNOMED CT expression templates (v1.1.1) is shown below. This syntax is derived by combining:
Compositional Grammar v2.4,
Template Syntax v1.1.1, and
Expression Constraint Language v1.4.
As explained in SNOMED CT Language Templates, references to the Template Syntax are also added into the Compositional Grammar rules to enable slots to be included within an expression template. Please note that rules that appear in both Compositional Grammar and the Expression Constraint Language (e.g. conceptId and term) are removed from the Expression Constraint Language (by commenting out) to avoid duplication.
; Compositional Grammar v2.4 with slot references (in blue)
expressionTemplate = ws [ ( definitionStatus / tokenReplacementSlot) ws] subExpression ws
subExpression = focusConcept [ws ":" ws refinement]
definitionStatus = equivalentTo / subtypeOf
equivalentTo = "==="
subtypeOf = "<<<"
focusConcept = [templateInformationSlot ws] conceptReference *(ws "+" ws [templateInformationSlot ws] conceptReference)
conceptReference = conceptReplacementSlot / expressionReplacementSlot / ( conceptId [ws "|" ws term ws "|"] )
conceptId = sctId
term = nonwsNonPipe *( *SP nonwsNonPipe )
refinement = (attributeSet / attributeGroup) *( ws ["," ws] attributeGroup )
attributeGroup = [ templateInformationSlot ws ] "{" ws attributeSet ws "}"
attributeSet = attribute *(ws "," ws attribute)
attribute = [ templateInformationSlot ws ] attributeName ws "=" ws attributeValue
attributeName = conceptReference
attributeValue = expressionValue / QM stringValue QM / "#" numericValue / booleanValue / concreteValueReplacementSlot
expressionValue = conceptReference / "(" ws subExpression ws ")"
stringValue = 1*(anyNonEscapedChar / escapedChar)
numericValue = ["-"/"+"] (decimalValue / integerValue)
integerValue = digitNonZero *digit / zero
decimalValue = integerValue "." 1*digit
booleanValue = true / false
true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
sctId = digitNonZero 5*17( digit )
ws = *( SP / HTAB / CR / LF ) ; optional white space
SP = %x20 ; space
HTAB = %x09 ; tab
CR = %x0D ; carriage return
LF = %x0A ; line feed
QM = %x22 ; quotation mark
BS = %x5C ; back slash
digit = %x30-39
zero = %x30
digitNonZero = %x31-39
nonwsNonPipe = %x21-7B / %x7D-7E / UTF8-2 / UTF8-3 / UTF8-4
anyNonEscapedChar = HTAB / CR / LF / %x20-21 / %x23-5B / %x5D-7E / UTF8-2 / UTF8-3 / UTF8-4
escapedChar = BS QM / BS BS
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
; Template Syntax v1.1
templateSlot = templateReplacementSlot / templateInformationSlot
templateReplacementSlot = conceptReplacementSlot / expressionReplacementSlot / tokenReplacementSlot / concreteValueReplacementSlot
conceptReplacementSlot = "[[" ws "+" ws conceptReplacement [slotName ws] "]]"
expressionReplacementSlot = "[[" ws "+" ws expressionReplacement [slotName ws] "]]"
tokenReplacementSlot = "[[" ws "+" ws tokenReplacement [slotName ws] "]]"
concreteValueReplacementSlot = "[[" ws "+" ws concreteValueReplacement [slotName ws] "]]"
conceptReplacement = "id" ws [ "(" ws slotExpressionConstraint ws ")" ws]
expressionReplacement = ["scg" ws] ["(" ws slotExpressionConstraint ws ")" ws]
tokenReplacement = "tok" ws [ "(" ws slotTokenSet ws ")" ws]
concreteValueReplacement = stringReplacement / integerReplacement / decimalReplacement / booleanReplacement
stringReplacement = "str" ws [ "(" ws slotStringSet ws ")" ws]
integerReplacement = "int" ws [ "(" ws slotIntegerSet ws ")" ws]
decimalReplacement = "dec" ws [ "(" ws slotDecimalSet ws ")" ws]
booleanReplacement = "bool" ws [ "(" ws slotBooleanSet ws ")" ws]
slotTokenSet = slotToken *(mws slotToken)
slotStringSet = slotStringValue *(mws slotStringValue)
slotStringValue = QM stringValue QM
slotIntegerSet = ( slotIntegerValue / slotIntegerRange) *(mws (slotIntegerValue / slotIntegerRange))
slotDecimalSet = ( slotDecimalValue / slotDecimalRange) *(mws (slotDecimalValue / slotDecimalRange))
slotBooleanSet = slotBooleanValue *(mws slotBooleanValue)
slotBooleanValue = booleanValue
slotIntegerRange = ( slotIntegerMinimum to [ slotIntegerMaximum ] ) / ( to slotIntegerMaximum )
slotIntegerMinimum = [ exclusiveMinimum ] slotIntegerValue
slotIntegerMaximum = [ exclusiveMaximum ] slotIntegerValue
slotIntegerValue = "#" ["-"/"+"] integerValue
slotDecimalRange = ( slotDecimalMinimum to [ slotDecimalMaximum ] ) / ( to slotDecimalMaximum )
slotDecimalMinimum = [ exclusiveMinimum ] slotDecimalValue
slotDecimalMaximum = [ exclusiveMaximum ] slotDecimalValue
slotDecimalValue = "#" ["-"/"+"] decimalValue
exclusiveMinimum = ">"
exclusiveMaximum = "<"
slotName = "@" (slotStringValue / nonQuoteStringValue)
slotToken = definitionStatus / memberOf / constraintOperator / conjunction / disjunction / exclusion / reverseFlag / expressionComparisonOperator / numericComparisonOperator / stringComparisonOperator /booleanComparisonOperator
nonQuoteStringValue = *(%x21 / %x23-26 / %x2A-3F / %x41-5A / %x5C / %x5E-7E) ; string with no ws, quotes, at, square brackets or round brackets
templateInformationSlot = "[[" ws slotInformation ws "]]"
slotInformation = [cardinality ws] [slotName ws]
; Expression Constraint Language v1.4
slotExpressionConstraint = ws ( slotRefinedExpressionConstraint / slotCompoundExpressionConstraint / slotDottedExpressionConstraint / slotSubExpressionConstraint ) ws
slotRefinedExpressionConstraint = slotSubExpressionConstraint ws ":" ws slotEclRefinement
slotCompoundExpressionConstraint = slotConjunctionExpressionConstraint / slotDisjunctionExpressionConstraint / slotExclusionExpressionConstraint
slotConjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws conjunction ws slotSubExpressionConstraint)
slotDisjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws disjunction ws slotSubExpressionConstraint)
slotExclusionExpressionConstraint = slotSubExpressionConstraint ws exclusion ws slotSubExpressionConstraint
slotDottedExpressionConstraint = slotSubExpressionConstraint 1*(ws slotDottedExpressionAttribute)
slotDottedExpressionAttribute = dot ws slotEclAttributeName
slotSubExpressionConstraint = [constraintOperator ws] [memberOf ws] (slotEclFocusConcept / "(" ws slotExpressionConstraint ws ")")
slotEclFocusConcept = slotEclConceptReference / wildCard
dot = "."
memberOf = "^"
slotEclConceptReference = conceptId [ws "|" ws term ws "|"]
; conceptId = sctId
; term = 1nonwsNonPipe ( 1SP 1nonwsNonPipe )
wildcard = "*"
constraintOperator = childOf / descendantOrSelfOf / descendantOf / parentOf / ancestorOrSelfOf / ancestorOf
descendantOf = "<"
descendantOrSelfOf = "<<"
childOf = "<!"
ancestorOf = ">"
ancestorOrSelfOf = ">>"
parentOf = ">!"
conjunction = (("a"/"A") ("n"/"N") ("d"/"D") mws) / ","
disjunction = ("o"/"O") ("r"/"R") mws
exclusion = ("m"/"M") ("i"/"I") ("n"/"N") ("u"/"U") ("s"/"S") mws
slotEclRefinement = slotSubRefinement ws [slotConjunctionRefinementSet / slotDisjunctionRefinementSet]
slotConjunctionRefinementSet = 1*(ws conjunction ws slotSubRefinement)
slotDisjunctionRefinementSet = 1*(ws disjunction ws slotSubRefinement)
slotSubRefinement = slotEclAttributeSet / slotEclAttributeGroup / "(" ws slotEclRefinement ws ")"
slotEclAttributeSet = slotSubAttributeSet ws [slotConjunctionAttributeSet / slotDisjunctionAttributeSet]
slotConjunctionAttributeSet = 1*(ws conjunction ws slotSubAttributeSet)
slotDisjunctionAttributeSet = 1*(ws disjunction ws slotSubAttributeSet)
slotSubAttributeSet = slotEclAttribute / "(" ws slotEclAttributeSet ws ")"
slotEclAttributeGroup = ["[" cardinality "]" ws] "{" ws slotEclAttributeSet ws "}"
slotEclAttribute = ["[" cardinality "]" ws] [reverseFlag ws] slotEclAttributeName ws (expressionComparisonOperator ws slotSubExpressionConstraint / numericComparisonOperator ws (slotIntegerValue /slotDecimalValue) / stringComparisonOperator ws slotStringValue / booleanComparisonOperator ws slotBooleanValue)
cardinality = minValue to maxValue
minValue = nonNegativeIntegerValue
to = ".."
maxValue = nonNegativeIntegerValue / many
many = "*"
reverseFlag = "R"
slotEclAttributeName = slotSubExpressionConstraint
expressionComparisonOperator = "=" / "!="
numericComparisonOperator = "=" / "!=" / "<=" / "<" / ">=" / ">"
stringComparisonOperator = "=" / "!="
booleanComparisonOperator = "=" / "!="
; stringValue = 1*(anyNonEscapedChar / escapedChar)
; integerValue = digitNonZero *digit / zero
; decimalValue = integerValue "." 1*digit
; booleanValue = true / false
; true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
; false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
nonNegativeIntegerValue = (digitNonZero *digit ) / zero
; sctId = digitNonZero 5*17( digit )
; ws = *( SP / HTAB / CR / LF / comment ) ; optional white space
mws = 1*( SP / HTAB / CR / LF / comment ) ; mandatory white space
comment = "/*" (nonStarChar / starWithNonFSlash) "/"
nonStarChar = SP / HTAB / CR / LF / %x21-29 / %x2B-7E /UTF8-2 / UTF8-3 / UTF8-4
starWithNonFSlash = %x2A nonFSlash
nonFSlash = SP / HTAB / CR / LF / %x21-2E / %x30-7E /UTF8-2 / UTF8-3 / UTF8-4
; SP = %x20 ; space
; HTAB = %x09 ; tab
; CR = %x0D ; carriage return
; LF = %x0A ; line feed
; QM = %x22 ; quotation mark
; BS = %x5C ; back slash
; digit = %x30-39
; zero = %x30
; digitNonZero = %x31-39
; nonwsNonPipe = %x21-7B / %x7D-7E / UTF8-2 / UTF8-3 / UTF8-4
; anyNonEscapedChar = SP / HTAB / CR / LF / %x20-21 / %x23-5B / %x5D-7E / UTF8-2 / UTF8-3 / UTF8-4
; escapedChar = BS QM / BS BS
; UTF8-2 = %xC2-DF UTF8-tail
; UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
; UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
; UTF8-tail = %x80-BFBefore a template can be processed, it is important that the input data is represented in a clear and unambiguous way. This is required to ensure that the template is processed in the expected manner, and the intended results are produced. In this section, we explain some of the considerations in representing and preparing the input data for processing.
Template input data may be represented in a variety of forms, ranging from flat tabular structures to nested serializations. Irrespective of the format, however, it is important that there is no ambiguity as to how each piece of input data should be used to create the resulting expressions. This can be particularly challenging where repetition of relationship groups or attribute name-value pairs is required.
The UML diagram below illustrates the logical structure of expression template input data. Each set of Expression Template Input Data includes the data intended to be used to create one or more expressions. The data used to populate a single expression is referred to in this model as Expression Data. Each Expression Data (identified by an expression id), may include at most one Definition Status Slot (with a slot name and a definitionStatus value), zero or more Focus Concept Slots (each with a slotName and zero or more values), zero or more Relationship Group Slots (each with a group name), and zero or more ungrouped Attribute Name-Value Pair Slots (each with a name). Each Relationship Group Slot has zero or more Relationship Group Data instances in the input data (each identified by a group id). Each of these Relationship Group Data instances has input data for one to many Attribute Name-Value Pair Slots. And for each Attribute Name-Value Pair Slot within a Relationship Group Data instance, there are zero to many Attribute Name-Value Pair Data instances (identified by an anvPair id), each with at most one Attribute Name Slot (with name and value), and at most one Attribute Value Slot (with name and either a simple data value, or an Expression Data instance of its own).
In this section, we provide some examples of unambiguous expression template input data, and discuss how this input data can be used to populate each expression.
The expression template below is used to create expressions that represent a with one or more and . When using expression templates, such as this one, in which attribute name-value pairs and relationship groups may be repeated, the input data should be explicit about which data values are used to populate each slot, and how these values are grouped into relationship groups.
To support the creation of input data for this expression template, the logical model in
The expression template below is used as a pattern for family history expressions. It contains a nested relationship group (i.e. SSgroup) inside the outer relationship group (i.e. AFgroup). To populate this expression template, the input data must be clear as to where each value should be used, and how these values should be grouped into relationship groups and expressions.
To support the creation of input data for this expression template, the logical model can be specialized as shown below. Please note that this model has been simplified by removing unnamed logical classes, which have a cardinality of 1..1 and no data attribute.
Using the input data shown above to process the given expression template will result in following three expressions.
The expression template below represents a procedure with a single method and one or more procedure devices. Please note that in the first attribute name-value pair, both the attribute name and the attribute value use a slot. Because this name-value pair is repeatable, the input data needs to include an attribute name-value pair slot to ensure that the corresponding attribute name and attribute value stays connected.
To support the creation of input data for this expression template, the logical model above can be specialized as shown below. Please note that this model has been simplified by removing unnamed logical classes, which have a cardinality of 1..1 and no data attribute.
This logical model can be populated with input data, as shown below in the table. Please note that because the first attribute name-value pair is repeatable and uses a replacement slot for both the attribute name and attribute value, the input data needs to include the attribute name-value pair slot to ensure that the corresponding attribute name and attribute value stays connected.
Using the input data shown in the table above to process the given expression template will result in the following two expressions.
The expression template below represents a with one or more values for and , grouped into one or more relationship groups.
To support the creation of input data for this expression template, the logical model above can be specialized as shown below. Please note that this model has been simplified by removing unnamed logical classes, which have a cardinality of 1..1 and no data attribute.
The table below shows some example input data for the above template represented using the tabular format used in the previous examples.
In addition to this tabular representation, there are a wide variety of other possible formats for representing template input data, including json, xml, tsv, csv etc. The exact format used will depend on the format required by the template processor. For example, the above input data can be represented in JSON as shown below.
Example JSON Representation of Input Data
While it is important that there is no ambiguity as to how each piece of input data should be used in processing the associated expression template, there are often opportunities to make the input data much simpler than is represented in the full logical model above. In particular:
When the maximum cardinality of a relationship group is 1, there is no need to include the relationship group slot in the input data to group the attributes it contains;
When the maximum cardinality of an attribute name-value pair is 1, there is no need to include the attribute name-value pair slot in the input data to group the corresponding name and value pairs;
When there is either an attribute name slot with a fixed attribute value, or a fixed attribute name with an attribute value slot, there is no need to include the attribute name-value pair slot in the input data to group the corresponding name and value pairs.
With this in mind, the examples in simplify the input data, where appropriate, using these assumptions and an implicit association with the logical model described above.
When an expression template is used, a number of steps must be performed to create a valid SNOMED CT expression that conforms to the given template.
In this section, we explain the steps involved in processing an expression template. We also explain the pre-processing and post-processing tasks involved.
The figure below illustrates this process. Please note that these steps do not necessarily need to be performed in this order.
Figure 7-1: Template processing steps

2
<<<
1
2
3
<<<
1
4
===
1
266898002 |Family history: Respiratory disease|
1
195967001 |Asthma|
1
24484000 |Severe|
444301002 |Mother of subject|
410589000 |All times past|
410515003 |Known present|
2
161077003 |Father smokes|
1
77176002 |Smoker|
1
255604002 |Mild|
444295003 |Father of subject|
15240007 |Current|
410515003 |Known present|
161078008 |Mother smokes|
2
77176002 |Smoker|
1
24484000 |Severe|
444301002 |Mother of subject|
15240007 |Current|
410515003 |Known present|
3
160288009 |Family history: neoplasm of skin|
1
372130007 |Malignant neoplasm of skin|
1
6736007 |Moderate|
113179006 |Skin structure of nose|
444304005 |Sister of subject|
410511007 |Current or past (actual)|
410515003 |Known present|
275937001 |Family history of cancer|
2
255604002 |Mild|
88089004 |Skin structure of lip|
1
363699004 |Direct device|
2282003 |Breast prosthesis, device|
257867005 |Insertion - action|
2
71388002 |Procedure|
1
1
363699004 |Direct device|
313025003 |Hearing aid battery|
282089006 |Replacement - action|
2
363710007 |Indirect device|
6012004 |Hearing aid, device|
2
84667006 |Bone structure of cervical vertebra|
72704001 |Fracture|
2
1
71341001 |Bone structure of femur|
72704001 |Fracture|
3
1
12611008 |Bone structure of tibia|
72704001 |Fracture|
1
===
[[+id (<< 413350009 |Finding with explicit context|) @Condition]]:
[[ 1..2 @AFgroup ]] {
[[1..1]] 246090004 |Associated finding| = (
[[+id (<< 404684003 |Clinical finding|) @Finding]]:
[[0..1 @SSgroup]] {
[[0..1]] 246112005 |Severity| = [[+id (< 272141005 |Severities|) @Severity]],
[[0..1]] 363698007 |Finding site| = [[+id (< 91723000 |Anatomical structure|) @Site]]
}
),
[[1..1]] 408732007 |Subject relationship context| = [[+id (< 444148008 |Person in family of subject|) @Relationship]],
[[1..1]] 408731000 |Temporal context| = [[+id (< 410510008 |Temporal context value|) @Time]],
[[1..1]] 408729009 |Finding context| = [[+id (< 410514004 |Finding context value|) @Context]]
}1
387713003 |Surgical procedure|
1
1
312763008 |Bone structure of trunk|
72704001 |Fracture|
{
"Expression Data": [
{
"Group": [
{
"Site": "312763008 |Bone structure of trunk|",
"Morphology": "72704001 |Fracture|"
},
{
"Site": "84667006 |Bone structure of cervical vertebra|",
"Morphology": "72704001 |Fracture|"
}
]
},
{
"Group": [
{
"Site": "71341001 |Bone structure of femur|",
"Morphology": "72704001 |Fracture|"
}
]
},
{
"Group": [
{
"Site": "12611008 | Bone structure of tibia|",
"Morphology": "72704001 |Fracture|"
}
]
}
]
}




1
1
1
In addition to a type and a constraint, replacement slots may also be given a name. Slot names are explained in more detail below.
Replacement slots may be given a slot name, to allow them to be referenced from outside the slot. There are a variety of reasons to do this, including assigning a value to each slot and creating a co-dependency constraint between slots. The most common use of slot names is to refer to the slot to which a value is assigned, during the process of populating the template.
Slot names are defined within the slot using an '@' prefix. For example, the following expression template includes one slot that represents the value of | Associated with| . This slot has been given the slot name "finding".
If a segment of code, a data file or a document assigns the value 56265001 | Heart disease| to the finding slot (e.g. finding = 56265001 | Heart disease| ), then the following expression can be created.
Slot names may be repeated within a template. When the same slot name is associated with more than one slot in the same template, it indicates that these slots must be populated with the same value.
For example, the expression template below has two slots, which have each been given the name "site".
If we assign the value | Liver structure| to the slots named "site" (i.e. site = | Liver structure| ), the below expression would be created.
For additional uses of slot names, please refer to .
Replacement slots may be given a replacement type to indicate what type of value may be used to replace the slot. The replacement type directly follows the '+' symbol inside the slot (with optional whitespace between). Permitted replacement types include:
id : The slot may be replaced by a single SNOMED CT concept reference.
scg : The slot may be replaced by a SNOMED CT compositional grammar expression (either a precoordinated or postcoordinated expression).
str : The slot may be replaced by a quoted string of characters. This is used to represent a concrete attribute value that is typed as a string.
int : The slot may be replaced by a integer (preceded by a '#' symbol). This is used to represent a concrete attribute value that is typed as an integer.
dec : The slot may be replaced by a decimal (preceded by a '#' symbol). This is used to represent a concrete attribute value that is typed as a decimal.
bool : The slot may be replaced by a boolean. This is used to represent a concrete attribute value that is typed as a boolean.
Please note, that if no replacement type is specified after the '+' symbol, then a replacement type of 'scg ' is assumed.
Slots with a replacement type of 'id ' may only be replaced by a single concept reference. For example, the replacement slot in the following expression template
may be replaced by the concept 82271004 | Injury of head| to form the expression
However, it is not possible to generate a nested expression using this expression template, as the slot may not be replaced by a postcoordinated expression.
Slots with a replacement type of 'scg ' may be replaced by any (precoordinated or postcoordinated) expression. For example, the slot in the following expression template
may be replaced by any of the following values
82271004 |Injury of head| 417163006 |Injury| : 363698007 |Finding site| = 69536005 |Head structure| 417163006 |Injury| + 118934005 |Disorder of head|
to generate the following expressions.
Please note that for the second and third replacements, the template processor must add round brackets around the subexpression to ensure that the resulting expression is syntactically valid.
Slots with a replacement type of 'tok ' may be replaced by any token (or symbol) that is defined in the base language. For example, the following expression has a definition status that has not yet been defined.
If the definitionStatus | '<<<'| is used to complete the slot then the resulting expression would be:
Slots with a replacement type of 'str ', 'int ', 'dec ' or 'bool ' may be replaced by any string, integer, decimal or boolean value respectively. For example, the slot in the expression template below: (see footnote 1)
may be replaced by the string PANADOL to form the following expression
Please note that the template processor must add quotation marks around the string to ensure that the resulting expression is syntactically valid.
The slot in the following expression template:
may be replaced by the integer value 30 to form the expression
Please note that the template processor must add a hash symbol ("#") before the integer value to ensure that the resulting expression is syntactically valid.
The slot in the following expression template:
may be replaced by the decimal value 1.5 to form the expression
Please note that the template processor must add a hash symbol ("#") before the decimal value to ensure that the resulting expression is syntactically valid.
And lastly, the slot in the following expression template:
may be replaced by the boolean value TRUE to form the expression2
1
Please note that these example expression templates are based on a hypothetical drug concept model, and are not intended to reflect any specific drug model. In these expressions, the SNOMED CT identifiers created with the '9999999' namespace are for example only, and should not be used in a production environment.
2
Please note that the concept 859999999102 |Is in national benefit scheme| is a fictitious attribute used here to illustrate boolean values.
In this chapter, we state the requirements of the SNOMED CT Template Syntax. These requirements are grouped into general SNOMED CT language requirements (which are shared by all SNOMED CT computable languages), template design requirements and template processing requirements.
The general SNOMED CT language requirements include:
Requirement G.1 : Backward compatibility
The language should be backwardly compatible with any version of the language that has previously been adopted as an IHTSDO standard. Note that the only exception to this rule is where an error in the syntax has been identified and subsequently fixed.
Requirement G.2 : Consistency
Each logical feature of the language should have a single, consistent meaning across all the languages in the SNOMED CT family of languages. Each logical feature should also have a consistent set of syntax representations.
Requirement G.3 : Sufficient and necessary
Each language must be sufficiently expressive to meet the requirements of the use cases for which it was designed. However, functionality without a corresponding use case will not be included, as this increases the complexity of implementation unnecessarily.
Requirement G.4 : Machine processability
In order to facilitate the easy adoption by technical audiences, instances of each language must be able to be parsed into a logical representation using a machine processable syntax specification. This requirement will be met by defining the language syntax in ABNF.
Requirement G.5 : Human readability
Non-technical stakeholders require that the language is as human readable as possible, while still meeting the other requirements. This is essential for both the clinical validation of language instances, as well as for education and training.
The template design requirements include:
Requirement D.1 : Placeholders for values
Templates should allow for placeholders (i.e. slots) to be specified, wherever a concept, expression, token or attribute value can be used.
Requirement D.2 Slot names
Templates should allow each slot to be assigned a name, enabling the slot to be referenced outside the slot (e.g. for specifying input data).
Requirement D.3 Slot types
Template slots should be able to be constrained to only permit a specific type of value (e.g. only allowing precoordinated concepts to replace a slot).
Requirement D.4 : Template value constraints
Templates slots should be able to be constrained to only permit values from a specific value set (e.g. only allowing expressions that satisfy a given expression constraint).
Requirement D.5 : Repeatability of template components
Templates should support a way of indicating how many times each focus concept, relationship group and attribute value pair can be repeated when the template is populated.
The template processing requirements include:
Requirement P.1 : Processable input data
Input data must be available, which can be automatically processed with the template to populate the slots with values. Input data must be clear (either explicitly or implicitly) as to which slot it is intended to populate, and whether multiple values are intended to be used within the same relationship group, the same expression (but different relationship groups), or different expressions.
Requirement P.2 : Post-processing validity of constraints
After template processing, the resulting language instance (e.g. expression) must be valid against the cardinality, slot type and value constraints that were defined in the template.
Requirement P.3 : Post-processing syntactic validity
After template processing, the resulting language instance (e.g. expression) must conform to the ABNF syntax of the associated base language (e.g. SNOMED CT compositional grammar).
Requirement P.4 : Post-processing concept model validity
After template processing, the resulting language instance (e.g. expression) should be valid according to the concept model rules defined by the relevant MRCM.
Requirement P.5 : Post-processing use case validity
After template processing, the resulting language instance (e.g. expression) should conform to all additional rules that are imposed by the relevant use case. For example, if an expression template is being used to author precoordinated concepts, then the resulting expression must not use nested values (to enable representation in RF2).
Expression templates can be used to enable the easy and consistent authoring of postcoordinated expressions. They are particularly useful in situations where a specific pattern is needed to support the entry, storage or retrieval of SNOMED CT expressions. Therefore, expression templates are useful for:
Creating batches of postcoordinated expressions with a consistent structure; and
Composing postcoordinated expressions from data entered into a user interface.
These uses are explained in more detail in the following sections.
Expression templates may be applied to ensure a consistent structure is used by a set of authored expressions. For example, there may be a preference to always represent allergies using an expression in which the allergen is explicitly defined as the value of the | Causative agent| attribute. Given an appropriate expression template and a predefined list of allergen substances, a set of postcoordinated expressions can automatically be batch authored (as shown below).
Expression Template
: = [[+id @Substance]]
List of Substances
Resulting Expressions
: = : = : = : = : =
Expression Templates are also useful for creating postcoordinated expressions from data entered in a user interface. For example, a radiology user interface may use two separate fields to capture the imaging procedure and the body site to which the procedure was applied. An expression template can then be applied to combine the data entered into these two fields into a single postcoordinated expression (see diagram below).
Expression templates can be used to author precoordinated clinical meanings by providing reusable patterns for the definition of similar concepts. Expression templates can define the set of attributes and attribute values that may be used to define concepts in a specific hierarchy or subhierarchy, thereby assisting SNOMED CT authors to create concepts in a consistent way. They can also be used together with an input file to either create or update batches of concepts very efficiently. Using expression templates to author SNOMED CT concepts can help to improve the quality of the terminology, by controlling the consistency of the definitions, and by validating concept definition against appropriate templates. Similarly, they can also be used as a metric to measure the quality of given subhierarchy.
In summary, expression templates can be used by terminology authors to:
Create a single concept, or a batch of concepts;
Update the definition of a concept (or batch of concepts) to conform to a particular pattern;
Validate the definition of concept or a set of concepts;
Define quality metrics for a particular subhierarchy.
The example below shows an expression template that may be used to define computed tomography (CT) concepts of a particular body site (e.g. CT of right arm). The 'bodysite' slot represents the placeholder, which is subsequently replaced with a specific body site concept to form a complete concept definition.
Example: An example expression template
The following examples show the expressions that result when processing the template using a specific slot value:
bodySite:
Resulting Expression:
bodySite:
Resulting Expression:
Example: Expressions that result from populating the example expression template


Replacement slots serve as a placeholder for a value that is not known at the time of authoring, but which can be completed at a subsequent time using data recorded elsewhere (such as in an information model or entered into a data entry form). A slot indicates that it may be replaced by a value by including a plus sign ( + ) as the first symbol within the slot. Replacement slots may be used in an expression template wherever a concept, expression or symbol may appear within an expression.
A replacement slot may be used to delay the selection of a focus concept in an expression. For example, the expression template below uses a slot to indicate that the focus concept in the expression can be replaced with any appropriate SNOMED CT expression. This expression template represents any expression with a single refinement in which the | Laterality| equals | Right| .
If the following values are provided to complete the slot:
182245002 |Entire upper limb| 182281004 |Entire lower limb| 244486005 |Entire eye| 1910005 |Entire ear|
then the expressions that result from processing the template would be:
A replacement slot may also be used to replace an attribute value in an expression. For example, the expression template below represents any expression with a focus concept of | Clinical finding| and a refinement which uses the attribute | Finding site| . The value of the | Finding site| attribute may be replaced by any valid value at a future time.
If the following value is provided to complete the slot:
then the expression that results from processing the template would be:
If, however, the value provided to complete the slot was the expression:
then the result of processing the template would be:
Please note that the template processor must add round brackets around the subexpression to ensure that the resulting expression is syntactically valid.
A replacement slot may also be used to replace an attribute name in an expression. For example, the expression template below represents any expression with a focus concept of and a refinement whose value equals The attribute name in the expression may be replaced by any valid attribute concept at a future time.
If the following values are provided to complete the slot:
then the expressions that result from processing the template would be:
To be added to Introduction: Later in 2020, the syntax was updated (v1.2) to support the following features:
Default slot values
Inter-slot cross references
SameValue and allOrNone constraints
The following ABNF definition specifies the SNOMED CT template syntax. This syntax incorporates the Expression Constraint Language version 1.3 (ECL v1.3), with some adaptations to support slot references.
Please note that some of the rules referenced below are defined elsewhere. In particular, definitionStatus and expression are defined in SNOMED CT compositional grammar. These rule definitions must therefore be combined with the syntax below before it can be used.
; Template Syntax v1.1
templateSlot = templateReplacementSlot / templateInformationSlot
templateReplacementSlot = conceptReplacementSlot / expressionReplacementSlot / tokenReplacementSlot / concreteValueReplacementSlot
conceptReplacementSlot = "[[" ws "+" ws conceptReplacement [slotName ws] "]]"
expressionReplacementSlot = "[[" ws "+" ws expressionReplacement [slotName ws] "]]"
tokenReplacementSlot = "[[" ws "+" ws tokenReplacement [slotName ws] "]]"
concreteValueReplacementSlot = "[[" ws "+" ws concreteValueReplacement [slotName ws] "]]"
conceptReplacement = "id" ws [ "(" ws slotExpressionConstraint ws ")" ws] [conceptDefault ws]
expressionReplacement = ["scg" ws] ["(" ws slotExpressionConstraint ws ")" ws] [expressionDefault ws]
tokenReplacement = "tok" ws [ "(" ws slotTokenSet ws ")" ws] [tokenDefault ws]
**concreteValueReplacement **= stringReplacement / integerReplacement / decimalReplacement / booleanReplacement
**stringReplacement **= "str" ws [ "(" ws slotStringSet ws ")" ws] [stringDefault ws]
******integerReplacement ** ****= "int" ws [ "(" ws slotIntegerSet ws ")" ws] [integerDefault ws]
**decimalReplacement **= "dec" ws [ "(" ws slotDecimalSet ws ")" ws] [decimalDefault ws]
**booleanReplacement **= "bool" ws [ "(" ws slotBooleanSet ws ")" ws] [booleanDefault ws]
slotTokenSet = slotToken *(mws slotToken)
slotStringSet = slotString *(mws slotString)
slotIntegerSet = ( slotIntegerValue / slotIntegerRange) *(mws (slotIntegerValue / slotIntegerRange))
slotDecimalSet = ( slotDecimalValue / slotDecimalRange) *(mws (slotDecimalValue / slotDecimalRange))
slotBooleanSet = slotBooleanValue *(mws slotBooleanValue)
slotIntegerRange = ( slotIntegerMinimum to [ slotIntegerMaximum ] ) / ( to slotIntegerMaximum )
slotIntegerMinimum = [ exclusiveMinimum ] slotIntegerValue
slotIntegerMaximum = [ exclusiveMaximum ] slotIntegerValue
slotIntegerValue = "#" digitNonZero *digit / "#" zero / slotReference
**slotDecimalRange **= ( slotDecimalMinimum to [ slotDecimalMaximum ] ) / ( to slotDecimalMaximum )
slotDecimalMinimum = [ exclusiveMinimum ] slotDecimalValue
slotDecimalMaximum = [ exclusiveMaximum ] slotDecimalValue
slotDecimalValue = "#" integerValue "." 1*digit
exclusiveMinimum = ">"
exclusiveMaximum = "<"
slotBooleanValue = true / false
true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
slotName = "@" (nonQuoteStringValue / slotString)
slotReference = "$" (nonQuoteStringValue / QM stringValue QM) [ws slotArrayReference]
slotReferenceList = slotReference *(ws "," ws slotReference)
slotArrayReference = "[" ws [numericComparisonOperator ws] (integerValue / self) ws "]"
self = ("s"/"S") ("e"/"E") ("l"/"L") ("f"/"F")
**slotToken **= definitionStatus / memberOf / constraintOperator / conjunction / disjunction / exclusion / reverseFlag / expressionComparisonOperator / numericComparisonOperator / stringComparisonOperator / booleanComparisonOperator / slotReference
**slotString **= QM stringValue QM
nonQuoteStringValue = *(%x21 / %x23-26 / %x2A-3F / %x41-5A / %x5C / %x5E-7E) ; string with no ws, quotes, at, square brackets or round brackets
conceptDefault = default ws "(" ws conceptId ws ")"
expressionDefault = default ws "(" ws expression ws ")"
tokenDefault = default ws "(" ws slotToken ws ")"
stringDefault = default ws "(" ws slotString ws ")"
integerDefault = default ws "(" ws "#" integerValue ws ")"
decimalDefault = default ws "(" ws "#" decimalValue ws ")"
booleanDefault = default ws "(" ws booleanValue ws ")"
default = ("d"/"D") ("e"/"E") ("f"/"F") ("a"/"A") ("u"/"U") ("l"/"L") ("t"/"T")
**templateInformationSlot = **"[[" ws slotInformation ws "]]"
slotInformation = [cardinality ws] [slotName ws] *(sameValue / allOrNone)
sameValue = ("s"/"S") ("a"/"A") ("m"/"M") ("e"/"E") ("v"/"V") ("a"/"A") ("l"/"L") ("u"/"U") ("e"/"E") ws "(" ws slotReferenceList ws ")"
allOrNone = ("a"/"A") ("l"/"L") ("l"/"L") ("o"/"O") ("r"/"R") ("n"/"N") ("o"/"O") ("n"/"N") ("e"/"E") ws "(" ws slotReferenceList ws ")"
; Expression Constraint Language v1.4 with slot References
slotExpressionConstraint = ws ( slotRefinedExpressionConstraint / slotCompoundExpressionConstraint / slotDottedExpressionConstraint / slotSubExpressionConstraint ) ws
slotRefinedExpressionConstraint = slotSubExpressionConstraint ws ":" ws slotEclRefinement
slotCompoundExpressionConstraint = slotConjunctionExpressionConstraint / slotDisjunctionExpressionConstraint / slotExclusionExpressionConstraint
slotConjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws conjunction ws slotSubExpressionConstraint)
slotDisjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws disjunction ws slotSubExpressionConstraint)
slotExclusionExpressionConstraint = slotSubExpressionConstraint ws exclusion ws slotSubExpressionConstraint
slotDottedExpressionConstraint = slotSubExpressionConstraint 1*(ws slotDottedExpressionAttribute)
slotDottedExpressionAttribute = dot ws slotEclAttributeName
slotSubExpressionConstraint = [constraintOperator ws] [memberOf ws] (slotEclFocusConcept / "(" ws slotExpressionConstraint ws ")")
slotEclFocusConcept = slotEclConceptReference / wildCard
dot = "."
memberOf = "^"
slotEclConceptReference = conceptId [ws "|" ws term ws "|"] / slotReference
conceptId = sctId
term = 1nonwsNonPipe ( 1SP 1nonwsNonPipe )
wildcard = "*"
constraintOperator = childOf / descendantOrSelfOf / descendantOf / parentOf / ancestorOrSelfOf / ancestorOf
descendantOf = "<"
descendantOrSelfOf = "<<"
childOf = "<!"
ancestorOf = ">"
ancestorOrSelfOf = ">>"
parentOf = ">!"
conjunction = (("a"/"A") ("n"/"N") ("d"/"D") mws) / ","
disjunction = ("o"/"O") ("r"/"R") mws
exclusion = ("m"/"M") ("i"/"I") ("n"/"N") ("u"/"U") ("s"/"S") mws
slotEclRefinement = slotSubRefinement ws [slotConjunctionRefinementSet / slotDisjunctionRefinementSet]
slotConjunctionRefinementSet = 1*(ws conjunction ws slotSubRefinement)
slotDisjunctionRefinementSet = 1*(ws disjunction ws slotSubRefinement)
slotSubRefinement = slotEclAttributeSet / slotEclAttributeGroup / "(" ws slotEclRefinement ws ")"
slotEclAttributeSet = slotSubAttributeSet ws [slotConjunctionAttributeSet / slotDisjunctionAttributeSet]
slotConjunctionAttributeSet = 1*(ws conjunction ws slotSubAttributeSet)
slotDisjunctionAttributeSet = 1*(ws disjunction ws slotSubAttributeSet)
slotSubAttributeSet = slotEclAttribute / "(" ws slotEclAttributeSet ws ")"
slotEclAttributeGroup = ["[" cardinality "]" ws] "{" ws slotEclAttributeSet ws "}"
slotEclAttribute = ["[" cardinality "]" ws] [reverseFlag ws] slotEclAttributeName ws (expressionComparisonOperator ws slotSubExpressionConstraint / numericComparisonOperator ws slotNumericValue / stringComparisonOperator ws slotStringValue / booleanComparisonOperator ws booleanValue)
cardinality = minValue to maxValue
minValue = nonNegativeIntegerValue
to = ".."
maxValue = nonNegativeIntegerValue / many
many = "*"
reverseFlag = "R"
slotEclAttributeName = slotSubExpressionConstraint
expressionComparisonOperator = "=" / "!="
numericComparisonOperator = "=" / "!=" / "<=" / "<" / ">=" / ">"
stringComparisonOperator = "=" / "!="
**booleanComparisonOperator **= "=" / "!="
slotNumericValue = "#" ["-"/"+"] (slotDecimalValue / slotIntegerValue) / slotReference
slotStringValue = QM 1*(anyNonEscapedChar / escapedChar) QM / slotReference
integerValue = digitNonZero *digit / zero
decimalValue = integerValue "." 1*digit
slotBooleanValue = true / false / slotReference
true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
nonNegativeIntegerValue = (digitNonZero *digit ) / zero
sctId = digitNonZero 5*17( digit )
ws = *( SP / HTAB / CR / LF / comment ) ; optional white space
mws = 1*( SP / HTAB / CR / LF / comment ) ; mandatory white space
comment = "/*" (nonStarChar / starWithNonFSlash) "/"
nonStarChar = SP / HTAB / CR / LF / %x21-29 / %x2B-7E /UTF8-2 / UTF8-3 / UTF8-4
starWithNonFSlash = %x2A nonFSlash
nonFSlash = SP / HTAB / CR / LF / %x21-2E / %x30-7E /UTF8-2 / UTF8-3 / UTF8-4
SP = %x20 ; space
HTAB = %x09 ; tab
CR = %x0D ; carriage return
LF = %x0A ; line feed
QM = %x22 ; quotation mark
BS = %x5C ; back slash
digit = %x30-39
zero = %x30
digitNonZero = %x31-39
nonwsNonPipe = %x21-7B / %x7D-7E / UTF8-2 / UTF8-3 / UTF8-4
anyNonEscapedChar = SP / HTAB / CR / LF / %x20-21 / %x23-5B / %x5D-7E / UTF8-2 / UTF8-3 / UTF8-4
escapedChar = BS QM / BS BS
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BFIn this section, we explain the steps involved in generating a set of SNOMED CT expressions from a SNOMED CT expression template and a set of input data. As illustrated in Processing Expression Templates, this includes:
Adding repetition and connectors;
Replacing slot values;
Removing information slots; and
Cleaning up.
Please note that these steps do not necessarily need to be performed in this order.
Expression templates may use explicit or default cardinalities to indicate parts of the expression that may be repeated (i.e. where the maximum cardinality is great than 1). In particular, a focus concept may be repeated, a relationship group may be repeated, or an attribute-value pair may be repeated. Repetition, however, is only required when multiple values are provided in the input data for a particular part of the template (see ). When multiple values are found in the input data, and this corresponds to a repeatable part of the expression template, the associated part of the expression must be duplicated to enable each separate value to be included.
For example, let's consider the following expression template and input data.
The input data above includes 2 focus concepts, 2 relationship groups, and 2 CausedBy attribute-name value pairs in the first relationship group. To support this input data, the expression template must duplicate the focus concept, relationship group, and the attribute name-value pair (in the first relationship group).
When parts of an expression template are repeated, it is important to ensure that the correct connector is added between repeated parts. For example, a "+" is added between repeated focus concepts, a "," is added between repeated relationship groups (although this is optional), and a "," is added between repeated name-value pairs.
The result of adding repetition and connectors to the above expression template (for the given input data) is shown below:
Please note that when an expression is used to populate an attribute value, it may be required to add brackets around the attribute value to ensure syntactic correctness of the resulting expression
With the repetition and connectors in place, the replacement slots must now be replaced with values. Each definition status, focus concept, attribute name and attribute value replacement slot must be removed, and the corresponding value from the input data inserted into the expression. After this step, the expression template above would look like the following:
Once the information contained in the information slots has been interpreted and processed, the information slots can be removed from the template. After this step, the expression template above would look like the following:
Clean up is an activity that can occur at any or all stages of template processing. However, any clean up that has not occurred during the previous stages, should be performed before completion.
In particular, this step involves removing any extra brackets (i.e. "( ... )"), braces (i.e. "{ ... }"), colons (i.e. ":"), equals (i.e. "="), attribute names or connectors (i.e. "+" or ",") that would cause the resulting expression to be syntactically invalid. Extraneous characters are most likely to occur when optional parts of an expression template have no corresponding value in the populated expression. When this occurs, clean up may be required to remove these characters.
In our example expression above, this step would involve removing the second instance of the attribute name , the comma before it, and the equals signs after. The resulting expression would look like:
The value that can be used to replace a slot in an expression template may be constrained by an expression constraint, value list constraint or range constraint (depending on the type of replacement slot). The following types of slot constraint may be used:
Expression constraints may be used to constrain replacement slots of type id and scg
Value list constraints may be used to constrain replacement slots of type tok, str, int, dec and bool.
Unlike replacement slots, information slots are added to an expression template purely to provide metadata about how the template should be processed. When an expression template is processed, the information contained in the information slots is used and then the information slot itself is removed.
Information slots may be added to an expression template in one of three places:
Before a focus concept slot to indicate information about the focus concept that follows,
Before a relationship group to indicate information about the relationship group that follows, and
1
80166006 |Streptococcus pyogenes|
1
58718002 |Rheumatic fever|
19342008 | Subacute disease|
2
113985000 |Streptococcus gallolyticus|
2
1
49872002 |Virus|
1
1
40733004 |Disorder due to infection|
1
Range constraints may be used to constrain replacement slots of type int and dec.
The following sections provide examples of each of these types of replacement constraints.
Expression constraints may be used to constrain the values permitted to replace a slot of type id or scg in an expression template.
For example, the slot in the following expression template can only be replaced by a concept reference that is a descendant or self of |Anatomical or acquired body structure|.
Because the concept | Shoulder region structure| is a descendant or self of | Anatomical or acquired body structure| , it may be used to replace the slot in the above expression template, resulting in the following expression.
However, the concept | Nonspecific site| may not be used as a replacement (because it is not a descendant or self of | Anatomical or acquired body structure| ).
Similarly, in the following expression template, the slot can be replaced by any expression that is a descendant of | Anatomical or acquired body structure| .
Value list constraints can be used to constrain the possible values that may replace slots of type tok, str, int, dec and bool.
For example, the following expression template uses a value list constraint to specify the possible definitionStatus tokens that may be used. The slot in this expression template may be replaced with either the token "<<<" or the token "===".
If the causative agent is assigned the value | Amoxicillin| then the following two expressions can be generated (depending on the token selected to replace the first slot).
The expression template below uses a value list constraint to constrain the value of the slot to the string "PANADOL", the string "TYLENOL", or the string “HERRON”.
Depending on the value used to replace the slot, any of the following three expressions may be generated.
In the next example, a value constraint is used to constrain a replacement slot of type int. In this case, the slot may be replaced by the integer values 10, 20 or 30.
The possible expressions that may be generated by filling the slot are:
Range constraints can be used by slots of type int or dec to constrain the permitted replacement values. Range constraints may specify the minimum permitted value, the maximum permitted value, or both. By default, ranges are inclusive (that is, the range includes the stated minimum and maximum values). However exclusive ranges (in which the stated minimum or maximum is not itself allows as a value) may be specified.
For example, the following expression template allows any pack size to be used that is between 20 and 30 capsules (inclusive).
To specify exclusive minimum values, a greater than sign (‘>’) is placed before the minimum value, and to specify exclusive maximum values, a less than sign (‘<’) is placed before the maximum value. For example, the following expression template allows any pack size that is between 20 and 30 capsules (exclusive). This range constraint is equivalent to an inclusive range of 21..29.
Multiple ranges may be specified in a single range constraint. When multiple ranges are specified, these should be interpreted as alternative ranges. For example, the expression template below permits any pack size between 10 and 20 capsules (inclusive), or between 30 and 40 capsules (inclusive). This template does not, for example, permit a pack size between 21 and 29 capsules.
When a minimum value is required with no maximum, it is possible to omit the maximum value in a range constraint. For example, the expression template below permits any pack size greater than or equal to 20 capsules.
Similarly, it is also possible to state a maximum without a minimum constraint. For example, the expression template below permits any pack size less than or equal to 20 capsules. It should be noted that without a concept model rule to ensure that all pack sizes are greater than zero, this template will, by default, allow a pack size of zero or a negative pack size to be defined.
Information slots may include either a cardinality constraint or a slot name (or both). In the following sections, we describe how each of these may be used in an information slot.
One of the important roles of an information slot is to specify the cardinality of the expression part that follows. A cardinality constraint states the minimum and maximum number of times that the focus concept, relationship group or attribute name-value pair that follows may be repeated in an expression that is generated from the given template.
For example, the expression template below allows between one and three concepts to be used to populate the finding slot, and exactly one _ | Finding site| _ name-value pair.
Based on the cardinality specified in the information slots, the finding slot could be replaced by the two concepts | Infectious disease| and | Congenital disease| and the site slot could be replaced by the concept | Lung structure| to generate the following expression:
Please note that when two or more concepts are used to replace a focus concept slot in an expression template, a plus sign ( + ) must be added between them to ensure the resulting expression is syntactically valid.
When a cardinality constraint is not provided in an information slot preceding a focus concept, relationship group or attribute name-value pair, the default cardinality that is assumed is 1..*. This means that by default focus concepts, relationship groups and attribute name-value pairs must appear at least once in the resulting expression, but may also be repeated many times. The SNOMED CT concept model, if enforced, may also impose some additional cardinality constraints on the number of times an attribute may be repeated. However, these additional concept model rules are not directly implied by the expression template itself.
As an example, the following expression template allows one or more procedures to be collectively refined by one or more relationship groups, each containing one or more values for | Method| and | Procedure site - Direct| .
The above expression template is therefore equivalent to the following template, in which the cardinality of 1..* is explicitly stated on the focus concept, the relationship group, and each attribute name-value pair.
The replacement slots in this expression template could, for example, be replaced to generate the following expression:
Please note that if the international SNOMED CT concept model was enforced, the above expression would not be valid due to the 260686004 | Method| appearing twice in the one relationship group.
Information slots can also be given a slot name, to allow the expression part that follows the slot (i.e. focus concept, relationship group, or attribute name-value pair) to be referenced. The most common use of information slot names is to support the process of populating the template (e.g. as part of a programmatic value replacement process).
For example, the following expression template uses the name mpGroup to name the relationship group that contains both a | Method| and a | Procedure site - Direct|
When values within a SNOMED CT expression, expression constraint or query are unknown at the time of authoring, a SNOMED CT template may be used. The SNOMED CT template syntax can be used in conjunction with the SNOMED CT computable languages to create SNOMED CT template languages for this purpose. For example:
Using the template syntax with SNOMED CT compositional grammar enables the representation of expression templates
Using the template syntax with the SNOMED CT expression constraint language enables the representation of expression constraint templates
Using the template syntax with the SNOMED CT query language (1) enables the representation of query templates.
This version of the SNOMED CT template syntax specifically focuses on supporting two important use cases in which the SNOMED CT template syntax is needed. In particular to support:
These use cases specifically require the use of slots within SNOMED CT Compositional Grammar. Therefore, this version of the specification focuses primarily on supporting the use of the template syntax within the context of the . Future versions of this specification will explore other use cases, and additional template languages (e.g. the Expression Constraint Template Language).
1
Please note that the SNOMED CT query language is not yet available.
The following sections describe the rules used by the Template Syntax. This syntax is a serialised representation of the logical model presented in the previous chapter, and is considered to be the normative syntax for interoperability purposes.
In addition to the simple examples shown on the previous pages, more advanced expression templates can also be used. On this page we show some examples of expression constraints with multiple replacement slots, multiple cardinality constraints and slot co-dependency constraints.
In many situations, it is useful for an expression template to contain more than one replacement slot. Below are some examples.
The following expression template uses three replacement slots to generate an expression that represents a type of procedure. The first slot (named "Procedure") is a placeholder for the focus concept, while the second slot (named "BodySite") is a placeholder for the | Procedure site - Direct| , and the third slot (named "Method") is a placeholder for the | Method| .
If the slots are populated with the values:
Procedure = 387713003 | Surgical procedure|
BodySite =
Method =
then the following expression would be generated.
Another example of an expression template with multiple slots is shown below. This expression template is used to generate expressions that represent the family history of a patient. The template contains two slots - the first slot (named "Finding") is a placeholder for the known to be present in the family member, while the second slot (named "Relationship") is a placeholder for the of this .
If the following input data is provided (in which each row represents a separate expression):
Then the following family history expressions would be generated.
Expression templates may also use more than one cardinality constraint to indicate the repeatability of different parts of the expression. Below are some examples.
The following expression template uses three replacement slots to generate an expression that represents a type of procedure. The first slot (named "Procedure") is a placeholder for the focus concept, while the second slot (named "BodySite") is a placeholder for the , and the third slot (named "Method") is a placeholder for the .
The first cardinality constraint (i.e. 1..1 ) indicates that exactly one value should be populated in the Procedure slot. The second cardinality constraint (i.e. 1..2 ) indicates that it is valid to include either 1 or 2 relationship groups in the resulting expression. The last two cardinality constraints, that appear inside the relationship group, (i.e. 1..1 ) indicate that in each instance of a relationship group, exactly one value and exactly one value should be used.
The following input data satisfies these cardinality constraints.
If the slots are populated with the values above, then the following expressions would be generated
Another example of an expression template with multiple cardinality constraints is shown below. This expression template is used to generate expressions that represent a clinical finding with explicit context.
The first cardinality constraint (i.e. 1..1 ) indicates that exactly one value should be populated in the Condition slot. The second cardinality constraint (i.e. 1..2 ) indicates that it is valid to include either 1 or 2 relationship groups (named "AFgroup") in the resulting expression. Each AFgroup relationship group must have exactly one , exactly one , exactly one and exactly one . The value of the in each AFgroup is an expression, may optionally be refined using a single relationship group named "SSgroup". Each SSgroup optionally has one and optionally has one . Based on these cardinality constraints, the input data shown in would be valid.
Table 8.6-1: Valid Input Data for Example 2
If the slots are populated with the values above, then the following expressions would be generated.
Please note that when part of an expression is repeated, connectors (e.g. a comma) must be added between the parts during processing. Similarly, when part of an expression is absent then clean up is required (e.g. to remove commas and brackets). For more information on these processing steps, please refer to .
In this chapter, we present a variety of examples to illustrate how the template syntax defined in Syntax Specification can be used to represent expression templates. A SNOMED CT expression template is a SNOMED CT expression, which contains one or more template slots. As defined in Syntax Specification, all template slots are represented using a pair of double square brackets - i.e. [[ ]].
There are two main types of template slots:
Replacement Slots , which are replaced by a concept, expression or string during template processing, and
Information Slots , which are purely there to provide metadata about how the template is to be processed.
The following ABNF definition specifies the SNOMED CT template syntax (v1.1.1). This syntax incorporates the Expression Constraint Language version 1.4 (ECL v1.4), with some adaptations to support slot references. It also incorporates 3 rules from Compositional Grammar (SCG v2.4) to ensure that the definitionStatus rule is defined.
; Template Syntax v1.1
templateSlot = templateReplacementSlot / templateInformationSlot
templateReplacementSlot = conceptReplacementSlot / expressionReplacementSlot / tokenReplacementSlot / concreteValueReplacementSlot
conceptReplacementSlot = "[[" ws "+" ws conceptReplacement [slotName ws] "]]"
expressionReplacementSlot = "[[" ws "+" ws expressionReplacement [slotName ws] "]]"
tokenReplacementSlot = "[[" ws "+" ws tokenReplacement [slotName ws] "]]"
concreteValueReplacementSlot = "[[" ws "+" ws concreteValueReplacement [slotName ws] "]]"
conceptReplacement = "id" ws [ "(" ws slotExpressionConstraint ws ")" ws]
expressionReplacement = ["scg" ws] ["(" ws slotExpressionConstraint ws ")" ws]
tokenReplacement = "tok" ws [ "(" ws slotTokenSet ws ")" ws]
concreteValueReplacement = stringReplacement / integerReplacement / decimalReplacement / booleanReplacement
stringReplacement = "str" ws [ "(" ws slotStringSet ws ")" ws]
integerReplacement = "int" ws [ "(" ws slotIntegerSet ws ")" ws]
decimalReplacement = "dec" ws [ "(" ws slotDecimalSet ws ")" ws]
booleanReplacement = "bool" ws [ "(" ws slotBooleanSet ws ")" ws]
slotTokenSet = slotToken *(mws slotToken)
slotStringSet = slotStringValue *(mws slotStringValue)
slotStringValue = QM stringValue QM
slotIntegerSet = ( slotIntegerValue / slotIntegerRange) *(mws (slotIntegerValue / slotIntegerRange))
slotDecimalSet = ( slotDecimalValue / slotDecimalRange) *(mws (slotDecimalValue / slotDecimalRange))
slotBooleanSet = slotBooleanValue *(mws slotBooleanValue)
slotBooleanValue = booleanValue
slotIntegerRange = ( slotIntegerMinimum to [ slotIntegerMaximum ] ) / ( to slotIntegerMaximum )
slotIntegerMinimum = [ exclusiveMinimum ] slotIntegerValue
slotIntegerMaximum = [ exclusiveMaximum ] slotIntegerValue
slotIntegerValue = "#" ["-"/"+"] integerValue
slotDecimalRange = ( slotDecimalMinimum to [ slotDecimalMaximum ] ) / ( to slotDecimalMaximum )
slotDecimalMinimum = [ exclusiveMinimum ] slotDecimalValue
slotDecimalMaximum = [ exclusiveMaximum ] slotDecimalValue
slotDecimalValue = "#" ["-"/"+"] decimalValue
exclusiveMinimum = ">"
exclusiveMaximum = "<"
slotName = "@" (slotStringValue / nonQuoteStringValue)
slotToken = definitionStatus / memberOf / constraintOperator / conjunction / disjunction / exclusion / reverseFlag / expressionComparisonOperator / numericComparisonOperator / stringComparisonOperator /booleanComparisonOperator
nonQuoteStringValue = *(%x21 / %x23-26 / %x2A-3F / %x41-5A / %x5C / %x5E-7E) ; string with no ws, quotes, at, square brackets or round brackets
templateInformationSlot = "[[" ws slotInformation ws "]]"
slotInformation = [cardinality ws] [slotName ws]
; Expression Constraint Language v1.4
slotExpressionConstraint = ws ( slotRefinedExpressionConstraint / slotCompoundExpressionConstraint / slotDottedExpressionConstraint / slotSubExpressionConstraint ) ws
slotRefinedExpressionConstraint = slotSubExpressionConstraint ws ":" ws slotEclRefinement
slotCompoundExpressionConstraint = slotConjunctionExpressionConstraint / slotDisjunctionExpressionConstraint / slotExclusionExpressionConstraint
slotConjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws conjunction ws slotSubExpressionConstraint)
slotDisjunctionExpressionConstraint = slotSubExpressionConstraint 1*(ws disjunction ws slotSubExpressionConstraint)
slotExclusionExpressionConstraint = slotSubExpressionConstraint ws exclusion ws slotSubExpressionConstraint
slotDottedExpressionConstraint = slotSubExpressionConstraint 1*(ws slotDottedExpressionAttribute)
slotDottedExpressionAttribute = dot ws slotEclAttributeName
slotSubExpressionConstraint = [constraintOperator ws] [memberOf ws] (slotEclFocusConcept / "(" ws slotExpressionConstraint ws ")")
slotEclFocusConcept = slotEclConceptReference / wildCard
dot = "."
memberOf = "^"
slotEclConceptReference = conceptId [ws "|" ws term ws "|"]
conceptId = sctId
term = 1nonwsNonPipe ( 1SP 1nonwsNonPipe )
wildcard = "*"
constraintOperator = childOf / descendantOrSelfOf / descendantOf / parentOf / ancestorOrSelfOf / ancestorOf
descendantOf = "<"
descendantOrSelfOf = "<<"
childOf = "<!"
ancestorOf = ">"
ancestorOrSelfOf = ">>"
parentOf = ">!"
conjunction = (("a"/"A") ("n"/"N") ("d"/"D") mws) / ","
disjunction = ("o"/"O") ("r"/"R") mws
exclusion = ("m"/"M") ("i"/"I") ("n"/"N") ("u"/"U") ("s"/"S") mws
slotEclRefinement = slotSubRefinement ws [slotConjunctionRefinementSet / slotDisjunctionRefinementSet]
slotConjunctionRefinementSet = 1*(ws conjunction ws slotSubRefinement)
slotDisjunctionRefinementSet = 1*(ws disjunction ws slotSubRefinement)
slotSubRefinement = slotEclAttributeSet / slotEclAttributeGroup / "(" ws slotEclRefinement ws ")"
slotEclAttributeSet = slotSubAttributeSet ws [slotConjunctionAttributeSet / slotDisjunctionAttributeSet]
slotConjunctionAttributeSet = 1*(ws conjunction ws slotSubAttributeSet)
slotDisjunctionAttributeSet = 1*(ws disjunction ws slotSubAttributeSet)
slotSubAttributeSet = slotEclAttribute / "(" ws slotEclAttributeSet ws ")"
slotEclAttributeGroup = ["[" cardinality "]" ws] "{" ws slotEclAttributeSet ws "}"
slotEclAttribute = ["[" cardinality "]" ws] [reverseFlag ws] slotEclAttributeName ws (expressionComparisonOperator ws slotSubExpressionConstraint / numericComparisonOperator ws (slotIntegerValue /slotDecimalValue) / stringComparisonOperator ws slotStringValue / booleanComparisonOperator ws slotBooleanValue)
cardinality = minValue to maxValue
minValue = nonNegativeIntegerValue
to = ".."
maxValue = nonNegativeIntegerValue / many
many = "*"
reverseFlag = "R"
slotEclAttributeName = slotSubExpressionConstraint
expressionComparisonOperator = "=" / "!="
numericComparisonOperator = "=" / "!=" / "<=" / "<" / ">=" / ">"
stringComparisonOperator = "=" / "!="
booleanComparisonOperator = "=" / "!="
stringValue = 1*(anyNonEscapedChar / escapedChar)
integerValue = digitNonZero *digit / zero
decimalValue = integerValue "." 1*digit
booleanValue = true / false
true = ("t"/"T") ("r"/"R") ("u"/"U") ("e"/"E")
false = ("f"/"F") ("a"/"A") ("l"/"L") ("s"/"S") ("e"/"E")
nonNegativeIntegerValue = (digitNonZero *digit ) / zero
sctId = digitNonZero 5*17( digit )
ws = *( SP / HTAB / CR / LF / comment ) ; optional white space
mws = 1*( SP / HTAB / CR / LF / comment ) ; mandatory white space
comment = "/*" (nonStarChar / starWithNonFSlash) "/"
nonStarChar = SP / HTAB / CR / LF / %x21-29 / %x2B-7E /UTF8-2 / UTF8-3 / UTF8-4
starWithNonFSlash = %x2A nonFSlash
nonFSlash = SP / HTAB / CR / LF / %x21-2E / %x30-7E /UTF8-2 / UTF8-3 / UTF8-4
SP = %x20 ; space
HTAB = %x09 ; tab
CR = %x0D ; carriage return
LF = %x0A ; line feed
QM = %x22 ; quotation mark
BS = %x5C ; back slash
digit = %x30-39
zero = %x30
digitNonZero = %x31-39
nonwsNonPipe = %x21-7B / %x7D-7E / UTF8-2 / UTF8-3 / UTF8-4
anyNonEscapedChar = SP / HTAB / CR / LF / %x20-21 / %x23-5B / %x5D-7E / UTF8-2 / UTF8-3 / UTF8-4
escapedChar = BS QM / BS BS
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
; Additional rules from Compositional Grammar v2.4
definitionStatus = equivalentTo / subtypeOf
equivalentTo = "==="
subtypeOf = "<<<"2
28231008 |Gallbladder structure|
129304002 |Excision - action|
387713003 |Surgical procedure|
1
66754008 |Appendix structure|
129304002 |Excision - action|
24484000 |Severe|
444292000 |Paternal grandfather of subject|
410512000 |Current or specified time|
410515003 |Known present|
2
22298006 |Myocardial infarction|
444292000 |Paternal grandfather of subject|
410589000 |All times past|
410516002 |Known absent|
57177007 |Family history with explicit context|
1
363346000 |Cancer|
6736007 |Moderate|
76752008 |Breast structure|
444244000 |Maternal grandmother of subject|
410512000 |Current or specified time|
410515003 |Known present|
160303001 |FH: Diabetes mellitus|
1
46635009 |Diabetes mellitus type 1|
444301002 |Mother of subject|
410512000 |Current or specified time|
410515003 |Known present|
387713003 |Surgical procedure|
1
28273000 |Bile duct structure|
281615006 |Exploration - action|
243796009 |Situation with explicit context|
1
56265001 |Heart disease|
This section provides a brief description of each rule listed above in the normative specification.
templateSlot = templateReplacementSlot / templateInformationSlot | A template slot is part of a template that is either replaced with a value (i.e. a templateRelacementSlot), or removed after the information it contains is interpreted (i.e. a templateInformationSlot). templateReplacementSlot = conceptReplacementSlot / expressionReplacementSlot / tokenReplacementSlot / concreteValueReplacementSlot | A template replacement slot is a placeholder whose value can be completed at a subsequent time. A template replacement slot may be either a concept replacement slot, an expression replacement slot, a token replacement slot or a concrete value replacement slot. c****onceptReplacementSlot = "[[" ws "+" ws conceptReplacement [slotName ws] "]]"
| A concept replacement slot starts and ends with double square brackets (i.e. "[[ ... ]]"). The first non-whitespace character inside the brackets must always be a plus sign (i.e. "+"), followed by the concept replacement rule and an optional slot name. expressionReplacementSlot = "[[" ws "+" ws expressionReplacement [slotName ws] "]]"
| An expression replacement slot starts and ends with double square brackets (i.e. "[[ ... ]]"). The first non-whitespace character inside the brackets must always be a plus sign (i.e. "+"), followed by the expression replacement rule and an optional slot name. tokenReplacementSlot = "[[" ws "+" ws tokenReplacement [slotName ws] "]]"
| A token replacement slot starts and ends with double square brackets (i.e. "[[ ... ]]"). The first non-whitespace character inside the brackets must always be a plus sign (i.e. "+"), followed by the token replacement rule and an optional slot name. concreteValueReplacementSlot = "[[" ws "+" ws concreteValueReplacement [slotName ws] "]]"
| A concrete value replacement slot starts and ends with double square brackets (i.e. "[[ ... ]]"). The first non-whitespace character inside the brackets must always be a plus sign (i.e. "+"), followed by the concrete value replacement rule and an optional slot name. conceptReplacement = "id" ws [ "(" ws slotExpressionConstraint ws ")" ws] | A concept replacement starts with the text "id", and then optionally includes an expression constraint (in round brackets) that restricts the valid values that may replace the slot. expressionReplacement = ["scg" ws] ["(" ws slotExpressionConstraint ws ")" ws] | An expression replacement starts (optionally) with the text "scg", and then optionally includes an expression constraint (in round brackets) to restrict the valid values that may replace the slot. Note that "scg" is the default type of replacement slot. tokenReplacement = "tok" ws [ "(" ws slotTokenSet ws ")" ws]
| A token replacement starts with the text "tok", and then optionally includes a token set (in round brackets) to restrict the valid values that may replace the slot. concreteValueReplacement = stringReplacement / integerReplacement / decimalReplacement / booleanReplacement
| A concrete value replacement may either be a string replacement, an integer replacement, a decimal replacement, or a boolean replacement. stringReplacement = "str" ws [ "(" ws slotStringSet ws ")" ws] | A string replacement starts with the text "str", and then optionally includes a string set (in round brackets) to restrict the valid values that may replace the slot. integerReplacement = "int" ws [ "(" ws slotIntegerSet ws ")" ws]
| An integer replacement starts with the text "int", and then optionally includes a integer set (in round brackets) to restrict the valid values that may replace the slot. decimalReplacement = "dec" ws [ "(" ws slotDecimalSet ws ")" ws]
| A decimal replacement starts with the text "dec", and then optionally includes a decimal set (in round brackets) to restrict the valid values that may replace the slot. booleanReplacement = "bool" ws [ "(" ws slotBooleanSet ws ")" ws]
| A boolean replacement starts with the text "bool", and then optionally includes a boolean set (in round brackets) to list the valid values that may replace the slot. slotTokenSet = slotToken *(mws slotToken)
| A slotTokenSet consists of one or more slotTokens separated by mandatory white space (i.e. mws). slotStringSet = slotStringValue *(mws slotStringValue) | A slotStringSet consists of one or more slotStringValues separated by mandatory white space (i.e. mws). slotStringValue = QM stringValue QM
| A slotStringValue is a stringValue surrounded with double quotation marks. slotIntegerSet = ( slotIntegerValue / slotIntegerRange) *(mws (slotIntegerValue / slotIntegerRange)) | A slotIntegerSet consists of one or more slotIntegerValues separated by mandatory white space (i.e. mws). slotDecimalSet = ( slotDecimalValue / slotDecimalRange) *(mws (slotDecimalValue / slotDecimalRange))
| A slotDecimalSet consists of one or more slotDecimals separated by mandatory white space (i.e. mws). slotBooleanSet** = slotBooleanValue (mws slotBooleanValue)*
| A slotBooleanSet consists of one or more slotBooleanValues separated by mandatory white space (i.e. mws). slotBooleanValue = booleanValue
| A slotBooleanValue is simply a boolean value (i.e. true or false). slotIntegerRange = ( slotIntegerMinimum to [ slotIntegerMaximum ] ) / ( to slotIntegerMaximum )
| A slotIntegerRange includes either a slotIntegerMinimum, a slotIntegerMaximum, or both. The slotIntegerMinimum and slotIntegerMaximum are separated by a 'to' token. slotIntegerMinimum = [ exclusiveMinimum ] slotIntegerValue
| A slotIntegerMinimum consists of a minimum slotIntegerValue. By default the minimum is inclusive (i.e. the minimum value is a valid value in the range). However, the minimum value may be declared to be exclusive (i.e. not a valid value in the range) by preceding it with the exclusiveMinimum symbol (i.e. ">"). slotIntegerMaximum = [ exclusiveMaximum ] slotIntegerValue
| A slotIntegerMaximum consists of a maximum slotIntegerValue. By default the maximum is inclusive (i.e. the maximum value is a valid value in the range). However, the maximum value may be declared to be exclusive (i.e. not a valid value in the range) by preceding it with the exclusiveMaximum symbol (i.e. "<"). slotIntegerValue = "#" ["-"/"+"] integerValue
| A slotIntegerValue consists of a hash symbol followed by an integer value, with an optional "+" or "-" just before the value. slotDecimalRange = ( slotDecimalMinimum to [ slotDecimalMaximum ] ) / ( to slotDecimalMaximum )
| A slotDecimalRange includes either a slotDecimalMinimum, a slotDecimalMaximum, or both. The slotDecimalMinimum and slotDecimalMaximum are separated by a 'to' token. slotDecimalMinimum = [ exclusiveMinimum ] slotDecimalValue
| A slotDecimalMinimum consists of a minimum slotDecimalValue. By default the minimum is inclusive (i.e. the minimum value is a valid value in the range). However, the minimum value may be declared to be exclusive (i.e. not a valid value in the range) by preceding it with the exclusiveMinimum symbol (i.e. ">"). slotDecimalMaximum = [ exclusiveMaximum ] slotDecimalValue
| A slotDecimalMaximum consists of a maximum slotDecimalValue. By default the maximum is inclusive (i.e. the maximum value is a valid value in the range). However, the maximum value may be declared to be exclusive (i.e. not a valid value in the range) by preceding it with the exclusiveMaximum symbol (i.e. "<"). slotDecimalValue = "#" ["-"/"+"] decimalValue
| A slotDecimalValue consists of a hash symbol followed by a decimal value, with an optional "+" or "-" just before the value. exclusiveMinimum = ">"
| The exclusiveMinimum symbol is ">". When used before the minimum value, it declares that this value is not a valid part of the range. exclusiveMaximum = "<"
| The exclusiveMaximum symbol is "<". When used before the maximum value, it declares that this value is not a valid part of the range. slotName = "@" (slotStringValue / nonQuoteStringValue)
| A slotName starts with an at symbol (i.e. "@"), followed by either a quoted or unquoted string. slotToken = definitionStatus / memberOf / constraintOperator / conjunction / disjunction / exclusion / reverseFlag / expressionComparisonOperator / numericComparisonOperator / stringComparisonOperator / booleanComparisonOperator
| A slotToken is any token from SNOMED CT Compositional Grammar or the SNOMED CT Expression Constraint Language. This includes the definitionStatus, memberOf, constraintOperator, conjunction, disjunction, exclusion, reverseFlag, expressionComparisonOperator, numericComparisonOperator, stringComparisonOperator and booleanComparisonOperator tokens. nonQuoteStringValue = *(%x21 / %x23-26 / %x28-3F / %x41-5A / %x5C / %x5E-7E) ; string with no ws, quotes, at or square brackets
| A nonQuoteStringValue includes any character that is not whitespace, quotes, or the @ symbol. templateInformationSlot = "[[" ws slotInformation ws "]]"
| A templateInformationSlot starts and ends with double square brackets (i.e. "[[ ... ]]"), and contains slotInformation. slotInformation = [cardinality ws] [slotName ws]
| A slotInformation consists of either a cardinality, a slotName or both.
The SNOMED CT Template Syntax defines a standard way to create templates for SNOMED CT expressions and expression constraints. It introduces slots as placeholders for values that can be filled in later, enabling reusable patterns for authoring, validation, and data entry. This syntax supports consistent, computable use of SNOMED CT across systems and is designed for both technical and non-technical users.
A SNOMED CT template is a SNOMED CT expression, expression constraint, or query that contains one or more slots. Each template slot either provides information as to how the template should be processed (i.e. an information slot), or serves as a placeholder for a specific value that may be completed at a subsequent time. Each replacement slot may have a replacement type (e.g. concept, expression, token, string, integer, decimal or boolean), a slot name, and a replacement constraint. Depending on the replacement type, the replacement constraint may either be an expression constraint, a value list constraint or a range constraint. Each information slot may have a cardinality and a slot name.
The SNOMED CT template syntax defines the syntax used for these slots, irrespective of the computable language in which they are embedded. Figure 4-1 below illustrates the abstract model of the SNOMED CT template syntax. Please note that no specific semantics should be attributed to each arrow in this diagram.
The figure below provides a non-normative representation of the logical model of the SNOMED CT Template Syntax using a UML class diagram.
Please note that each of the classes in this diagram corresponds to a rule in the syntax specification defined in Syntax Specification. For a short description of each of these, please refer to Informative Comments.
** **


After an expression template has been processed, it is important to validate the expressions that are generated. This validation process may include checking that:
Each expression is syntactically valid;
Each expression conforms to the structure and constraints defined in the template; and
Each expression is valid according to the SNOMED CT concept model.
Please note that concept model validation may not be required in all use cases.
The SNOMED CT expressions generated when processing an expression template must be syntactically valid according the SNOMED CT compositional grammar syntax. To test for syntactic correctness, an expression parser, based on the ABNF rules defined in the SNOMED CT compositional grammar specification is used. For more information, please refer to the section on Parsing.
The SNOMED CT expressions generated when processing an expression template must conform to the structure and constraints defined in the template. This includes:
Each part of the resulting expression should conform structurally to a correspond part of the template, in the same order that it appears in the template;
All mandatory parts of the expression template must appear at least once in the resulting expression (i.e. where the minimum cardinality is > 0);
All non-repeatable parts of the expression template must appear at most once in the resulting expression (ie. where the maximum cardinality is 1); and
Each token, concept, expression or value in the resulting expression, that was added as a result of replacing a slot, must conform to the type (e.g. id, scg) and value constraint (e.g. expression constraint, value list or range) defined in the corresponding slot;
In most cases, the SNOMED CT expressions generated when processing an expression template should conform to the SNOMED CT concept model. This can be tested automatically by checking for conformance with the rules defined in the SNOMED CT machine readable concept model (MRCM) in conjunction with a specific SNOMED CT substrate (e.g. the active concepts in the current SNOMED CT international edition). This includes determining the domains that the focus concepts belong to, checking that the attributes are valid for the given domains, checking that the attributes appear an appropriate number of times, and ensuring that the value of each attribute is in the correct range. For more information on using the MRCM to validate postcoordinated expressions please refer to MRCM section 6. Considerations.
