I’ve been mulling over the old expression syntax that was defined in the rules section of an archetype a few years ago, and that @pieterbos and @yampeku and I have been discussing. The following is an example.
rules
$apgar_breathing_value: Integer := /data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value
$apgar_heartrate_value: Integer := /data[id3]/events[id4]/data[id2]/items[id6]/value[id40]/value
$apgar_muscle_value: Integer := /data[id3]/events[id4]/data[id2]/items[id14]/value[id41]/value
$apgar_reflex_value: Integer := /data[id3]/events[id4]/data[id2]/items[id18]/value[id42]/value
$apgar_colour_value: Integer := /data[id3]/events[id4]/data[id2]/items[id22]/value[id43]/value
$apgar_total_value: Integer := /data[id3]/events[id4]/data[id2]/items[id26]/value[id44]/magnitude
Apgar_total: $apgar_total_value = $apgar_breathing_value + $apgar_heartrate_value + $apgar_muscle_value + $apgar_reflex_value + $apgar_colour_value
In the modern syntax, this would be something like:
rules
apgar_total_value: Integer
apgar_heartrate_value: Integer
apgar_breathing_value: Integer
apgar_reflex_value: Integer
apgar_muscle_value: Integer
apgar_colour_value: Integer
check apgar_total_value = apgar_heartrate_value + apgar_breathing_value + apgar_reflex_value + apgar_muscle_value + apgar_colour_value
bindings
path_bindings = <
["apgar_breathing_value"] = <"/data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value">
["apgar_heartrate_value"] = <"/data[id3]/events[id4]/data[id2]/items[id6]/value[id40]/value">
["apgar_muscle_value"] = <"/data[id3]/events[id4]/data[id2]/items[id14]/value[id41]/value">
["apgar_reflex_value"] = <"/data[id3]/events[id4]/data[id2]/items[id18]/value[id42]/value">
["apgar_colour_value"] = <"/data[id3]/events[id4]/data[id2]/items[id22]/value[id43]/value">
["apgar_total_value"] = <"/data[id3]/events[id4]/data[id2]/items[id26]/value[id44]/magnitude">
>
This is style of bindings currently used in GDL2 guidelines, and correctly separates out the expression (which has instance level semantics) from the bindings (which have multiple->single instance mapping semantics).
Now, if the data contained say 3 Apgar samples, i.e. 3 entire trees of instances to which these paths will map, the meaning of the expression check apgar_total_value = apgar_heartrate_value + apgar_breathing_value + apgar_reflex_value + apgar_muscle_value + apgar_colour_value
is as follows:
- for each top-level data instance (3 in this case)…
- traverse the expression tree, in the normal way, and for all vars in the expression tree,
- find the node at the path mapped to each right-hand-side variable,
- find the node at the path mapped to the left-hand side variable
- extract the data values into the parse tree and execute the expression
- traverse the expression tree, in the normal way, and for all vars in the expression tree,
Or in normal words: execute the expression for each of the 3 Apgar instance trees.
Notice that the symbolic variables get mapped only to data tree nodes within the same data hierarchy - and not to all possible permutations of mappings, which would be incoherent. The semantics of ‘expressions’ as applied to archetypes require some special processing, to ensure they are executed on coherent data shapes that match the archetype.
The relationship between each (instance-level) symbolic variable and its path (a constraint-level object which can match multiple instances) is clearly a ‘mapping’ or ‘binding’ one, whereby more than one value (in general) from the data will be mapped to the variable. The older expression
$apgar_breathing_value: Integer := /data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value
is thus not really the assignment it looks like, but is stating this binding. Indeed, it doesn’t make sense as a typed assignment, because the path and the symbols are operating at different levels of abstraction.
I therefore propose that the bridge between older archetypes that may have this construction, and proper type-safe rule expressions in archetypes is to interpret this syntax as a shorthand for the the following more modern expression + binding:
rules
...
apgar_breathing_value: Integer
bindings
path_bindings = <
["apgar_breathing_value"] = <"/data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value">
Ideally, a tool encountering the old pseudo-assignment expression would restructure it in the above form, i.e. silently upgrade the archetype.
There are more details to take care of, but this would fix one of the major issues. Feedback welcome.