Repository navigation
Conversation
jdsika
force-pushed
the
feat/shaclgen-has-member-qualified-value-shape
branch
from
October 2, 2026 15:08
21e4983 to
a0b2c05
Compare
jdsika
changed the base branch from
feat/shaclgen-class-boolean-expressions
to
feat/shaclgen-inlined-range-sh-node
October 2, 2026 15:08
jdsika
force-pushed
the
feat/shaclgen-inlined-range-sh-node
branch
from
October 2, 2026 15:13
5db175a to
111a453
Compare
jdsika
force-pushed
the
feat/shaclgen-has-member-qualified-value-shape
branch
from
October 2, 2026 15:13
a0b2c05 to
883509a
Compare
jdsika
force-pushed
the
feat/shaclgen-inlined-range-sh-node
branch
3 times, most recently
from
October 5, 2026 09:52
937b986 to
3f14cf9
Compare
jdsika
marked this pull request as draft
October 5, 2026 11:26
jdsika
force-pushed
the
feat/shaclgen-has-member-qualified-value-shape
branch
from
October 5, 2026 11:47
883509a to
c94f379
Compare
jdsika
marked this pull request as ready for review
October 5, 2026 12:01
jdsika
force-pushed
the
feat/shaclgen-inlined-range-sh-node
branch
2 times, most recently
from
October 7, 2026 20:03
68430f4 to
46c2ab1
Compare
jdsika
force-pushed
the
feat/shaclgen-has-member-qualified-value-shape
branch
from
October 7, 2026 21:09
c94f379 to
23553b9
Compare
has_member asks for at least one value of a multivalued slot satisfying an expression. gen-shacl ignored it. gen-json-schema translated it as contains, which an absent slot passes but an empty one fails, applied only the value operators of the expression, and ignored it in class-level expressions. Both generators now read a member as one value, which must satisfy the value operators, range and range_expression of the expression. A slot without a value has no member, so has_member decides presence. In SHACL it is an sh:qualifiedValueShape with sh:qualifiedMinCount 1; in JSON Schema, contains on a required slot, or some value of a dict inlined by key. In a slot condition the member takes the form of the condition. SHACL skips a has_member it cannot express with a warning. Signed-off-by: jdsika <[email protected]>
jdsika
force-pushed
the
feat/shaclgen-inlined-range-sh-node
branch
from
October 14, 2026 05:44
46c2ab1 to
3f2a2ba
Compare
jdsika
force-pushed
the
feat/shaclgen-has-member-qualified-value-shape
branch
from
October 14, 2026 06:00
23553b9 to
a7becc8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #30. Covers upstream linkml#2465 (gen-shacl ignores
has_member).Change
has_memberasks for "at least one member satisfying the condition" of a multivalued slot. Both generators now read it the same way: a member is one value, which must satisfy the value operators,rangeandrange_expressionof the expression.tags[][pending][reviewed, pending]has_member. It now emitssh:qualifiedValueShapewithsh:qualifiedMinCount 1(SHACL §4.7.3), on slots and in slot conditions of class-level expressions.has_memberin class-level expressions. It now emitscontainson a required slot. For a slot inlined as a dict it emitsnot: {additionalProperties: {not: <member>}}, becausecontainsdoesn't apply to objects.has_memberdecides presence (an absent slot fails it), and the member takes the form of the condition: "definitely true" undernone_of.Decisions
A slot without a value has no member, so an absent slot and
[]both fail. The evidence:value_presencesays that for lists, ABSENT means empty;has_memberon[]is invalid;owl:someValuesFrom.gen-json-schema accepted an absent slot but rejected
[], a distinction RDF can't express.This changes gen-json-schema: an optional slot with
has_memberis now required. Thehas_membercases ofjsonschema_multivalued_element_constraints.yamlmove tojsonschema_multivalued_has_member.yaml, which adds the absent, empty andnullcases.Skipped by SHACL, with a warning:
has_memberon a single-valued slot; the metamodel says "the value of the slot is multivalued";minimum_cardinality,any_of, …);equals_stringon a reference; that is fork issue gen-shacl rules: translate equals_string on IRI- and typed-literal-valued ranges (follow-up to linkml/linkml#3989) #37.Dropped from the earlier version: comparing
equals_stringwith class references by IRI (issue gen-shacl rules: translate equals_string on IRI- and typed-literal-valued ranges (follow-up to linkml/linkml#3989) #37),equals_expression(see fix(generators): enforce range_expression on each value alike in SHACL and JSON Schema #30), raising on unsupported input, and the changes to rules, which keep their own reading (feat(gen-shacl): translate presence-implies-value rules to SHACL-SPARQL linkml/linkml#3989).Other generators
owl:someValuesFromunder open-world semantics; unchanged.has_membersupport; unchanged.has_member; the rules stack (feat(gen-shacl): translate presence-implies-value rules to SHACL-SPARQL #19/feat(gen-shacl): add a compositional fallback for rule-to-SPARQL conversion #20) adds it to gen-shacl's composed rule translation.Validation
test_has_member.py: 48 cases. They validate the same instance with both generated artifacts (RDF through the generated JSON-LD context), plus SHACL-only and JSON-only cases. 34 fail on fix(generators): enforce range_expression on each value alike in SHACL and JSON Schema #30.has_memberon slots and in class-level conditions, with memberrange_expression). gen-shacl, gen-json-schema and an independent three-valued model agreed on all of them. That harness is not part of this PR.states_presence.test_membershipnow expects SHACL to implementhas_member, except on references.tests/linkml/utils/generator_agreement.py, shared with these tests.