On 02/02/2019 16:21, Pieter Bos wrote:
*From: *openEHR-technical
<openehr-technical-boun...@lists.openehr.org> on behalf of Thomas
Beale <thomas.be...@openehr.org>
*Reply-To: *For openEHR technical discussions
<openehr-technical@lists.openehr.org>
*Date: *Saturday, 2 February 2019 at 15:01
*To: *"openehr-technical@lists.openehr.org"
<openehr-technical@lists.openehr.org>
*Subject: *Re: Rules in archetypes - what are the requirements?
Assuming you meant to put 'id7' as the first one, I don't understand
what this achieves beyond just:
/events[id2]/data/items/element[id7]/value/magnitude >
/events[id2]/data/items/element[id4]/value/magnitude +
/events[id2]/data/items/element[id5]/value/magnitude +
/events[id2]/data/items/element[id6]/value/magnitude
which says the same thing, for all events in the runtime data that
conform to the /events[id2] branch of the structure.
Since the occurrences of events[id2] can be more than one,
/events[id2]/data/items/element[id7]/value/magnitude in the execution
environment (actual data) maps to a List<Real>.
well it could be understood that way - that would be to literally
interpret it as a runtime path. The way I think of it is to mean 'this
condition xyz must hold true' for each instance to which it applies.
This greatly simplifies things - otherwise you end up in a complicated
place like you have described below.
That means you need to define operators such as +, > and = on a list
of reals. Or to define somehow that a statement containing only path
bindings within a single multiply-occurring structure will mean that
it gets evaluated for each occurrence of such a structure. The second
case is complicated if you need to include data outside /events[id2]
in your expression. A real world use case would be data in /protocol,
which can influence the interpretation of event data, but is outside
of the event.
So we did the first in Archie, with a bit of tricks to make this work
for assignments. For example, how the plus operator is interpreted in
Archie:
+(Real r1, Real r2)
return the sum both numbers
...
Much of this complexity can be avoided by not defining the operator
on lists/sets, and requiring the for_all loop on lists or sets of data
in the specification. This comes at a price, because the author of the
expressions needs to understand more of the language and data
structures. So we chose the second, since the previous draft
specification did not specify at all how to handle these cases.
Undefined value handling is another subject, I have not checked yet if
the new proposal solves it. We defined some functions to handle this
explicitly if the automatic handling doesn’t do it ((input ,
alternative) -> return input unless input is undefined, then
alternative), as well as some rounding functions.
the Expression Language draft
<https://specifications.openehr.org/releases/LANG/latest/expression_language.html#_defined_predicate>
has the defined() predicate which I think should do the job.
If we were to allow the expression for_all $event in /data/events[id3]
then we need to be clear on what it means: it actually refers to an
object of type List<EVENT>, but do the members consist of EVENT
objects found in data at the moment the expression is evaluated? Or
just the statically defined members in the archetype - which can also
be multiple, e.g. see the Apgar archetype, it has 1 min, 2 min, 5 min
events?
You would need to evaluate on actual data. If you define it on the
archetype data, you would need some kind of rules to convert it to an
evaluation on actual data with different multiplicities than the rules
specify, for example if events[id2] has occurrences > 1. Might be
possible, I have not tried to define that. Would probably include some
extra for_all loops plus some kind of validation errors for cases that
cannot be converted.
So I would say always the data found at the moment which the
expression is evaluated. You can still refer to separate statically
defined members using their distinct node ids, and even those could
have occurrences > 1 (not in the apgar example since those have
occurrences {0..1} in the archetype).
Normally we want the processing of 'rules' expressions in archetypes
to apply to the data when the archetype is being used in its normal
role of creation / semantic validation at data commit time.
Agreed.
So it seems to me that if we want to support expressions like the
above, we need to be able to do something like (don't worry about the
concrete syntax too much, could easily be TS or java-flavoured):
*use_model*
org.openehr.rm
*data_context*
$xxx_events: List<EVENT>
$item_aaa, $item_bbb, $item_ccc, $item_ddd: Real
*definition*
check for_all event in $xxx_events:
event/$item_aaa > event/$item_bbb + event/$item_ccc +
event/$item_ddd
*data_bindings*-- pseudo-code for now
$xxx_events -> /events[id2]
$item_aaa -> /data/items/element[id7]/value/magnitude
$item_bbb -> /data/items/element[id4]/value/magnitude
$item_ccc -> /data/items/element[id5]/value/magnitude
$item_ddd -> /data/items/element[id6]/value/magnitude
I don't know what this archetype is, so assume that $xxx_events,
$item_aaa etc are more meaningful names.
That would leave $item_aaa globally defined as a path-reference, not
matching a path in the archetype on its own. Type of variable being
some kind of PATH_REFERENCE?
It would still be Real. The idea is that the path is relative to an
EVENT, although that is not clear from the above. Perhaps something like:
$item_aaa -> (EVENT)/data/items/element[id7]/value/magnitude
That would solve the problem. Why not just inline the assignments,
such as:
$events := /events[id2]
this was in a previous draft. But I am pretty convinced we don't want to
mix paths in with the main 'code'. This is particularly the case if we
want to use TypeScript or some other mainstream language to write the
main statements in - the bindings need to be separate.
I'll have more of a think about how the bindings should work.
- thomas
_______________________________________________
openEHR-technical mailing list
openEHR-technical@lists.openehr.org
http://lists.openehr.org/mailman/listinfo/openehr-technical_lists.openehr.org