FHIR Chat · how to require at-least one code is X · shorthand

Stream: shorthand

Topic: how to require at-least one code is X


view this post on Zulip John Moehrke (Apr 01 2022 at 16:38):

on a CodeableConcept that is 0..*; I want to say in my profile that at-least one of them must be code X, but not disallow other codes. I thought that simple profiling assignment would do that

  • subtype = mySystem#myCode

This seems to say in my IG rendering of that profile --> "Required Pattern: At least the following"
BUT, this seems to actually forbid any other code

view this post on Zulip John Moehrke (Apr 01 2022 at 16:39):

I could slice, and get the behavior I want

* subtype ^slicing.discriminator.type = #value
* subtype ^slicing.discriminator.path = "$this"
* subtype ^slicing.rules = #open
* subtype ^slicing.description = "needs to at least be a disclosure event"
* subtype contains disclosure 1..1
* subtype[disclosure] = http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle#disclose "Disclose Record Lifecycle Event"

But that seems so much harder

view this post on Zulip Julian Carter (Apr 01 2022 at 19:34):

Hi @John,

It seems to me that this is a bug within SUSHI, and that other codes should be allowed when an array element is constrained with an assignment rule as you did here. I've filed an issue in SUSHI (#1055)to address this.

view this post on Zulip John Moehrke (Apr 01 2022 at 19:46):

I am not so sure it is sushi fault. because the IG publisher is the one rendering the profile and it is the one indicating "at least the following"

view this post on Zulip John Moehrke (Apr 01 2022 at 19:46):

image.png

view this post on Zulip John Moehrke (Apr 01 2022 at 19:54):

ah, so sushi is failing to allow it multiple codes in my examples... that the slicing did allow.

Sushi couldn't be run. Complete output from running Sushi : error Cannot assign http://hl7.org/fhir/restful-interaction#read "read" to this element; a different Coding is already assigned: {"code":"disclose","system":"http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle","display":"Disclose Record Lifecycle Ev (00:35.0356)

view this post on Zulip Chris Moesel (Apr 01 2022 at 19:54):

So... it's actually unclear what pattern[x] means on a repeating (0..*) element. The spec (as written) is confusing, but seems to imply that what's in the pattern[x] only has to match on one element in the array. But several people, including Lloyd and Grahame, apparently thought it should apply to all elements in the array. I brought this up a few months ago and there still seemed to be a lot of confusion (this thread is a bit of a roller coaster). I'm going to revive that thread to see if a decision was made.

view this post on Zulip John Moehrke (Apr 01 2022 at 19:56):

I thought I remembered discussion on this topic.. and thought I remembered no conclusion.

view this post on Zulip John Moehrke (Apr 01 2022 at 19:56):

what is odd is that the IG publisher clearly decorates it as "at least..."

view this post on Zulip John Moehrke (Apr 01 2022 at 19:57):

which is what I figured was happening. and had no examples that stressed this, until now.

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:03):

Disclaimer: I am bumbling around in the dark as much as anyone on these things =)

Putting it into FSH online, the differential looks okay to me, as long as you are stating that a conformant AuditEvent must have exactly one disclosure slice.

  "differential": {
    "element": [
      {
        "id": "AuditEvent.subtype",
        "path": "AuditEvent.subtype",
        "slicing": {
          "discriminator": [
            {
              "type": "value",
              "path": "$this"
            }
          ],
          "rules": "open",
          "description": "needs to at least be a disclosure event"
        },
        "min": 1
      },
      {
        "id": "AuditEvent.subtype:disclosure",
        "path": "AuditEvent.subtype",
        "sliceName": "disclosure",
        "min": 1,
        "max": "1",
        "patternCoding": {
          "code": "disclose",
          "system": "http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle",
          "display": "Disclose Record Lifecycle Event"
        }
      }
    ]
  }

To me, that reads that:

  • AuditEvent.subtype now has a min cardinality of 1.
  • The pattern established by disclosure has a cardinality of 1..1

view this post on Zulip John Moehrke (Apr 01 2022 at 20:06):

@Gino Canessa yes, it works if I slice... I just don't think i should have to slice.

view this post on Zulip John Moehrke (Apr 01 2022 at 20:06):

I would far prefer in sushi to just say

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:08):

The problem with that would be that element id's would no longer be unique. E.g., if you wanted to have a disclose and a verify, you have no way of adding both of those discriminators uniquely without slicing.

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:09):

Hmm... though I don't know if that matters.

view this post on Zulip John Moehrke (Apr 01 2022 at 20:09):

understood... if I need more than one... Fine, I will switch to slicing.. and have

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:09):

(I am trying to work through this from the side of parsing and understanding a differential/snapshot)

view this post on Zulip John Moehrke (Apr 01 2022 at 20:09):

I just have many cases where I simply want to say that an element in a profile needs to at-least have X

view this post on Zulip John Moehrke (Apr 01 2022 at 20:10):

