cqframework / clinical_quality_language

Clinical Quality Language (CQL) is an HL7 specification for the expression of clinical knowledge that can be used within both the Clinical Decision Support (CDS) and Clinical Quality Measurement (CQM) domains. This repository contains complementary tooling in support of that specification.
https://confluence.hl7.org/display/CDS/Clinical+Quality+Language
Apache License 2.0
251 stars 121 forks source link

Verify equivalent logic for conditional statements #1305

Open brynrhodes opened 7 months ago

brynrhodes commented 7 months ago

The following rewrite of a function in QICoreCommon:

define function ToPrevalenceInterval(condition Condition):
if condition.clinicalStatus ~ "active"
  or condition.clinicalStatus ~ "recurrence"
  or condition.clinicalStatus ~ "relapse" then
  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)]
else if (end of ToAbatementInterval(condition) is null) 
   then Interval[start of ToInterval(condition.onset), null)
   else Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] 

resulted in different behavior than the equivalent formulation with a let:

define function ToPrevalenceInterval(condition Condition):
if condition.clinicalStatus ~ "active"
  or condition.clinicalStatus ~ "recurrence"
  or condition.clinicalStatus ~ "relapse" then
  Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)]
else
  (end of ToAbatementInterval(condition)) abatementDate
    return if abatementDate is null then
      Interval[start of ToInterval(condition.onset), abatementDate)
    else
      Interval[start of ToInterval(condition.onset), abatementDate]

This is related to the following CQLIT ticket: https://oncprojectracking.healthit.gov/support/browse/CQLIT-426

In theory, the above functions should behave exactly the same. Create a unit test to verify this for all the edges involved:

Condition.clinicalStatus as active and inactive Condition.onset as a dateTime (null and non-null Condition.onset as an Interval (null and non-null start and end dates) Condition.abatement as a dateTime (null and non-null) Condition.abatement as an Interval (null and non-null start and end dates)