FHIR Chat · slicing question for patterns on bindings · IG creation

Stream: IG creation

Topic: slicing question for patterns on bindings


view this post on Zulip Eric Haas (Nov 25 2021 at 20:43):

based on this:

Each slice must use the element definition for the element(s) in the discriminator(s) to ensure that the slices are clearly differentiated by assigning an appropriate value domain, depending on the discriminator type. If the type is value, or pattern, then the element definition must use either:

ElementDefinition.fixed[x], or
ElementDefinition.pattern[x], or
if the element has a terminology binding, a required binding with a Value Set that enumerates the list of possible codes in the value set ("extensional definition") (my highlighting )

I did this ...

#....
    - id: DiagnosticReport.category
      path: DiagnosticReport.category
      slicing:
        discriminator:
          - type: pattern    #<<<<<<<<<<<<<<<<<<
            path: $this          #<<<<<<<<<<<<<<<<<<<
        rules: open
      min: 1
      mustSupport: true
    - id: 'DiagnosticReport.category:us-core'
      path: DiagnosticReport.category
      sliceName: us-core
      min: 1
      mustSupport: true
      binding:  #<<<<<<<<<<<<<<<<<<<<<
        strength: extensible  #<<<<<<<<<<<<<<<<<<<<<
        valueSet: 'http://hl7.org/fhir/us/core/ValueSet/us-core-diagnosticreport-category'  #<<<<<<<<<<<<<

which is causing this validation error:

1. ERROR: DiagnosticReport/bone-density-report: DiagnosticReport.category[0]: Slicing cannot be evaluated: Could not match discriminator ([$this]) for slice DiagnosticReport.category:us-core in profile http://hl7.org/fhir/us/core/StructureDefinition/us-core-diagnosticreport-note - the discriminator [$this] does not have fixed value, binding or existence assertions

view this post on Zulip Eric Haas (Nov 25 2021 at 20:45):

I want this slice to be an extensible binding and to replicate the same binding rules as an extensible binding on CodeableConcept behaves - i.e., at least one of the Categories contains a value from the extensible binding.

how do I fix it ?

  • Does the binding need to be required? ()

