Re: Rules in archetypes - what are the requirements?

2019-02-01 Thread Pieter Bos
About the calculation:

Ah, I see, the assignment seems like a good solution. But why would I need a 
function to calculate a score that is just a sum of a number of values, instead 
of a few +-operators?


Multiplicities/data binding:

The there exists case is clear. However, what if I have four events, all having 
four elements, each with dv_quantity as value. Say I want the magnitude of the 
last of these quantities to be larger than the sum of the first three. Before I 
could write something like:

for_all $event in /data/events[id3]
 $event/data/items/element[id6]/value/magnitude >
$event/data/items/element[id4]/value/magnitude +
$event/data/items/element[id5]/value/magnitude +
$event/data/items/element[id6]/value/magnitude

(I omitted a few node ids here that are not important for the example)
Not the most readable -  but it does the job. With data binding, how do I 
express this? There no longer seems to be a path lookup outside of data 
binding, so I can’t write:

for_all $event in $events
 $event/data/items/element[id6]/value/magnitude >
$event/data/items/element[id4]/value/magnitude +
$event/data/items/element[id5]/value/magnitude +
$event/data/items/element[id6]/value/magnitude

And binding all the separate paths to variables doesn’t work either – they will 
be bound as lists, and there is no way to iterate over four lists of values at 
once.

Note that a path that points to a single typed dvquantity in an archetype can 
still point to many items in the RM if somewhere up the tree there is a list or 
a set, for example more than one observation. So if you really want them to be 
typed on validation time, you need to check every attribute in the path to see 
if it can point to more than one value, then either make it a 
List> or define in which order to add it as a single list.
I implemented it by determining type at runtime, but it’s possible otherwise. 
This means that very often you need a for all statement, in which case data 
binding doesn’t really help. I defined some tricks with the basic operators 
also working on equally sized lists to make things a bit easier to understand 
for modelers. That’s why I asked about the execution rules. The tricks I did 
can be easily rewritten into for_all statements if we need to have them removed.

This leads to more interesting cases when you flatten rules to an OPT 2 
template, to obtain a single artifact that can be used for many things, 
including rule evaluation. That is very doable right now by prepending some 
paths and adding some for_all statements. I’m not sure how to do that with data 
binding.

Regards,


Pieter Bos

From: openEHR-technical  on behalf 
of Thomas Beale 
Reply-To: For openEHR technical discussions 

Date: Friday, 1 February 2019 at 14:16
To: "openehr-technical@lists.openehr.org" 
Subject: Re: Rules in archetypes - what are the requirements?


Thanks Pieter,

this is very useful.
On 01/02/2019 12:54, Pieter Bos wrote:
For us the main requirement of the rules is to calculate the value of other 
fields based on other fields. Only the checking of assertions has relatively 
little added value for the use cases our customers encounter. I would find it 
very hard to explain to any users or modelers that they can write checks that 
do the actual score calculation, but that they cannot actually use the 
calculated value anywhere. So we ignore this limitation altogether.

the obvious solution to that requirement seems to be to a) use functions and b) 
to allow assignment:

rules
-- assert that manually set total is correct
check $apgar_total_value == apgar_total ($apgar_heartrate_value, 
$apgar_breathing_value, $apgar_reflex_value, $apgar_muscle_value, 
$apgar_colour_value)



rules
-- assign total value
$apgar_total_value = apgar_total ($apgar_heartrate_value, 
$apgar_breathing_value, $apgar_reflex_value, $apgar_muscle_value, 
$apgar_colour_value)



Also the value binding seems to have an case that has not been covered:


it is possible that a single path lookup results in a list of values. This 
means a single path-bound variable will contain multiple values (so a list of 
values). In the old case, you could handle this with a for_all statement to 
express that the assertion should be valid within the scope of a single event, 
for all events. How could value binding solve this? The same question applies 
to output variable binding as well as input variable binding.

conceptually, rules statements are typed, so in this case, the type will be 
List or List or whatever. In that case, expressions need to 
treat it in the normal way, i.e. with List or Set operators that obtain single 
values. E.g.

$systolic_bp_samples: List

there_exists v in $systolic_bp_samples : v > Systolic_bp_threshold implies 

These kinds of things (and for_all) are documented in the Expression Language 

Re: Rules in archetypes - what are the requirements?

2019-02-01 Thread Thomas Beale

Thanks Pieter,

this is very useful.

On 01/02/2019 12:54, Pieter Bos wrote:


