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.
Resolved by adding equal
and equivalent
to the ModelResolver interface