see the other stream for less about sushi, and more about profiling -- https://chat.fhir.org/#narrow/stream/179177-conformance/topic/pattern.5Bx.5D.20on.200.2E.2E*.20elements/near/264222809

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:10):

Yes.. I am trying to figure out how to say that in an ElementDefinition without slicing though.

view this post on Zulip John Moehrke (Apr 01 2022 at 20:11):

pattern[x] seems should work... if patern[x] is seen as "at least" which is what gets rendered by the IG publisher.

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:12):

My concern is that since ElementDefinition.pattern[x] has a max cardinality of 1, I think a pattern like that would prohibit anything else useful from being said downstream.

view this post on Zulip John Moehrke (Apr 01 2022 at 20:12):

and if that is the conclusion... then it is just up to sushi enforcing that definition on pattern[x], rather than today it is enforcing "all must"

view this post on Zulip Gino Canessa (Apr 01 2022 at 20:12):

(and changing the cardinality there would not help, since what would that even mean?)

view this post on Zulip John Moehrke (Apr 01 2022 at 20:13):

John Moehrke said:

image.png

this shows subtype as 0..*, with "at least..."

view this post on Zulip Chris Moesel (Apr 01 2022 at 20:17):

Right. It comes down to what pattern[x] actually means in the context of a 0..* element. Until that is decided for sure, we don't know what SUSHI should do. As I said in the other thread, someone needs to decide which of these is right:

  • A pattern[x] on a repeating element must match every element in the instance array, OR
  • A pattern[x] on a repeating element must match at least one element in the instance array

view this post on Zulip John Moehrke (Apr 04 2022 at 20:46):

so... now that FHIR-I has clarified that pattern[x] really means "all"... can we have sushi support for "at least one"?

so where I presumed the following setup an at-least one,

subtype = http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle#disclose "Disclose Record Lifecycle Event"

how about keyword atLeast that automatically does all the slicing stuff?

subtype atLeast http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle#disclose "Disclose Record Lifecycle Event"

is equivalent to

* subtype ^slicing.discriminator.type = #value
* subtype ^slicing.discriminator.path = "$this"
* subtype ^slicing.rules = #open
* subtype contains disclosure 1..1
* subtype[disclosure] = http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle#disclose "Disclose Record Lifecycle Event"

view this post on Zulip Chris Moesel (Apr 04 2022 at 20:52):

@John Moehrke -- that's an interesting proposal. I think my one concern w/ it would be that by obscuring the slicing, we might be introducing ways for people to shoot themselves in the foot if they then try to go and do explicit slicing as well. But... I suppose we could issue warnings for that... I'd be interested to hear what others in the community think.

view this post on Zulip John Moehrke (Apr 04 2022 at 20:52):

well, isn't that the whole role of sushi? It hides all kinds of complexity behind a more simple (and constrained) encoding

view this post on Zulip John Moehrke (Apr 04 2022 at 20:53):

simple profile assignment when the element is ..1 is proper; but it seems completely useless because of the pattern[x] definition to be done on elements with upper that is not 1.

view this post on Zulip Chris Moesel (Apr 04 2022 at 21:03):

Yeah, I get it. It's just that sometimes when we obscure things, it causes problems. There is a balance between having just the right amount of magic and having too much magic. I want to be sure that something like this is closer to the former than the latter.

I know it's not as elegant, but this can be made a bit simpler w/ a RuleSet for the time being:

RuleSet: requireAtLeastOneMatch(path, slice, pattern)
* {path} ^slicing.discriminator.type = #value
* {path} ^slicing.discriminator.path = "$this"
* {path} ^slicing.rules = #open
* {path} contains {slice} 1..1
* {path}[{slice}] = {pattern}

Profile: AuditEventProfile
Parent: AuditEvent
* insert requireAtLeastOneMatch(subtype, disclosure, http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle#disclose "Disclose Record Lifecycle Event")

Example on FSH Online

view this post on Zulip John Moehrke (Apr 04 2022 at 21:15):

I guess that is just about as elegant. I have not played with that feature of sushi... too powerful to fully understand is a surely a "razor" defined by someone

view this post on Zulip John Moehrke (Apr 04 2022 at 21:16):

I am more worried there are these kinds of things that I don't know I did. The simple assignment is so easy to use.

view this post on Zulip Luke Duncan (Apr 11 2022 at 20:00):

Is there any guidance on slicing vs. invariants for that? I'm not sure if the FHIRPath would work on the field itself.

Invariant: some-rule
Expression: '$this.where(coding.system="http://terminology.hl7.org/CodeSystem/iso-21089-lifecycle" and coding.type = "disclose").exists()'

Then in the profile

  • subtype obeys some-rule

Or if that doesn't work, put the rule on the top of the resource and use subtype instead of $this in the expression. Is that easier or better than slicing?


Last updated: Apr 12 2022 at 19:14 UTC