Skip to content

GH-829: Stratification and evaluation for run-once rules#865

Open
afs wants to merge 2 commits intogh-pagesfrom
rules-run-once
Open

GH-829: Stratification and evaluation for run-once rules#865
afs wants to merge 2 commits intogh-pagesfrom
rules-run-once

Conversation

@afs
Copy link
Copy Markdown
Contributor

@afs afs commented Apr 21, 2026

@afs afs added the Rules For SHACL 1.2 Rules spec. label Apr 21, 2026
@afs afs self-assigned this Apr 21, 2026
@robert-david
Copy link
Copy Markdown
Contributor

This is the correct URI for the githack render:
https://raw.githack.com/w3c/data-shapes/rules-run-once/shacl12-rules/index.html

@robert-david robert-david self-requested a review April 22, 2026 15:22
Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html Outdated
@afs afs force-pushed the rules-run-once branch from 93abf89 to ae2ad35 Compare April 22, 2026 17:33
Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html Outdated
@afs afs force-pushed the rules-run-once branch 2 times, most recently from 6772250 to 0a288c0 Compare April 29, 2026 13:15
@afs afs marked this pull request as ready for review April 29, 2026 13:18
Copy link
Copy Markdown
Contributor

@simonstey simonstey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would following corner cases be classified?

  • A rule with an assignment element AND a negation element -> .once or .general?
  • A rule with blank nodes in the head AND a recursive positive dependency -> .once or .general? If .once, the recursion is lost; if .general, blank nodes generate infinitely.
  • A rule with no assignment elements and no blank nodes in head -> presumably .general, but not stated.
  • A rule with BNODE() in an assignment expression but not in the head -> .once or .general?

Comment thread shacl12-rules/index.html
Comment on lines +858 to +872
A [=stratification layer=], also called a "stratum",
is a pair of sets of rules.
The pair consists of a set of rules that are executed once, for assignment
and blank nodes created in a [=rule head=], and a set of rules
that are evaluated, possibly involving recursion, until there are
no more inferred triples.
A stratum pair <var>P</var> has components <var>P.once</var>
and <var>P.general</var>.
<div class="ednote">create a notation section?</div>
</dd>
<dt><dfn>Stratification</dfn></dt>
<dd>
A [=stratification=] of a [=rule set=] is a sequence of [=stratification layers=].
Each rule in a [=rule set=] appears in exactly one of the sets of one of
the [=stratification layers=].
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this def says a "stratum" it is "a pair of sets of rules": one for rules "executed once" (for assignments and blank nodes in head) and one for general rules. However, there is no normative definition anywhere in the spec that specifies how a rule is classified into .once or .general.

it's somewhat hinted at via: "for assignment and blank nodes created in a [=rule head=]" but I think we should add a precise normative statement such as:

A rule belongs to `P.once` if it contains an [=assignment element=] in its body or a blank node in its [=rule head=]; otherwise it belongs to `P.general`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment on updating the stratification algorithm.

Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html
to ensure that [=negation elements=], [=assignment elements=], and
blank nodes created in a [=rule head=] depend only on results computed
using earlier (lower) [=strata=] and the [=base graph=].
This guarantees a single, well-defined, and finite
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that this paragraph got expanded, shouldn't the strat condition section be expanded accordingly as well?

https://github.com/w3c/data-shapes/pull/865/changes#diff-4cb699e56152bee095a8650906565f110dd7ed444551f33a7b1987a0a92fd214R876-R896:

   <section id="stratification-condition">
          <h4>Stratification Condition</h4>
          <p>
            [=Stratification=] is only defined when the following condition is
            satisfied. If a [=rule set=] does not meet this condition, then this
            specification does not define the outcome of [=rule set=] evaluation.
          </p>
          <dl>
            <dt><dfn>Stratification Condition</dfn></dt>
            <dd>
              The [=stratification condition=] requires that
              there is no [=recursive dependency=] involving a
              <em>negative</em> dependency
              in the [=dependency graph=] for a [=rule set=].
            </dd>
          </dl>
          <p>
            In other words, there is no `NOT` used in any rule that
            transitively depends on itself.
          </p>
        </section>

this still only forbids negative cycles, but says nothing about assignment elements or blank-node-generating rules. There is no condition that requires a rule with assignments or blank nodes in its head to be in a lower stratum than rules it depends on (or that such rules cannot be depending on itsedlf).

bug or feature?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that this paragraph got expanded, shouldn't the strat condition section be expanded accordingly as well?

Yes.

Comment thread shacl12-rules/index.html
let S = {R} &cups; stratumLevel.get(stratumNum)
stratumLevel.set(stratumNum, S)
endfor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add:

## Partition each level into once and general
for i = 0 to maxStratum:
    let rules = stratumLevels.get(i)
    let once = { R in rules | R is a run-once rule }
    let general = rules \ once
    stratumLevels.set(i, pair(once, general))
endfor

Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html Outdated
Comment thread shacl12-rules/index.html
Comment thread shacl12-rules/index.html
@afs afs force-pushed the rules-run-once branch from fb873d5 to fcafc82 Compare May 6, 2026 08:40
@afs
Copy link
Copy Markdown
Contributor Author

afs commented May 6, 2026

how would following corner cases be classified?

  • A rule with an assignment element AND a negation element -> .once or .general?

"once" - that takes precedence.

  • A rule with blank nodes in the head AND a recursive positive dependency -> .once or .general? If .once, the recursion is lost; if .general, blank nodes generate infinitely.

Reject.

  • A rule with no assignment elements and no blank nodes in head -> presumably .general, but not stated.

Will update the stratification algorithm

  • A rule with BNODE() in an assignment expression but not in the head -> .once or .general?

Once.

Copy link
Copy Markdown
Contributor

@recalcitrantsupplant recalcitrantsupplant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one suggested wording for updating the stratification algorithm

Comment thread shacl12-rules/index.html
Comment on lines 890 to 891
</dd>
</dl>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
</dd>
<dd>
In addition, every rule in `P.once` depends only on rules in lower
[=stratification layers=].
</dd>
</dl>

@afs afs force-pushed the rules-run-once branch from fcafc82 to 433a2c1 Compare May 6, 2026 11:08
Co-authored-by: simon <simon.steyskal@siemens.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Rules For SHACL 1.2 Rules spec.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An approach to handling new RDF terms - "run once" rules.

5 participants