openEHR / archie

OpenEHR library implementing ADL 2, AOM 2, BMM, RM 1.0.4 and many tools
Apache License 2.0
53 stars 25 forks source link

Rule evaluation is order-dependent #568

Open EBrader opened 8 months ago

EBrader commented 8 months ago

Evaluation of rules depends on the order at which these appear in the rules section of an archetype. Order should not matter and rules should first all be assessed before being executed. The archetype below can be used for testing. Rule evaluation in the example will fail only if gender man is selected, while it has similar rules as for vrouw. Selecting man should make path Normwaarde man visible and hide that for Normwaarde vrouw and vice versa. With the rule for vrouw being placed above that for man, when man selected, the rule for vrouw is false and thereby ignored and for some reason a path for Normwaarde vrouw is still generated after rule evaluation probably because of the rule that assigns at95 to it without an explicit check for the value of gender.

archetype (adl_version=2.0.5; rm_release=1.0.4)
    test::openEHR-EHR-OBSERVATION.rule_order_test.v0.0.1

language
    original_language = <[ISO_639-1::nl]>

description
    original_author = <
        ["name"] = <"Test">
    >
    lifecycle_state = <"DRAFT">
    details = <
        ["nl"] = <
            language = <[ISO-639_1::nl]>
            purpose = <"">
            use = <"">
            misuse = <"">
        >
    >

definition
    OBSERVATION[id1] matches {    -- Rule order test
        data matches {
            HISTORY[id2] matches {
                events matches {
                    POINT_EVENT[id3] matches {    -- Point event
                        data matches {
                            ITEM_TREE[id4] matches {
                                items matches {
                                    ELEMENT[id128] matches {    -- Gender
                                        value matches {
                                            DV_CODED_TEXT[id129] matches {
                                                defining_code matches {[ac25]}    -- Gender
                                            }
                                        }
                                    }
                                    ELEMENT[id124] occurrences matches {0..1} matches {    -- Normwaarde Man
                                        value matches {
                                            DV_CODED_TEXT[id125] matches {
                                                defining_code matches {[ac94]}    -- Normwaarde
                                            }
                                        }
                                    }
                                    ELEMENT[id122] occurrences matches {0..1} matches {    -- Normwaarde vrouw
                                        value matches {
                                            DV_CODED_TEXT[id123] matches {
                                                defining_code matches {[ac94]}    -- Normwaarde
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

rules
    $client_gender:String ::= /data[id2]/events[id3]/data[id4]/items[id128]/value/defining_code/code_string
    rule_female: $client_gender = "at26" implies
        exists /data[id2]/events[id3]/data[id4]/items[id122] and not exists /data[id2]/events[id3]/data[id4]/items[id124]
    /data[id2]/events[id3]/data[id4]/items[id122]/value/defining_code matches {[at95]}
    rule_male: $client_gender = "at27" implies
        exists /data[id2]/events[id3]/data[id4]/items[id124] and not exists /data[id2]/events[id3]/data[id4]/items[id122]
    /data[id2]/events[id3]/data[id4]/items[id124]/value/defining_code matches {[at102]}

terminology
    term_definitions = <
        ["nl"] = <
            ["id1"] = <
                text = <"Rule order test">
                description = <"">
            >
            ["id3"] = <
                text = <"Point event">
                description = <"Point event">
            >
            ["ac25"] = <
                text = <"Gender">
                description = <"">
            >
            ["at26"] = <
                text = <"Vrouw">
                description = <"">
                code = <"at26">
            >
            ["at27"] = <
                text = <"Man">
                description = <"">
                code = <"at27">
            >
            ["ac94"] = <
                text = <"Normwaarde">
                description = <"">
            >
            ["at95"] = <
                text = <"8">
                description = <"">
                code = <"">
            >
            ["at102"] = <
                text = <"26">
                description = <"">
            >
            ["id122"] = <
                text = <"Normwaarde vrouw">
                description = <"">
            >
            ["id124"] = <
                text = <"Normwaarde Man">
                description = <"">
            >
            ["id128"] = <
                text = <"Gender">
                description = <"">
            >
        >
    >
    value_sets = <
        ["ac25"] = <
            id = <"ac25">
            members = <"at26", "at27">
        >
        ["ac94"] = <
            id = <"ac94">
            members = <"at95", "at102">
        >
    >
pieterbos commented 8 months ago

Rule evaluation order now simply matters by definition of how this is implemented. Because of variable assignment and re-using fields set as a result of a previous rule.

Your assertions appear to be ambiguous. You assert normwaarden vrouw should always have a specific value, then you say it must not exists at the same time. That will not work. If you want normwaarden vrouw to be set only for women, put it inside the corresponding female rule implies assertion, chained with and. That will fix your problem properly.

I would say trying to fix this in the rule evaluator will cause loads of trouble.