cqframework / cql-engine

Clinical Quality Language Evaluation Engine

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Invariant should be evaluating to true, but returns false

brynrhodes opened this issue · comments

This invariant evaluation:

library Retrieve1 version '1.0'
using FHIR version '3.0.0'
include FHIRHelpers version '3.0.0' called FHIRHelpers
context Patient

define Money: FHIR.Money { 
  value: FHIR.decimal { value: 1.0 }, 
  code: FHIR.code { value: '$' }, 
  system: FHIR.uri { value: 'urn:iso:std:iso:4217' } 
}

define MoneyInvariant: Money.select((code."exists"() or value.empty()) and (system.empty() or system = FHIR.uri { value: 'urn:iso:std:iso:4217' }))

should be evaluating to true, there is a code, so there can be a value, and the system is correct. But it is evaluating to false.

The issue is with this argument system = FHIR.uri { value: 'urn:iso:std:iso:4217' }
That is failing because HAPI's UriType doesn't have the equals(UriType other) override defined. Instead, they have an equals(String theString) function.
However, the following does evaluate as true:

define MoneyInvariant: 
  Money.select(
    (code."exists"() or value.empty()) 
    and (system.empty() or system = 'urn:iso:std:iso:4217')
  ) 

Which seems closer to the expression laid out in the FHIR spec:
(code or value.empty()) and (system.empty() or system = 'urn:iso:std:iso:4217')

Okay, I didn't even think to try that because I had already gotten an error about not being able to resolve ToString() (That's why I added the FHIR.uri selector in the first place).

So, if you take that out of the Money definition:

library Retrieve1 version '1.0'
using FHIR version '3.0.0'
include FHIRHelpers version '3.0.0' called FHIRHelpers
context Patient

define Money: FHIR.Money { 
  value: FHIR.decimal { value: 1.0 }, 
  code: FHIR.code { value: '$' } //, 
  //system: FHIR.uri { value: 'urn:iso:std:iso:4217' } 
}

define MoneyInvariant: Money.select((code."exists"() or value.empty()) and (system.empty() or system = 'urn:iso:std:iso:4217'))

Then it gets an error about not being able to resolve ToString(). That's the overload issue which we're already addressing in a different way, so don't worry about that one, but is there a way we can address the Equal not being provided by HAPI there? Like a class-based equal provider?

Interesting. Yeah, I think so. I could develop a provider similar to the external function provider for equality functions.

I can aslo try something like this:

if (left.getClass() == right.getClass()) {
  try {
    Object leftValue = left.getClass().getMethod("getValue").invoke(left);
    Object rightValue = right.getClass().getMethod("getValue").invoke(right);
    return equal(leftValue, rightValue);
  } catch (Exception e) {
    // continue to general equals
  }
}

That would work for this case and other cases involving HAPI's STU3 primitives, but it is hacky for sure.

commented

Resolved by adding equal and equivalent to the ModelResolver interface