Skip to content

[staging] feat(gen-shacl): add a compositional fallback for rule-to-SPARQL conversion - #62

Open
jdsika wants to merge 1 commit into
feat/shaclgen-presence-implies-value-stackedfrom
staging/3990-with-rule-docs
Open

jdsika wants to merge 1 commit into
feat/shaclgen-presence-implies-value-stackedfrom
staging/3990-with-rule-docs

Conversation

@jdsika

@jdsika jdsika commented Oct 30, 2026

Copy link
Copy Markdown

Staging for linkml#3990: the documentation of linkml#3991 folded into linkml#3990's commit, so the rules stack is one PR fewer. Rayene Messaoud stays the author.

After approval this commit is pushed to feat/shaclgen-compositional-rule-fallback (fork #20, linkml#3990) with a lease on 5a673d4c8, and linkml#3991 and fork #23 are closed with a pointer before their branch is deleted. Plan: #61.

…ersion

A rule that no named pattern matches is now composed from the operators
it uses: each precondition becomes SPARQL filters on $this, and each
postcondition slot gets its own constraint, the union of the ways to
violate that slot's condition, binding the offending value to ?value
(SHACL sections 5.3.1 and 5.3.2).  A rule P -> A and B is violated
exactly when P and not A, or P and not B, holds.

A condition may use value_presence, required, equals_string,
equals_string_in, equals_number, pattern, minimum_value, maximum_value,
the slot-level any_of, all_of, exactly_one_of and none_of over those
value tests, a range_expression on the slot's class (nested to any
depth) and has_member.  The semantics follow the JSON Schema
generator's if/then:

- presence: value_presence decides, then required, then a default: a
  precondition requires its slot, a postcondition unless the rule is
  open_world, an inner condition of a nested expression never;
- value operators and range_expression apply to every value of the slot
  (05validation.md: "all members"), has_member to some value;
- equals_string(_in) only on string, enum and boolean slots (the named
  patterns' range check); equals_number and the bounds only on the
  numeric datatypes of SPARQL 1.1 section 17.1, guarded with isNumeric,
  and only finite numbers; pattern as REGEX on the value's string form,
  as sh:pattern reads it (SHACL section 4.4.2);
- a value is one term, so each member of a slot-level boolean is true or
  false, and the operators are those of 05validation.md: exactly_one_of
  counts the members that hold.

Any other operator, or a rule with empty pre- or postconditions, skips
the rule with one warning, so a rule is never partially translated.  A
rule skipped part-way no longer reports the notes of the abandoned
translation.

The compliance suite now runs SHACL in the rule tests, and every rule of
test_preconditions and test_preconditions_combos is translated, so each
instance is checked.

The SHACL generator's documentation now describes the translation: the
two named patterns and the composed one with the operators it supports
and one constraint per postcondition slot, the semantics shared with the
JSON Schema generator, inheritance, open_world, --no-emit-rules and the
skip warnings, with a generated example. The rules section of
advanced.md links to the JSON Schema and SHACL generator pages instead of
a dangling "See above for implementation status".

Co-authored-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants