FHIR Chat · potentially bad invariant in RatioRange · implementers

Stream: implementers

Topic: potentially bad invariant in RatioRange


view this post on Zulip Lee Surprenant (Dec 08 2021 at 13:45):

R4B introduces datatype RatioRange with the following invariant:

One of lowNumerator or highNumerator and denominator SHALL be present, or all are absent. If all are absent, there SHALL be some extension present

Expression:

((lowNumerator.empty() and highNumerator.empty()) xor denominator.exists()) and (lowNumerator.exists() or extension.exists())

I find both the description and the fhirpath a bit dense, but at the outer layer of the expression its an and with (lowNumerator.exists() or extension.exists())

Should the following RatioRange be valid (e.g. in concentration[x] in Ingredient)?

      <concentrationRatioRange>
        <highNumerator>
          <value value="1"/>
          <unit value="L"/>
        </highNumerator>
        <denominator>
          <value value="2"/>
          <unit value="L"/>
        </denominator>
      </concentrationRatioRange>

If so, I think the expression is in error.

view this post on Zulip Josh Mandel (Dec 08 2021 at 14:12):

Reading the English and making a guess about where the parentheses belong, I think your example is valid.

I can't read that FHIRpath expression before coffee ;-)

view this post on Zulip Lee Surprenant (Dec 08 2021 at 14:13):

I had to make a truth table to convince myself the xor part was right (but i think it is)
image.png

view this post on Zulip Lee Surprenant (Dec 08 2021 at 14:14):

but maybe we should strive for more readable expressions...

view this post on Zulip Lee Surprenant (Dec 08 2021 at 14:16):

I think its the mix of .empty() and .exists() with various boolean operations in the same expression that made it hard for my feable mind

view this post on Zulip Grahame Grieve (Dec 08 2021 at 18:55):

totally agree about that. @Rik Smithies can we write a more natural expression that doesn't use xor? (looks like it was translated from xpath to me)

view this post on Zulip Rik Smithies (Dec 08 2021 at 20:24):

It wasn't me that created that, I just copied the whole datatype into R4B from the main build. Possibly @Jean Duteau ?

view this post on Zulip Grahame Grieve (Dec 08 2021 at 20:27):

yes it was @Jean Duteau

view this post on Zulip Jean Duteau (Dec 08 2021 at 21:47):

when this was applied, the invariant was taken from Ratio:
rat-1: (numerator.empty() xor denominator.exists()) and (numerator.exists() or extension.exists())
this became for RatioRange:
inv-1: ((lowNumerator.empty() and highNumerator.empty()) xor denominator.exists()) and (lowNumerator.exists() or extension.exists())

view this post on Zulip Jean Duteau (Dec 08 2021 at 22:01):

this does miss the case where high and denominator are present, so the invariant isn't quite right.

view this post on Zulip Jean Duteau (Dec 08 2021 at 22:12):

here is the easier invariant:
((low.exists or high.exists) and denom.exists) or (low.empty and high.empty and denom.empty and extension.exists)

view this post on Zulip Jean Duteau (Dec 08 2021 at 22:14):

if we want to rewrite the Ratio invariant to not use xor:
(numerator.exists and denominator.exists) or (numerator.empty and denominator.empty and extension.exists)

view this post on Zulip Lee Surprenant (Dec 08 2021 at 22:24):

I, for one, find those much more readable

view this post on Zulip Lee Surprenant (Dec 10 2021 at 22:34):

Would it be helpful for me to open a JIRA tracker for this one, or is already being worked?

view this post on Zulip Jean Duteau (Dec 11 2021 at 04:29):

Open a Jira issue

view this post on Zulip Lee Surprenant (Dec 11 2021 at 15:19):

FHIR#34454

view this post on Zulip Grahame Grieve (Dec 14 2021 at 05:02):

I pre-applied these in R4B


Last updated: Apr 12 2022 at 19:14 UTC