For us the main requirement of the rules is to calculate the value of 
other fields based on other fields. Only the checking of assertions 
has relatively little added value for the use cases our customers 
encounter. I would find it very hard to explain to any users or 
modelers that they can write checks that do the actual score 
calculation, but that they cannot actually use the calculated value 
anywhere. So we ignore this limitation altogether.


the obvious solution to that requirement seems to be to a) use functions 
and b) to allow assignment:


*rules
*    -- assert that manually set total is correct
*check *$apgar_total_value == apgar_total ($apgar_heartrate_value, 
$apgar_breathing_value, $apgar_reflex_value, $apgar_muscle_value, 
$apgar_colour_value)



*rules
*    -- assign total value
    $apgar_total_value = apgar_total ($apgar_heartrate_value, 
$apgar_breathing_value, $apgar_reflex_value, $apgar_muscle_value, 
$apgar_colour_value)




Also the value binding seems to have an case that has not been covered:

it is possible that a single path lookup results in a list of values. 
This means a single path-bound variable will contain multiple values 
(so a list of values). In the old case, you could handle this with a 
for_all statement to express that the assertion should be valid within 
the scope of a single event, for all events. How could value binding 
solve this? The same question applies to output variable binding as 
well as input variable binding.


conceptually, rules statements are typed, so in this case, the type will 
be List or List or whatever. In that case, expressions 
need to treat it in the normal way, i.e. with List or Set operators that 
obtain single values. E.g.


$systolic_bp_samples: List

there_exists v in $systolic_bp_samples : v > Systolic_bp_threshold 
implies 


These kinds of things (and for_all) are documented in the Expression 
Language draft 
.


Related to this, both the current and proposed specification is 
missing execution rules, especially when paths lookup to a list of 
values instead of a single variable and how to handle that. For 
example what does the following mean when 
/data/events/data/items/element[id3]/value/magnitude resolves to more 
than one value?


I don't see how it can, since that path is defined to be of type Real 
(not List or Set etc) by the RM definition of DvQuantity. 
But I'm probably missing something in the sense of your question...


Anyway, the more I can find out about current requirements, working 
solutions, workaround etc, the better - the intention is to evolve the 
expression facility in archetypes to match those needs and to be as 
useful as possible.


- thomas


___
openEHR-technical mailing list
openEHR-technical@lists.openehr.org
http://lists.openehr.org/mailman/listinfo/openehr-technical_lists.openehr.org


Re: Rules in archetypes - what are the requirements?

2019-02-01 Thread Pieter Bos
For us the main requirement of the rules is to calculate the value of other 
fields based on other fields. Only the checking of assertions has relatively 
little added value for the use cases our customers encounter. I would find it 
very hard to explain to any users or modelers that they can write checks that 
do the actual score calculation, but that they cannot actually use the 
calculated value anywhere. So we ignore this limitation altogether.

Also the value binding seems to have an case that has not been covered:

it is possible that a single path lookup results in a list of values. This 
means a single path-bound variable will contain multiple values (so a list of 
values). In the old case, you could handle this with a for_all statement to 
express that the assertion should be valid within the scope of a single event, 
for all events. How could value binding solve this? The same question applies 
to output variable binding as well as input variable binding.

Related to this, both the current and proposed specification is missing 
execution rules, especially when paths lookup to a list of values instead of a 
single variable and how to handle that. For example what does the following 
mean when /data/events/data/items/element[id3]/value/magnitude resolves to more 
than one value?

/data/events/data/items/element[id15]/value/magnitude = 
/data/events/data/items/element[id3]/value/magnitude + 3

And what if 3 is replaced by another path instead? What if the left hand side 
matches one value? And what if it matches more than one? In Archie I 
implemented ways to handle these cases by defining the operations on single 
values, on equally sized lists and in cases where one value is a list and the 
other one is a single value. But unless this is specified, this will be 
different for different implementations.

Regards,

Pieter Bos

From: openEHR-technical  on behalf 
of Thomas Beale 
Reply-To: For openEHR technical discussions 

Date: Friday, 1 February 2019 at 13:01
To: Openehr-Technical 
Subject: Rules in archetypes - what are the requirements?


For many years, there has been a little-used capability in ADL which enables 
basic expressions to be stated such as the following in the Apgar Observation 
archetype:

rules

score_sum: 
/data[id3]/events[id4]/data[id2]/items[id26]/value[id44]/magnitude = 
/data[id3]/events[id4]/data[id2]/items[id6]/value[id40]/value + 
/data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value + 
/data[id3]/events[id4]/data[id2]/items[id14]/value[id41]/value + 
/data[id3]/events[id4]/data[id2]/items[id18]/value[id42]/value + 
/data[id3]/events[id4]/data[id2]/items[id22]/value[id43]/value

