From b8aaa5afc27c4e19815b3712d89f9b3cd66997be Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Mon, 28 Sep 2026 14:30:24 +0100 Subject: [PATCH 1/9] SRL: No rule dependency for WHERE DATA --- sparql12-rl/index.html | 76 ++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index a2b757f82..12526c76a 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -853,6 +853,10 @@

Elements of the Abstract Syntax

It has a negation element body comprised of a sequence of [=triple pattern elements=] and [=filter elements=]. + A [=negation element=] has a flag, + .evaldata + to indicate which graph to use for matching + the [=negation element body=].
Assignment element
@@ -903,9 +907,12 @@

Elements of the Abstract Syntax

Rule
- A [=rule=] contains a [=rule head=] (often just "head") and - a [=rule body=] (often just "body"). - A [=rule=] can be given a URI to help identify it. + A [=rule=] contains a [=rule head=] (often just "head"), + a [=rule body=] (often just "body"), + and a flag, .evaldata + to indicate which + graph to use for matching [=triple patterns=] in the body. + A rule can be given a URI or blank node to help identify it.
Run-once rule
@@ -1043,8 +1050,8 @@

Elements of the Abstract Syntax

The [=rule elements=] of the [=rule=]. - rule.basedata - A boolean flag; if true, the [=rule body=] is matched + rule.evaldata + A boolean flag; if false, the [=rule body=] is matched against the [=base graph=]. @@ -1072,8 +1079,8 @@

Elements of the Abstract Syntax

- negation.basedata - A boolean flag; if true, the `negation.inner` is matched + negation.evaldata + A boolean flag; if false, the `negation.inner` is matched against the [=base graph=]. @@ -1223,7 +1230,10 @@

Rule Dependency

while the rule `R2` might be run again to generate further triples which can then cause `R1` to be reevaluated with the new triples from `R2`.

- +

+ A rule with `.evaldata` set to `false` only matches using the + [=base graph=] and the rule has no dependencies. +

In this first example, the first rule has an open dependency on the second rule. @@ -1280,8 +1290,10 @@

Rule Dependency

Rule dependency

- Rule `R1` [=depends on=] `R2` if any [=triple pattern=] in the body of `R1`, - whether as a [=triple pattern element=] or inside a [=negation element=], + Rule `R1` [=depends on=] `R2` if + `R1.evaldata` is `true` and any [=triple pattern=] in the body of `R1`, + whether as a [=triple pattern element=] or inside a + [=negation element=] `neg` where `neg.evaldata` is `true`, depends on a [=triple template=] in the head of `R2`.

@@ -1293,7 +1305,8 @@

Rule Dependency

if either of the following conditions hold:

@@ -906,7 +906,7 @@

Elements of the Abstract Syntax

Rule
A [=rule=] contains a [=rule head=] (often just "head"), - a [=rule body=] (often just "body"), + a [=rule body=] (often just "body"), and a flag, .evaldata to indicate which graph to use for matching [=triple patterns=] in the body. @@ -948,9 +948,9 @@

Elements of the Abstract Syntax

An [=inference graph=] is an [=RDF Graph=] produced by a rule set evaluation. - It contains all inferred triples not present in the + It contains all inferred triples not present in the [=base graph=] - that are inferred by applying the + that are inferred by applying the [=rule set=] to the [=base graph=].
@@ -1144,7 +1144,7 @@

Well-formedness Conditions

Let Vi - be the union of + be the union of V0 and all varsj, for j from 1 to i.

@@ -1229,7 +1229,7 @@

Rule Dependency

which can then cause `R1` to be reevaluated with the new triples from `R2`.

- A rule with `.evaldata` set to `false` only matches using the + A rule with `.evaldata` set to `false` only matches using the [=base graph=] and the rule has no dependencies.

@@ -1288,9 +1288,9 @@

Rule Dependency

Rule dependency

- Rule `R1` [=depends on=] `R2` if + Rule `R1` [=depends on=] `R2` if `R1.evaldata` is `true` and any [=triple pattern=] in the body of `R1`, - whether as a [=triple pattern element=] or inside a + whether as a [=triple pattern element=] or inside a [=negation element=] `neg` where `neg.evaldata` is `true`, depends on a [=triple template=] in the head of `R2`. @@ -1320,8 +1320,6 @@

Rule Dependency

A [=rule dependency=] of rule `R1` on rule `R2` is an [=open dependency=] if the dependency is not a [=closed dependency=]. - That is, any [=triple pattern=] of `R1` that depends on - `R2` occurs only as a [=triple pattern element=].

@@ -1338,7 +1336,7 @@

Rule Dependency

Similarly, a [=triple pattern=] matches a triple `T1` if there are values for the variables of the - [=triple pattern=] such that replacing variables + [=triple pattern=] such that replacing variables in the pattern by the values, gives a triple `T2` where `T2` equals `T1`. @@ -1349,7 +1347,7 @@

Rule Dependency

is used as the replacement.

- Replacing variables by RDF terms in a triple pattern + Replacing variables by RDF terms in a triple pattern includes replacing variables inside triple terms.

@@ -1552,10 +1550,6 @@

Stratification Condition

in the [=dependency graph=] for a [=rule set=]. -

- In other words, there is no `NOT` or run-once rule (assignment or rule [=triple template=] - involving a blank node) involved in a transitive dependency cycle of the [=dependency graph=]. -