What does "extensional definition" in the documentation above mean exactly ("a required binding with a Value Set that enumerates the list of possible codes in the value set ("extensional definition")?

view this post on Zulip Grahame Grieve (Nov 25 2021 at 21:16):

I think the definition is pretty clear: a required binding

view this post on Zulip Grahame Grieve (Nov 25 2021 at 21:16):

extensional: see https://www.hl7.org/fhir/valueset.html#int-ext

view this post on Zulip Eric Haas (Nov 25 2021 at 22:00):

Grahame Grieve said:

I think the definition is pretty clear: a required binding

My question really is the parenthetic "extensional definition" makes no sense in in the context of this documentation : "a required binding with a Value Set that enumerates the list of possible codes in the value set ("extensional definition")" Why is it there ?

Second, I want this slice to be an extensible binding and to replicate the same binding rules as an extensible binding on CodeableConcept behaves - i.e., at least one of the Categories contains a value from the extensible binding. how do I do that? In other words how does validation behave for extensible bindings on CodeableConcepts? it would be the same as that for slicing.

view this post on Zulip Eric Haas (Nov 25 2021 at 22:03):

for example, I have a value set A = 'foo', 'bar'. I would like a slice for element bound to value set A but also allow for 'baz' if that is a local extension of the valueset.

view this post on Zulip Grahame Grieve (Nov 25 2021 at 22:07):

I don't know how the documentation could be more clear: you can only slice by a required binding

view this post on Zulip Grahame Grieve (Nov 25 2021 at 22:08):

and the vocabulary committee don't think "extensional definition" makes no sense. it's just what we call 'a value set that enumerates the list of possible codes in the value set' is

view this post on Zulip Lloyd McKenzie (Nov 26 2021 at 05:46):

If the binding is extensible, there's no way for the engine to know when the slice doesn't apply - because any code you send could potentially fall into the 'extensible' space. (And it would take a human being to figure out whether it did or not.)

view this post on Zulip Eric Haas (Nov 26 2021 at 21:10):

IMO This is an academic argument that doesn't reflect the real world and is bad for actual implementation.

view this post on Zulip Grahame Grieve (Nov 26 2021 at 21:11):

no. using an extensible binding for a slice discriminator would be bad for actual implementation

view this post on Zulip Eric Haas (Nov 26 2021 at 21:11):

and what about CodeableConcept with extensiblible bindings - how does that work today?

view this post on Zulip Grahame Grieve (Nov 26 2021 at 21:14):

works moderately badly, but what's the relationship?

view this post on Zulip Eric Haas (Nov 26 2021 at 21:14):

We assumed incorrectly that an extensibly bound element would behave that way too. but alas it does not. So it turns out slicing does not get you that either. This is a gap

view this post on Zulip Eric Haas (Nov 26 2021 at 21:15):

moderately good or badly?

view this post on Zulip Grahame Grieve (Nov 26 2021 at 21:16):

I'm not sure what you're saying here. if your question is, 'can a slice have an extensible binding?' then the answer is yes, of course it can. Just like if it wasn't sliced. But if you question is 'can you discriminate a slice based on an extensible binding?' then the answer is no, you can't discriminate like that

view this post on Zulip Grahame Grieve (Nov 26 2021 at 21:18):

(and slices that can't be discriminated are bad for implementers)

view this post on Zulip Eric Haas (Nov 26 2021 at 21:22):

So one solution could be to describe the discriminator and let Inferno figure it out for certification ... @Yunwei Wang heads up

view this post on Zulip Lloyd McKenzie (Nov 26 2021 at 21:35):

How exactly would you expect the engine to discriminate on an extensible binding @Eric Haas? In what circumstances would an instance not always match the slice with that binding?

view this post on Zulip Grahame Grieve (Nov 26 2021 at 22:00):

So one solution could be to describe the discriminator and let Inferno figure it out for certification

well, FMG isn't going to approve of that, and inferno couldn't figure it out

view this post on Zulip Eric Haas (Nov 27 2021 at 02:24):

These value set are not designed to be required as there is not agreement within a context of use that a specified set of codes are the only ones that can be used. and a required bindings on category slice would imply this. Hopefully we can figure something out.

view this post on Zulip Grahame Grieve (Nov 27 2021 at 06:17):

well, you can have an extensible binding. you just can't slice by it

view this post on Zulip Grahame Grieve (Nov 27 2021 at 06:17):

what's the details?

view this post on Zulip Eric Haas (Nov 27 2021 at 23:11):

(deleted)

view this post on Zulip Eric Haas (Nov 28 2021 at 00:42):

Grahame Grieve said:

well, you can have an extensible binding. you just can't slice by it

We have several instances of extensible bindings on if the element category which usually repeats for example DiagnosticReport.category then If an extensible binding is applied to an element with maximum cardinality > 1, the binding applies to all the elements. (http://hl7.org/fhir/R4/terminologies.html#extensible) That was not our intent and has led to the current situation:

  1. Our intent is only single repeat be bound to the valueset. To illustrate this problem , look at SDOHCC Condition a derived profile from USCore Condition - there SDOH slice which is technically invalid since it does not contain the US Core valueset concepts.
  2. In addition we know our valuesets are incomplete so making it required prohibits other local valid category concepts.

I understand the technical difficulty with this but I can imagine defining multiple orthogonal categorization schemes that could be defined with orthogonal not-fully-realized valuesets at time of publishing.

view this post on Zulip Lloyd McKenzie (Nov 28 2021 at 15:22):

The rules with slicing are simple - the discriminators must discriminate. I.e. no two slices can allow overlapping values for the set of declared discriminators. Two extensible bindings will always overlap even if the base value sets don't because "extensible" means that codes not found within the value set are also allowed.

The best way to accomplish what you're trying to do is have 0..1 must support slices with required bindings. That says "you must be capable of sending and receiving content that looks like this, but it's ok if the category doesn't apply and you're free to send other categories too. Also, you can't have multiple categories from this value set." (Personally, I think that last statement is questionable - if you're going to say that you must ensure that there's never a circumstance where more than one of the codes could apply at the same time.)

view this post on Zulip Grahame Grieve (Nov 28 2021 at 22:03):

generally agree with Lloyd - but it sounds like you really want a pretty general binding and a 'must-support' value set tied to a functional context?

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 14:57):

Having a required or extensible binding across all category repetitions in US-Core is an error. That's saying that every repetition must satisfy the binding, which isn't what you want. If you make category 1..* overall and have a 0..1 required mustSupport slice with your current value set, you'll accomplish your desired outcome. I.e. "Must always have a category. Must send one of our category codes if one of them applies".

view this post on Zulip Eric Haas (Nov 29 2021 at 15:27):

Lloyd McKenzie said:

Having a required or extensible binding across all category repetitions in US-Core is an error. That's saying that every repetition must satisfy the binding, which isn't what you want. If you make category 1..* overall and have a 0..1 required mustSupport slice with your current value set, you'll accomplish your desired outcome. I.e. "Must always have a category. Must send one of our category codes if one of them applies".

I agree and that is what i stated earlier twice and why we are stuck using the more opaque slicing structure

view this post on Zulip Eric Haas (Nov 29 2021 at 15:39):

OK after stewing on this over the weekend.

element 1..* with 1..* slice on extensible binding ( which we can't do :rage:) ~= element 1..* with 0..* slice on required binding

The meaning of a required binding is compromised to allow for slicing in this case and folks reading us core are going to see required and have a cow. We are going to have to document how a required binding slice with a combination of cardinality is really an extensible binding in disguise.

view this post on Zulip Josh Mandel (Nov 29 2021 at 16:33):

I'm confused about the rules for discriminators -- I thought they were technically optional (i.e., without a discriminator, the semantics of slicing still work, just in a less computationally tractable way) per http://build.fhir.org/profiling.html#discriminator .

view this post on Zulip Grahame Grieve (Nov 29 2021 at 18:41):

yes that's right, so why confused?

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 21:59):

If you just express the rules with a description, you still need to express the rules in a way that can meet the requirements - i.e. every slice can be discriminated and every instance repetition matches against no more than one slice. If you've got multiple slices with extensible bindings, that's not possible.

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 22:00):

@Eric Haas Not sure what you mean by "the meaning of a required binding is compromised". I don't think there's any compromise here?

view this post on Zulip Josh Mandel (Nov 29 2021 at 22:04):

So there's (intentionally) no way to use slicing to say:

  • Need at least one Coding from {"A", "B", "C"}
  • Need at least one Coding from {"C", "D", "E"}

... and satisfy the slicing validator with a single Coding "C"?

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 22:06):

Right. Slices must be disjoint.

view this post on Zulip Josh Mandel (Nov 29 2021 at 22:07):

Can you help me with the intuition for why? Is it that use cases like the example above don't really exist? Or that supporting such things would introduce complexities elsewhere?

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:15):

hey no

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:15):

slices don't have to be disjoint, but discriminators have to be disjoint. But slices that are not disjoint are... not anticipated or desired

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:16):

the point of having slices is so that you can describe them differently.

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:21):

the specification does not rule out having over-lapping slices, because we never thought that would be a thing, really. The langauge is written for it not to be a thing, but it's not stated explicitly. E.g.

In this case, the "code" element in the target resource can be used to determine which slice that target refers to

It's always singular - an element fits into one slice. But it's only on discriminators that we say:

When a constraining structure designates one or more discriminators, it SHALL ensure that the possible values for each slice are different and non-overlapping, so that the slices can easily be distinguished

Note, though, that the reason is so that slices can easily be distinguished. Not so that they can be distinguished at all, since the language assumes that each element is in at most, one slice. Which is also how the validator is implemented - it allocates elements to slices, and then validates them against their slice (singular)

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:21):

I'm not in a hurry to change that either - slicing is the most difficult code I've ever written (both the snapshot generation, and the validation)

view this post on Zulip Josh Mandel (Nov 29 2021 at 22:23):

slices don't have to be disjoint, but discriminators have to be disjoint. But slices that are not disjoint are... not anticipated or desired

How can disjoint discriminators result in nondisjoint slices? At this point I'm just trying to follow the logic, not arguing for anything in particular.

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 22:29):

I don't understand how a slice can avoid being disjoint if the discriminators are disjoint? Can you give an example Grahame?

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:30):

if there is no discriminators

view this post on Zulip Grahame Grieve (Nov 29 2021 at 22:35):

the point of discriminators is to discriminate, so if there are any, then conformant slices will be disjoint - they must be.

but if there's no discriminators, then all bets are off. The spec anticipates that they are still disjoint, but it does not say so explicitly. And the validator implements that they are disjoint, but has no way to test that they are, other than trying to match. I guess I'll have to add a test case to find out what happens to my todo list

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 23:07):

If there are no discriminators, isn't the discrimination process defined in text - but still expected to actually discriminate?

view this post on Zulip Grahame Grieve (Nov 29 2021 at 23:15):

doesn't have to be defined in text. if it's not, then it's purely based on validation against the slices.

view this post on Zulip Grahame Grieve (Nov 29 2021 at 23:16):

as for

expected to actually discriminate

yes. it's expected to - at least, we expected it to when we wrote the spec, but we failed to be explicit about it

view this post on Zulip Lloyd McKenzie (Nov 29 2021 at 23:24):

FHIR#34387

view this post on Zulip Eric Haas (Nov 29 2021 at 23:49):

re "the meaning of a required binding is compromised"

required binding definition: "The other place where this is used is when profiling resources, and there is agreement within a context of use that a specified set of codes are the only ones that can be used. In these cases, the data type SHALL contain one of the values in the value set." ( http://hl7.org/fhir/terminologies.html#required )

required binding definition when slicing by valueset : "The other place where this is used is when slicing by valueset. Because it is necessary to define disjoint slices only a specified set of codes even if there is not agreement within a context of use that a specified set of codes are the only ones that can be used" ( my interpretation.)

view this post on Zulip Lloyd McKenzie (Nov 30 2021 at 02:12):

But the point is - within the slice, it is the only set of codes that can be used. You just have other slices that allow for other things too. The meaning of 'required' isn't any different. You're just using it (appropriately) in a more constrained space. Outside that space, the 'required' has no force.


Last updated: Apr 12 2022 at 19:14 UTC