where all those paths point to the various Apgar leaf data values, i.e. total, 
heart rate etc.

This kind of statement is intended to assert that the total value = the sum of 
the 5 elements, as per the Apgar formula. However, it was never that clear that 
it is an assertion, not a value-setting formula, which might also be something 
we want.

It's also not very readable, even if the paths were rendered with a tool, they 
are long and painful to read.

Another kind of assertion was to for conditional mandation of some part of the 
data depending on some other data element (or more generally, an expression), 
e.g.

rules

/data[id2]/items[id21]/items[id15]/value[id50]/defining_code matches 
{[at19]} implies exists /data[id2]/items[id21]/items[id20]

Here the logical intention is to mandate that the data at the second path, 
which is about details of transfer (i.e. discharge to other care) if the value 
of the datum at the first path, which is 'type of separation' = at19|transfer|. 
Other examples are mandating data containing details of tobacco use if the 
value of the data item 'tobacco use' /= at44|non-user|.

This also is not that easy to read, or clear in its intentions.

More recently, as part of the development of a simple expression language that 
can be used across openEHR (archetypes, Task Planning, GDL etc), I proposed 
some key improvements to expressions in archetypes, namely:

  *   symbolic names for paths, done by bindings
  *   an explicit 'check' instruction to make the intention of assertion clearer
  *   a defined() predicate to replace the use of 'exists'

Examples of how these changes look are shown here in the working copy of the 
ADL2 
spec.
 In this form, the above Apgar example becomes:

rules
check $apgar_total_value = $apgar_heartrate_value + $apgar_breathing_value 
+ $apgar_reflex_value + $apgar_muscle_value + $apgar_colour_value

data_bindings

content_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"] = 

Re: Rules in archetypes - what are the requirements?

2019-02-01 Thread Diego Boscá
I'm fine with this improvements, the only thing I feel that can be
troublesome for users is having data_bindings and computed values in a
completely different format/style


El vie., 1 feb. 2019 a las 13:01, Thomas Beale ()
escribió:

> For many years, there has been a little-used capability in ADL which
> enables basic expressions to be stated such as the following in the Apgar
> Observation archetype:
>
> *rules*
>
> *score_sum*:
> /data[id3]/events[id4]/data[id2]/items[id26]/value[id44]/magnitude =
> /data[id3]/events[id4]/data[id2]/items[id6]/value[id40]/value +
> /data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value +
> /data[id3]/events[id4]/data[id2]/items[id14]/value[id41]/value +
> /data[id3]/events[id4]/data[id2]/items[id18]/value[id42]/value +
> /data[id3]/events[id4]/data[id2]/items[id22]/value[id43]/value
>
> where all those paths point to the various Apgar leaf data values, i.e.
> total, heart rate etc.
>
> This kind of statement is intended to assert that the total value = the
> sum of the 5 elements, as per the Apgar formula. However, it was never that
> clear that it is an assertion, not a value-setting formula, which might
> also be something we want.
>
> It's also not very readable, even if the paths were rendered with a tool,
> they are long and painful to read.
>
> Another kind of assertion was to for conditional mandation of some part of
> the data depending on some other data element (or more generally, an
> expression), e.g.
>
> *rules*
>
> /data[id2]/items[id21]/items[id15]/value[id50]/defining_code *matches
> *{[at19]} *implies exists */data[id2]/items[id21]/items[id20]
>
> Here the logical intention is to mandate that the data at the second path,
> which is about details of transfer (i.e. discharge to other care) if the
> value of the datum at the first path, which is 'type of separation' =
> at19|transfer|. Other examples are mandating data containing details of
> tobacco use if the value of the data item 'tobacco use' /= at44|non-user|.
>
> This also is not that easy to read, or clear in its intentions.
>
> More recently, as part of the development of a simple expression language
> that can be used across openEHR (archetypes, Task Planning, GDL etc), I
> proposed some key improvements to expressions in archetypes, namely:
>
>- symbolic names for paths, done by bindings
>- an explicit 'check' instruction to make the intention of assertion
>clearer
>- a defined() predicate to replace the use of 'exists'
>
> Examples of how these changes look are shown here in the working copy of
> the ADL2 spec
> .
> In this form, the above Apgar example becomes:
>
> *rules*
> *check *$apgar_total_value = $apgar_heartrate_value + $
> apgar_breathing_value + $apgar_reflex_value + $apgar_muscle_value + $
> apgar_colour_value
>
> *data_bindings*
>
> content_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">
> >
>
> And the smoking example is:
>
> *check *$is_smoker = *True **implies **defined *($smoking_details)
>
> Note that this does not address the possible requirement of being able to
> state a formula that *sets *a field, or defines a purely computed value
> at a path.
>
> We are still working on details of the expression language, variable
> binding idea and so on. I am interested in feedback on the approach shown
> in the spec, preferably provided here in the first instance.
>
> - thomas
> ___
> openEHR-technical mailing list
> openEHR-technical@lists.openehr.org
>
> http://lists.openehr.org/mailman/listinfo/openehr-technical_lists.openehr.org
>


-- 

[image: VeraTech for Health SL] 

[image: Twitter]   [image: LinkedIn]
 [image: Maps]


Diego Boscá Tomás / Senior developer
diebo...@veratech.es
yamp...@gmail.com

VeraTech for Health SL
+34 654604676 <+34%20654604676>
www.veratech.es

La información contenida en este mensaje y/o archivo(s) adjunto(s), enviada
desde VERATECH FOR HEALTH, SL, es confidencial/privilegiada y está
destinada a ser leída sólo por la(s) persona(s) a la(s) que va dirigida. Le
recordamos que sus datos han sido incorporados en el sistema de tratamiento
de VERATECH FOR HEALTH, 

Rules in archetypes - what are the requirements?

2019-02-01 Thread Thomas Beale
For many years, there has been a little-used capability in ADL which 
enables basic expressions to be stated such as the following in the 
Apgar Observation archetype:


*rules*

/score_sum/: 
/data[id3]/events[id4]/data[id2]/items[id26]/value[id44]/magnitude = 
/data[id3]/events[id4]/data[id2]/items[id6]/value[id40]/value + 
/data[id3]/events[id4]/data[id2]/items[id10]/value[id39]/value + 
/data[id3]/events[id4]/data[id2]/items[id14]/value[id41]/value + 
/data[id3]/events[id4]/data[id2]/items[id18]/value[id42]/value + 
/data[id3]/events[id4]/data[id2]/items[id22]/value[id43]/value


where all those paths point to the various Apgar leaf data values, i.e. 
total, heart rate etc.


This kind of statement is intended to assert that the total value = the 
sum of the 5 elements, as per the Apgar formula. However, it was never 
that clear that it is an assertion, not a value-setting formula, which 
might also be something we want.


It's also not very readable, even if the paths were rendered with a 
tool, they are long and painful to read.


Another kind of assertion was to for conditional mandation of some part 
of the data depending on some other data element (or more generally, an 
expression), e.g.


*rules*

/data[id2]/items[id21]/items[id15]/value[id50]/defining_code *matches 
*{[at19]} *implies exists */data[id2]/items[id21]/items[id20]


Here the logical intention is to mandate that the data at the second 
path, which is about details of transfer (i.e. discharge to other care) 
if the value of the datum at the first path, which is 'type of 
separation' = at19|transfer|. Other examples are mandating data 
containing details of tobacco use if the value of the data item 'tobacco 
use' /= at44|non-user|.


This also is not that easy to read, or clear in its intentions.

More recently, as part of the development of a simple expression 
language that can be used across openEHR (archetypes, Task Planning, GDL 
etc), I proposed some key improvements to expressions in archetypes, namely:


 * symbolic names for paths, done by bindings
 * an explicit 'check' instruction to make the intention of assertion
   clearer
 * a defined() predicate to replace the use of 'exists'

Examples of how these changes look are shown here in the working copy of 
the ADL2 spec 
. 
In this form, the above Apgar example becomes:


*rules*
*check *$apgar_total_value = $apgar_heartrate_value + 
$apgar_breathing_value + $apgar_reflex_value + $apgar_muscle_value + 
$apgar_colour_value


*data_bindings*

    content_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">

    >

And the smoking example is:

*check *$is_smoker = *True **implies **defined *($smoking_details)

Note that this does not address the possible requirement of being able 
to state a formula that /sets /a field, or defines a purely computed 
value at a path.


We are still working on details of the expression language, variable 
binding idea and so on. I am interested in feedback on the approach 
shown in the spec, preferably provided here in the first instance.


- thomas

___
openEHR-technical mailing list
openEHR-technical@lists.openehr.org
http://lists.openehr.org/mailman/listinfo/openehr-technical_lists.openehr.org