@@ -1830,12 +1824,12 @@

Evaluation Definitions

dom(μ) is replaced by the [=RDF term=] given by the [=solution mapping=] for var. - If the triple pattern result has no variables, then it is an + If the triple pattern result has no variables, then it is an [=RDF Triple=].

The function subst(μ, [=triple template=]) - is similarly defined. Each occurrence of a variable in the + is similarly defined. Each occurrence of a variable in the [=triple template=] is replaced by the [=RDF term=] given by the [=solution mapping=] for var.

From 15be39a8f72db91ffcb90d6e80b2c18b85791041 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Mon, 28 Sep 2026 19:17:16 +0100 Subject: [PATCH 5/9] SRL: Editorial --- sparql12-rl/index.html | 158 ++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index 4d278e3d9..a4853fe98 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -167,7 +167,7 @@ Datalog-style rules language for RDF.

SPARQL-RL generates new RDF data by evaluating a set of declarative - rules against an input RDF graph. Rules are written in a + rules against an input RDF graph. Rules are written in a SPARQL-like text syntax.

@@ -187,15 +187,15 @@

Introduction

The document defines the syntax and semantics of rule-based inference.

- Implementations of SPARQL-RL provide one or both of operations + Implementations of SPARQL-RL provide one or both of the operations infer and query. The infer operation applies the rules to a given - base graph and produces an inference graph containing the - RDF triples derived by rule execution that do not appear in the base graph. + base graph and produces an inference graph containing the + RDF triples derived by rule evaluation that do not appear in the base graph. Combining the inference graph with the base graph is optional and left to users. The query operation determines whether and how a - given goal pattern can be derived from the base graph + given goal pattern can be derived from the base graph using the rules.

@@ -204,11 +204,10 @@

Introduction

SPARQL-RL also supports negation as failure, that could lead to - different inferred graphs depending on the order in which rules are - executed. To avoid this, rules are evaluated using the technique - of stratification, which establishes a single, implicit - ordering among rules, ensuring that the same inference graph is always - produced. + different inference graphs depending on the order in which rules are + evaluated. To avoid this, rules are evaluated using the technique + of stratification, which establishes an ordering among rules, + ensuring that the same inference graph is always produced.

SPARQL-RL can be referred to as SRL when the context is clear. @@ -216,8 +215,8 @@

Introduction

Terminology

- The following other specifications provide fundamental terminology - that is used in this document: + The following specifications provide fundamental terminology + used in this document:

    @@ -269,7 +268,7 @@

    Document Conventions

    - Throughout the document, color-coded boxes containing RDF graphs in + Throughout the document, color-coded boxes containing SPARQL Rules and RDF graphs in Turtle will appear. These fragments of Turtle documents use the prefix bindings given above.

    @@ -292,7 +291,7 @@

    Document Conventions

  • SPARQL-RL syntax
-

A conforming [=SRL document=] is an +

A conforming [=SPARQL-RL document=] is an RDF string that conforms to the grammar starting with the RuleSet @@ -301,12 +300,13 @@

Document Conventions

- This specification does not define how a [=SPARQL-RL processor=] handles non-conforming [=rule sets=]. + This specification does not define how a [=SPARQL-RL processor=] + handles non-conforming [=SPARQL-RL documents=].

-

SPARQL-RL

+

SPARQL-RL Overview

SPARQL-RL infers new triples given a [=base graph=] and a [=rule set=]. @@ -330,18 +330,16 @@

SPARQL-RL

SPARQL-RL execution is defined so that the order of rule execution does not lead to different outcomes when creating new RDF terms, - including new blank nodes, nor when testing for the absence of a - pattern. In other words, the same inference graph is produced + including new blank nodes, or when testing for the absence of a + pattern. In other words, the same inference graph is produced regardless of the order of rule execution.

-

SPARQL-RL has a human-friendly syntax inspired by [[[SPARQL12-QUERY]]]. Rule set evaluation contains elements similar to SPARQL, with differences in the details to ensure that the same inference graph is produced regardless of the order of rule execution.

-

The examples in this section describe software components and their dependencies: a frontend calls an application server, and @@ -355,12 +353,13 @@

Triple Patterns

A [=triple pattern=] is matched against triple data to give values to variables. The pattern has - three elements, each of which is an RDF term, or a variable, + three elements, each of which is an RDF term, a variable, or it can be a pattern for a - triple term. + triple terms + containing variables.

-

In this first example, we have the following data graph and rule set:

+

In this first example, we have the following data in the base graph and rule set:

@@ -2628,7 +2629,7 @@

Evaluating the Strata

SPARQL-RL Grammar

- A SPARQL-RL Document + A SPARQL-RL document is an RDF string encoded in UTF-8 [[!RFC3629]] and starting with the RuleSet @@ -2669,7 +2670,7 @@

Version Announcement

Multiple VERSION directives - may appear in a [=SPARQL-RL Document=]. + may appear in a [=SPARQL-RL document=]. Each directive applies to the part of the document following the directive, until another directive is encountered or the end of the document is reached.

@@ -2687,7 +2688,7 @@

White Space

White space (production WS) is used - to separate two terminals which would otherwise be (mis-)recognized as one + to separate two terminals that would otherwise be (mis-)recognized as one terminal. Rule names below in capitals indicate where white space is significant; these form a possible choice of terminals for constructing a SPARQL-RL parser. @@ -2969,7 +2970,7 @@

Grammar

Selected Terminal Literal Strings

This document uses some specific terminal literal strings - [[EBNF-NOTATION]]. To clarify the Unicode code points used for these + [[EBNF-NOTATION]]. To clarify the Unicode code points used for these terminal literal strings, the following table describes specific characters used in this section.

@@ -3012,12 +3013,12 @@

Selected Terminal Literal Strings

Example Imports Algorithm

- The following algorithm shows one way to resolve imports statements by + The following algorithm shows one way to resolve `IMPORTS` statements by visiting all the referenced documents recursively.

The rule set merge of two rule sets, `RS1` and `RS2`, - is a rule set, `MR`, defined as follows: + produces a rule set, `MR`, defined as follows:

@@ -3034,9 +3035,8 @@ 

Example Imports Algorithm

enddefine define imports(rule set RS): - let I = the set of import URLs declared for the rule set RS let RS2 be a rule set formed from RS.rules and RS.data - foreach URL x in I: + foreach URL x in RS.imports: if x ∉ V: V = V ∪ { x } read rule set RS3 from URL x @@ -3104,7 +3104,7 @@

Internet Media Type and File Extension

The syntax of SPARQL-RL is expressed over code points in Unicode [[UNICODE]]. The encoding is always UTF-8 [[RFC3629]].
Unicode code points may also be expressed using an \uXXXX (U+0 to - U+FFFF) or \UXXXXXXXX syntax (for U+10000 onwards) + U+FFFF) or \UXXXXXXXX syntax (for U+10000 onward) where X is a hexadecimal digit [0-9A-Fa-f], excluding U+D800 to U+DFFF, the surrogate code points. @@ -3175,7 +3175,7 @@

Security Considerations

including out-of-date copies.

- Applying a SPARQL-RL rule set to a data graph can result in + Applying a SPARQL-RL rule set to an RDF graph can result in significant computation and memory usage, which may be exploited to cause denial of service. Applications should take care to limit the amount of computation and @@ -3186,14 +3186,14 @@

Security Considerations

the use of unescaped control characters in string data. Although this specification does not directly expose this content to an end user, it might be presented through a user agent, which may cause the presented text to - be obfuscated due to presentation of such characters. + be misleading due to such characters.

SPARQL-RL can be used to process and create arbitrary application data; security considerations will vary by domain of use. Security tools and protocols applicable to text (for example, PGP encryption, checksum validation, password-protected compression) may also be used on [=SPARQL-RL documents=]. - Security/privacy protocols must be imposed which reflect the sensitivity of the + Security/privacy protocols must be imposed that reflect the sensitivity of the information in the outcome of SPARQL-RL rule set evaluation.

The security considerations of SPARQL-RL include those of @@ -3219,7 +3219,7 @@

Privacy Considerations

-

Acknowledgements

+

Acknowledgments

The following people contributed to the development of SPARQL-RL in the rules task force of the Data Shapes Working Group: From db10b7ada0e5e5d47d50821a93a65e6f850a4c38 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 29 Sep 2026 16:12:20 +0100 Subject: [PATCH 6/9] SRL: Soundness contract for stratification --- sparql12-rl/index.html | 53 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index a4853fe98..01e06799d 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -670,7 +670,7 @@

Evaluation of a Rule Set

  • A [=stratification=] is calculated - () + () so that [=negation elements=] and [=assignment elements=] produce consistent, predictable outcomes. [=Stratification=] involves inspecting the dependencies between rules @@ -1213,7 +1213,7 @@

    Rule Dependency

    A rule `R1` depends on a rule `R2` if the output of the second rule affects the evaluation of the body of the first rule. That is, the head of `R2` - has a [=triple template=] that might generate a triple that matches + has a [=triple template=] that can generate a triple that matches a [=triple pattern=] in the body of `R1`, either as a [=triple pattern element=] or inside a [=negation element=].

    @@ -1275,7 +1275,7 @@

    Rule Dependency

    A [=triple pattern=] depends on a [=triple template=] - if the [=triple pattern=] could possibly match the [=triple template=]. + if the [=triple pattern=] matches the [=triple template=].

    A [=triple pattern=] @@ -1526,10 +1526,37 @@

    Stratification

    Stratification
    - 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=]. +

    + 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=]. +

    +

    + The [=stratification layers=] of a [=stratification=] are numbered + from zero. The stratum number of a [=rule=] is the number + of the [=stratification layer=] that contains the rule. + A rule with a smaller [=stratum number=] is in a lower stratum; + one with a larger [=stratum number=] is in a higher stratum. +

    +

    + For every edge from rule `R1` to rule `R2` in the + [=dependency graph=] of the [=rule set=]: +

    +
      +
    • + if the edge is labeled closed, the [=stratum number=] of + `R1` is strictly greater than the [=stratum number=] of `R2`. +
    • +
    • + if the edge is labeled open, the [=stratum number=] of + `R1` is greater than or equal to the [=stratum number=] of `R2`. +
    • +
    +

    + A [=rule set=] can have more than one [=stratification=]. + An implementation can use any [=stratification=] of the [=rule set=]. +

    @@ -1549,6 +1576,12 @@

    Stratification Condition

    in the [=dependency graph=] for a [=rule set=]. +

    + The [=stratification condition=] is exactly the condition for a + [=stratification=] to exist: a [=stratification=] of a [=rule set=] can + be formed if and only if no cyclic path in the [=dependency graph=] of + the rule set contains a [=closed dependency=]. +

    @@ -1957,8 +1990,10 @@

    Preparation for Evaluation

    .
  • - Calculate the [=stratification=] for the combined rule set, as described in - . + Calculate a [=stratification=] of the combined rule set, as described in + . + + gives one way to calculate a [=stratification=].
  • @@ -2127,7 +2162,7 @@

    Evaluation of a Rule

    Evaluation of a Rule Set

    - Evaluation of a [=rule set=] is defined as the execution of each [=stratum=] of the + Evaluation of a [=rule set=] is defined as the execution of each [=stratum=] of a [=stratification=] of the rule set, where each stratum is executed completely and in order before moving on to the next [=stratum=]. A [=stratum=] is evaluated by first evaluating From f59f558b1cd2425c325ff7ec2875df4f0eb0364b Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 29 Sep 2026 19:14:01 +0100 Subject: [PATCH 7/9] SRL: Extract 'run-once' and remove repetition --- sparql12-rl/index.html | 83 +++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index 01e06799d..9656b0ebd 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -1,4 +1,4 @@ - +each of @@ -812,9 +812,9 @@

    Elements of the Abstract Syntax

    Triple pattern
    - A [=triple pattern=] is a 3-tuple where each element is either a - [=variable=] or an [=RDF term=] - (which might be a triple term with variables). + A [=triple pattern=] is a 3-tuple where each element is + a [=variable=], an [=RDF term=], or a pattern for a + [=triple term=] with [=variables=]. The second element of the tuple must be an [=IRI=] or a [=variable=]. [=Triple patterns=] appear in the [=body=] of a [=rule=] and are used to match [=RDF triples=]. @@ -822,12 +822,19 @@

    Elements of the Abstract Syntax

    Triple template
    - A [=triple template=] is a 3-tuple where each element is either - a [=variable=] or an [=RDF term=] (which might be a - [=triple term=] with variables). - The second element of the tuple must be an [=IRI=] or a [=variable=]. - [=Triple templates=] appear in the [=head=] of a [=rule=] and - are used to generate [=RDF triples=]. +

    + A [=triple template=] is a 3-tuple where each element is + a [=variable=], an [=RDF term=], or a template for a + [=triple term=] with [=variables=]. + The second element of the tuple must be an [=IRI=] or a [=variable=]. + [=Triple templates=] appear in the [=head=] of a [=rule=] and + are used to generate [=RDF triples=]. +

    +

    + A pattern or template for a [=triple term=] in which no + [=variable=] occurs is a [=triple term=], and therefore also + an [=RDF term=]. +

    Filter element
    @@ -914,10 +921,15 @@

    Elements of the Abstract Syntax

    Run-once rule
    - A [=run-once rule=] is a rule that is run exactly once at a - particular point in the evaluation of a rule set. - Such rules involve assignment or create blank nodes - from evaluation of the [=rule head=]. +

    + A [=run-once rule=] is a rule that is run exactly once at a + particular point in the evaluation of a rule set. + A [=rule=] is a [=run-once rule=] if any of the following hold: +

    +
      +
    • the [=rule body=] has an [=assignment element=];
    • +
    • a [=triple template=] of the [=rule head=] has a [=blank node=].
    • +
    General rule
    @@ -1307,9 +1319,7 @@

    Rule Dependency

    matches a [=triple template=] in the [=rule head=] of `R2`.
  • Rule `R1` [=depends on=] rule `R2` - and `R1` is a [=run-once rule=]; that is, - rule `R1` has an [=assignment element=] or - the [=rule head=] of `R1` has a blank node. + and `R1` is a [=run-once rule=].
  • @@ -1445,10 +1455,7 @@

    Dependency Graph Algorithm

    endif foreach pair (triple pattern TP, depLabel) in bodyDependencies: - if R1.body has an assignment element: - set depLabel to "closed" - endif - if R1.head has a triple template with a blank node: + if R1 is a run-once rule: set depLabel to "closed" endif # Find dependencies for this triple pattern element or negation element. @@ -1491,9 +1498,9 @@

    Stratification

    [=Stratification=] imposes constraints on dependencies between [=rules=] - 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=]. + to ensure that [=negation elements=] and [=run-once rules=] depend only + on results computed using earlier (lower) [=strata=] and the + [=base graph=]. This guarantees a single, well-defined, and finite outcome from the evaluation of a [=rule set=] over a given [=base graph=].

    @@ -1516,10 +1523,11 @@

    Stratification

    A [=stratification layer=] `SL` is a pair of disjoint sets of rules (`SL.once`, `SL.general`). - `SL.once` contains [=run-once rules=], which are + `SL.once` contains [=run-once rules=] which are rules that use [=assignment elements=] or produce - blank nodes in the [=rule head=]; these rules are each evaluated exactly - once at the start of evaluation of the [=stratification layer=]. + blank nodes in the [=rule head=]. + These rules are each evaluated + exactly once at the start of evaluation of the [=stratification layer=]. `SL.general` contains the remaining rules, which are evaluated repeatedly until no new triples are inferred.

    @@ -1553,11 +1561,11 @@

    Stratification

    -

    - A [=rule set=] can have more than one [=stratification=]. - An implementation can use any [=stratification=] of the [=rule set=]. -

    +

    + A [=rule set=] can have more than one [=stratification=]. + An implementation can use any [=stratification=] of the [=rule set=]. +

    Stratification Condition

    @@ -1767,13 +1775,12 @@

    Relationship between SPARQL-RL and SPARQL

  • The syntax of `NOT` limits the inner body to triple patterns and filters, and does not allow nested patterns. - `NOT` executes as a filter at the point in the rule body - where it is written, unlike SPARQL `FILTER NOT EXISTS`. + `NOT` executes as a filter at the point in the rule body + where it is written, unlike SPARQL `FILTER NOT EXISTS`.
  • - Property path syntax only covers paths with `/` and `^`. - These that can be expanded into triple - patterns. + Property path syntax only covers paths with `/` and `^`. + These can be expanded into triple patterns. It does not allow the arbitrary length operators `*` and `+`. Arbitrary length paths can be expressed in SPARQL-RL with recursion as a more general approach. @@ -2004,7 +2011,7 @@

    Evaluation of an Expression

    An expression, whether used in a [=filter element=] or an [=assignment element=], is evaluated with - respect to a [=solution mapping=}. The solution mapping provides the + respect to a [=solution mapping=]. The solution mapping provides the RDF term values for each variable in the expression. The well-formedness requirements of ensure that all variables in the expression @@ -2482,7 +2489,7 @@

    Calculating the Stratification

    are final. Each stratum is then partitioned into [=run-once rules=] and [=general rules=]. `R5` has a blank node in its head, so it is a [=run-once rule=]; no other rule - has an [=assignment element=] or a blank node in its head. + of the rule set is a [=run-once rule=]. The stratification is:

      From f64e14f1a5cf49afbaa9f97d9fe5045876244a3e Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 29 Sep 2026 21:17:32 +0100 Subject: [PATCH 8/9] SRL: Add triple term templates to run-once rules --- sparql12-rl/index.html | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index 9656b0ebd..e2ff77a1f 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -1,4 +1,4 @@ -each of + @@ -563,9 +563,11 @@

      Assignment and Creating RDF Terms

      -

      - Rules involving [=assignments=] and rules that create blank nodes - from evaluation of the [=rule head=] are [=run-once rules=]. +

      + Rules involving [=assignments=], rules that create blank nodes + from evaluation of the [=rule head=] and rules with a template + that involves a [=triple term=] containing [=variables=] + are [=run-once rules=]. Such rules are run after all the rules that could produce data that they depend on, and before any rules that depend on the data they produce.

      @@ -573,6 +575,12 @@

      Assignment and Creating RDF Terms

      This condition ensures that such rules do not loop back to themselves and cause the creation of an unbounded number of RDF terms.

      +

      + A constant [=RDF term=] in a [=rule head=] does not make a rule a + [=run-once rule=], even when the term does not occur in the + [=base graph=]: the rule contributes the same term each time it is + evaluated, so it can only add a bounded number of terms. +

      If evaluating the expression in an [=assignment=] causes an error, then the current solution mapping is rejected by the [=assignment=]. @@ -671,7 +679,7 @@

      Evaluation of a Rule Set

    • A [=stratification=] is calculated () - so that [=negation elements=] and [=assignment elements=] produce consistent, + so that [=negation elements=] and [=run-once rules=] produce consistent, predictable outcomes. [=Stratification=] involves inspecting the dependencies between rules (). @@ -928,7 +936,10 @@

      Elements of the Abstract Syntax

      • the [=rule body=] has an [=assignment element=];
      • -
      • a [=triple template=] of the [=rule head=] has a [=blank node=].
      • +
      • a [=triple template=] of the [=rule head=] has a [=blank node=];
      • +
      • a [=triple template=] of the [=rule head=] has a template for a + [=triple term=] in which a [=variable=] occurs. +
      @@ -1523,9 +1534,7 @@

      Stratification

      A [=stratification layer=] `SL` is a pair of disjoint sets of rules (`SL.once`, `SL.general`). - `SL.once` contains [=run-once rules=] which are - rules that use [=assignment elements=] or produce - blank nodes in the [=rule head=]. + `SL.once` contains [=run-once rules=]. These rules are each evaluated exactly once at the start of evaluation of the [=stratification layer=]. `SL.general` contains the remaining rules, which are evaluated @@ -2315,8 +2324,8 @@

      Determining the Dependencies

      only the data. `?y :exposedTo ?v` matches the head template `?x :exposedTo ?v` of `R1`, and also matches the head of `R2` itself. Both occurrences are [=triple pattern elements=] - (they do not occur inside a [=negation element=], and `R2` has - no [=assignment element=] and no blank node in its head), so + (they do not occur inside a [=negation element=], and `R2` is + not a [=run-once rule=]), so `R2` has an open dependency on `R1` and an open dependency on itself. The dependency of `R2` on itself makes `R2` a recursive rule. From 5f9252f1d3333ef620afb9fa582cda418dcfbdd1 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Wed, 30 Sep 2026 13:11:47 +0100 Subject: [PATCH 9/9] SRL: Editorial --- sparql12-rl/index.html | 160 ++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 84 deletions(-) diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index e2ff77a1f..24ade875e 100644 --- a/sparql12-rl/index.html +++ b/sparql12-rl/index.html @@ -44,12 +44,13 @@ w3cid: "73545" } ], + + xref: ["RDF12-CONCEPTS"], lint: { // "informative-dfn": false, "no-unused-dfns": false }, //implementationReportURI: "http://w3c.github.io/data-shapes/sparql12-rl/tests/implementations", - //testSuiteURI: "https://w3c.github.io/data-shapes/shacl12-test-suite/tests/sparql12-rl/", testSuiteURI: "https://github.com/w3c/data-shapes/tree/gh-pages/shacl12-test-suite/tests/sparql-rl", // No previous REC //previousPublishDate: "", @@ -101,10 +102,6 @@ .list-no-bullet { list-style: none; } .list-inner { list-style: disc; } - body { - counter-reset: example; - } - .algorithm { background: #fafafa; border: 1px solid #c0c0c0 ; @@ -203,7 +200,7 @@

      Introduction

      that can be used in triple templates in the head of rules.

      - SPARQL-RL also supports negation as failure, that could lead to + SPARQL-RL also supports negation as failure, which could lead to different inference graphs depending on the order in which rules are evaluated. To avoid this, rules are evaluated using the technique of stratification, which establishes an ordering among rules, @@ -268,9 +265,8 @@

      Document Conventions

      - Throughout the document, color-coded boxes containing SPARQL Rules and RDF graphs in - Turtle will appear. These fragments of Turtle documents use the prefix - bindings given above. + Throughout the document, color-coded boxes contain rules in SPARQL-RL syntax + or contain RDF graphs in Turtle syntax.

              # This box represents rules
      @@ -292,7 +288,7 @@

      Document Conventions

    A conforming [=SPARQL-RL document=] is an - RDF string that + [=RDF string=] that conforms to the grammar starting with the RuleSet production as defined in @@ -354,9 +350,7 @@

    Triple Patterns

    A [=triple pattern=] is matched against triple data to give values to variables. The pattern has three elements, each of which is an RDF term, a variable, - or it can be a pattern for a - triple terms - containing variables. + or is a pattern for a [=triple term=] containing variables.

    In this first example, we have the following data in the base graph and rule set:

    @@ -563,9 +557,9 @@

    Assignment and Creating RDF Terms

    -

    +

    Rules involving [=assignments=], rules that create blank nodes - from evaluation of the [=rule head=] and rules with a template + from evaluation of the [=rule head=] and rules with a template that involves a [=triple term=] containing [=variables=] are [=run-once rules=]. Such rules are run after all the rules that could produce data that they depend on, @@ -648,14 +642,14 @@

    Evaluation of a Rule Set

    A rule set and a data graph (the [=base graph=]) are inputs to evaluation. The output is a graph, called the [=inference graph=], which is the set of triples produced by the evaluation process - that do not appear in the data graph. + that do not appear in the [=base graph=].

    During evaluation, triples inferred based on one rule are available for matching in other rules. Rule set evaluation proceeds until the [=inference graph=] contains all the possible triples from the inputs of - rule set and the [=base graph=]. + the [=rule set=] and the [=base graph=].

    Evaluation starts with steps to @@ -866,7 +860,7 @@

    Elements of the Abstract Syntax

    composed of a sequence of [=triple pattern elements=] and [=filter elements=]. A [=negation element=] has a flag, - .evaldata + .evaldata, to indicate which graph to use for matching the [=negation element body=]. @@ -921,10 +915,10 @@

    Elements of the Abstract Syntax

    A [=rule=] contains a [=rule head=] (often just "head"), a [=rule body=] (often just "body"), - and a flag, .evaldata + and a flag .evaldata to indicate which graph to use for matching [=triple patterns=] in the body. - A rule can be given a URI or blank node to help identify it. + A rule can be given a URI or a blank node to help identify it.
    Run-once rule
    @@ -1053,8 +1047,8 @@

    Elements of the Abstract Syntax

    ruleset.data - The RDF graph - formed by union of the [=data blocks=] in the rule set. + The [=RDF graph=] + formed by the union of the [=data blocks=] in the rule set. @@ -1123,14 +1117,14 @@

    Well-formedness Conditions

    Define well-formedness for a sequence of [=rule elements=] - given an initial set of variables as follows: + given an initial set of variables.

    Let elti be the i-th element of a sequence of [=rule elements=].

    Let varsi be the set of variables defined by - elti where: + elti as follows:

      @@ -1172,7 +1166,7 @@

      Well-formedness Conditions

      Let Vall be the value of VN, - where N is the length of the sequence. + where N is the length of the sequence.

      A well-formed sequence is a sequence of [=rule elements=], @@ -1185,7 +1179,7 @@

      Well-formedness Conditions

    • If elti is a [=filter element=] then
        -
      • every [=variable=] mentioned in a [=filter element=] +
      • every [=variable=] mentioned in the [=filter element=] is an element of Vi-1.
      @@ -1251,7 +1245,7 @@

      Rule Dependency

      which can then cause `R1` to be reevaluated with the new triples from `R2`.

      - A rule with `.evaldata` set to `false` matches using the + A rule with flag `.evaldata` set to `false` matches using the [=base graph=] and the rule has no dependencies.

      @@ -1285,7 +1279,7 @@

      Rule Dependency

      -
      Triple pattern matching
      +
      Triple pattern matching

      A [=triple pattern=] matches a [=triple template=] if @@ -1297,39 +1291,38 @@

      Rule Dependency

      A [=triple pattern=] - depends on a [=triple template=] - if the [=triple pattern=] matches the [=triple template=]. + depends on + a [=triple template=] + if the [=triple pattern=] can + match + the [=triple template=].

      -

      - A [=triple pattern=] - depends on a [=rule=] - if the [=triple pattern=] has dependency on any of the [=triple templates=] - in the [=head=] of the rule. -

      -
      Rule dependency
      + +
      Rule dependency

      - Rule `R1` [=depends on=] `R2` if + Rule `R1` depends on + rule `R2` if `R1.evaldata` is `true` and any [=triple pattern=] in the body of `R1`, whether as a [=triple pattern element=] or inside a [=negation element=] `neg` where `neg.evaldata` is `true`, - depends on - a [=triple template=] in the head of `R2`. + depends on a triple template + in the head of `R2`.

      Closed dependency

      A [=rule dependency=] of rule `R1` on rule `R2` is a [=closed dependency=] - if either of the following conditions hold: + if any of the following conditions hold:

      • A [=triple pattern=] occurring inside a [=negation element=] of `R1` where the [=negation element=] flag `.evaldata` is `true` matches a [=triple template=] in the [=rule head=] of `R2`.
      • -
      • Rule `R1` [=depends on=] rule `R2` +
      • Rule `R1` depends on rule `R2` and `R1` is a [=run-once rule=].
      @@ -1347,17 +1340,17 @@

      Rule Dependency

      A [=triple template=] can generate an - RDF triple `T1` + [=RDF triple=] `T1` if there are values for the variables of the [=triple template=] such that replacing variables by values - in the template, gives a triple `T2` where + in the template gives a triple `T2` where `T2` equals `T1`.

      Similarly, a [=triple pattern=] matches a triple `T1` if there are values for the variables of the [=triple pattern=] such that replacing variables - in the pattern by the values, gives a triple `T2` where + in the pattern by the values gives a triple `T2` where `T2` equals `T1`.

      @@ -1368,8 +1361,7 @@

      Rule Dependency

      Replacing variables by RDF terms in a triple pattern - includes replacing variables inside - triple terms. + includes replacing variables inside [=triple terms=].

      @@ -1429,9 +1421,9 @@

      Dependency Graph Algorithm

      define mergeLabel(oldLabel, newLabel): # Closed dependency overrides open dependency. if oldLabel == "open" and newLabel == "open": - return "open" + the result is "open" else: - return "closed" + the result is "closed" endif enddefine @@ -1521,7 +1513,7 @@

      Stratification

      decisions. This document describes the necessary conditions for consistent evaluation and gives one possible way to form a stratification. Implementations need to meet the conditions - described here in order to get compatible behavior but they are not + described here in order to get compatible behavior, but they are not required to implement the algorithm as presented.

    @@ -1534,11 +1526,11 @@

    Stratification

    A [=stratification layer=] `SL` is a pair of disjoint sets of rules (`SL.once`, `SL.general`). - `SL.once` contains [=run-once rules=]. - These rules are each evaluated + `SL.once` is exactly the [=run-once rules=] of the layer; + these rules are each evaluated exactly once at the start of evaluation of the [=stratification layer=]. - `SL.general` contains the remaining rules, which are evaluated - repeatedly until no new triples are inferred. + `SL.general` is the set of remaining rules of the layer, + which are evaluated repeatedly until no new triples are inferred.

    Stratification
    @@ -1634,16 +1626,16 @@

    Stratification Algorithm

    let qRule = destination of the edge let label = edge label - if label == "open" : - if stratumMap.get(pRule) < stratumMap.get(qRule) : + if label == "open": + if stratumMap.get(pRule) < stratumMap.get(qRule): stratumMap.set(pRule, stratumMap.get(qRule)) changed = true endif endif - if label == "closed" : - if stratumMap.get(pRule) <= stratumMap.get(qRule) : + if label == "closed": + if stratumMap.get(pRule) <= stratumMap.get(qRule): let xStratum = 1 + stratumMap.get(qRule) - if xStratum > limit : + if xStratum > limit: # Stratification requirement violated error "Stratification error" endif @@ -1760,8 +1752,8 @@

    Relationship between SPARQL-RL and SPARQL

    within the [=rule body=].
  • - The SRL `SET` form and SPARQL `BIND` form have different error - handling behavior. An error encountered in `SET` causes the + The SRL `SET` form and SPARQL `BIND` form have different + error-handling behavior. An error encountered in `SET` causes the current solution to be filtered out, whereas `BIND` does not set the variable in the current solution but passes on the solution. SET(?var := expr) would be the same as @@ -1796,7 +1788,7 @@

    Relationship between SPARQL-RL and SPARQL

  • Some functions are not included in the SRL syntax. There is no - `COALESCE`, nor `BOUND`. There are no hash functions. There + `COALESCE` or `BOUND`. There are no hash functions. There is no `RAND`, because it has different results each time it is called.
    @@ -1851,7 +1843,7 @@

    Evaluation Definitions

    >Solution mapping
    A [=solution mapping=], μ, is a partial function - μ : V → T, + μ : V → T, where V is the set of all variables and T is the set of all [=RDF terms=]. The domain of μ is denoted @@ -1917,7 +1909,7 @@

    Evaluation Definitions

    Let G be an [=RDF graph=], TP be a [=triple pattern=], and V be the set of variables occurring in TP.

    -
    graphMatch(G, TP) = { μ | dom(μ) = V and subst(μ, TP) is a triple in G }
    +
    graphMatch(G, TP) = { μ | dom(μ) = V and subst(μ, TP) is a triple in G }
    @@ -1928,7 +1920,7 @@

    Evaluation Definitions

    Let S1 and S2 be solutions.

    -
    compatible(μ1, μ2) = true
    +              
    compatible(μ1, μ2) = true
                           if forall v in dom(μ1) intersection dom(μ2)
                               μ1(v) = μ2(v)
     compatible(μ1, μ2) = false otherwise
    @@ -1951,12 +1943,12 @@ 

    Evaluation Definitions

    Let μ1, μ2 be solution mappings, and S1 and S2 be solution sequences. -
    +              
     merge(μ1, μ2) = μ such that
                         μ(v) = μ1(v) if v in dom(μ1)
                         μ(v) = μ2(v) otherwise
    -
    +              
     merge(S1, S2) = { μ |
                         μ1 in S1, μ2 in S2
                         and compatible(μ1, μ2)
    @@ -2036,7 +2028,7 @@ 

    Evaluation of an Expression

    if F is an RDF term: return F if F is a variable: - # By well-formedness, F ∈ dom(μ). + # By well-formedness, F ∈ dom(μ). return μ(F) # F is of the form F = op(expr1, ..., exprN) if op is a functional form (e.g., IF, logical-or): @@ -2199,7 +2191,7 @@

    Evaluation of a Rule Set

    # Inference graph let GI = { t ∈ D | t ∉ G0 } -# Evaluation graph. +# Evaluation graph and data blocks let GE = G0 ∪ D foreach stratum ST in LS: @@ -2620,7 +2612,7 @@

    Evaluating the Strata

    triples, giving the solutions `?x = :db`, `?x = :app`, and `?x = :frontend`. For each solution, instantiating the head creates a fresh blank node, producing two triples - per solution: a notification for each critical + per solution which are notifications for each critical component. `R5` is not evaluated again, even though the general rules of the stratum will now be evaluated repeatedly. @@ -2681,8 +2673,7 @@

    SPARQL-RL Grammar

    A SPARQL-RL document - is an RDF string - encoded in UTF-8 [[!RFC3629]] and starting with the + is an [=RDF string=] encoded in UTF-8 [[!RFC3629]] and starting with the RuleSet production and conforming to the additional constraints defined in . @@ -2728,7 +2719,7 @@

    Version Announcement

    [=Version labels=] can also be given by the `version` parameter of the - Media Type. In the absence of a current + Media Type. In the absence of a current VERSION directive, the version specified as part of the Media Type is considered.

    @@ -2774,17 +2765,16 @@

    IRI References

    Relative IRI references are resolved with base IRIs as per [[[RFC3986]]] [[RFC3986]] using only the basic algorithm in section 5.2. Neither Syntax-Based Normalization nor Scheme-Based Normalization - (described in sections 6.2.2 and 6.2.3 of RFC3986) are performed. + (described in sections 6.2.2 and 6.2.3 of RFC3986) is performed. Characters additionally allowed in IRI references are treated in the same way that unreserved characters are treated in URI references, per section 6.5 of [[[RFC3987]]] [[RFC3987]].

    The BASE - directive defines the Base IRI used to - resolve relative IRI - references per [[RFC3986]] + directive defines the Base IRI used to resolve + relative IRI references per [[RFC3986]] section 5.1.1, "Base URI Embedded in Content". - Section 5.1.2, "Base URI from the Encapsulating Entity" + section 5.1.2, "Base URI from the Encapsulating Entity" defines how the In-Scope Base IRI may come from an encapsulating document, such as a SOAP envelope with an `xml:base` directive or a MIME multipart document with a `Content-Location` header. @@ -2854,8 +2844,8 @@

    Escape Sequences

    -

    where hex is a hexadecimal character

    -

    HEX ::= [0-9] | [A-F] | [a-f]

    +

    where hex is a hexadecimal character

    +

    HEX ::= [0-9] | [A-F] | [a-f]

  • @@ -2937,7 +2927,7 @@

    Escape Sequences

    IRIs, - used as RDF terms, + used as [=RDF terms=], PREFIX, or BASE declarations yes @@ -3075,7 +3065,9 @@

    Example Imports Algorithm

     let RS be a rule set
     let V = {}
    -if RS has a location, V = { location of RS }
    +if RS has a location:
    +    V = { location of RS }
    +endif
     
     define ruleSetMerge(rule set RS1, rule set RS2):
         let MR be a rule set
    @@ -3187,7 +3179,7 @@ 

    Internet Media Type and File Extension

    The SPARQL-RL 'BASE <IRIref>' term can change the current base URI for relative IRIrefs in the language that - are used sequentially later in the document. + are used later in the document.
    @@ -3244,7 +3236,7 @@

    Security Considerations

    Security tools and protocols applicable to text (for example, PGP encryption, checksum validation, password-protected compression) may also be used on [=SPARQL-RL documents=]. - Security/privacy protocols must be imposed that reflect the sensitivity of the + Security/privacy protocols must be imposed to reflect the sensitivity of the information in the outcome of SPARQL-RL rule set evaluation.

    The security considerations of SPARQL-RL include those of