diff --git a/sparql12-rl/index.html b/sparql12-rl/index.html index a2b757f82..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 ; @@ -167,7 +164,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 +184,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.

@@ -203,12 +200,11 @@

Introduction

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

- 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. + 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, + ensuring that the same inference graph is always produced.

SPARQL-RL can be referred to as SRL when the context is clear. @@ -216,8 +212,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:

-

A conforming [=SRL document=] is an - RDF string that +

A conforming [=SPARQL-RL document=] is an + [=RDF string=] that conforms to the grammar starting with the RuleSet production as defined in @@ -301,12 +296,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 +326,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 +349,11 @@

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, - or it can be a pattern for a - triple term. + three elements, each of which is an RDF term, a variable, + or is a pattern for a [=triple term=] 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:

- 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.

This condition ensures that such rules do not loop back to themselves - and cause an unbounded number of RDF terms. + 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, @@ -591,8 +592,8 @@

Importing Rule Sets

The `IMPORTS` statements of a rule set are processed before any of the rules in the rule set are evaluated. During the importing step, if an imported rule set has its own imports, those are also processed recursively. - Traversing `IMPORTS` statements during the processing of rule sets may lead to - cyclic imports. A rule set is imported only once; + Traversing `IMPORTS` statements during the processing of rule sets may + encounter cyclic imports. A rule set is imported only once; cycles in the import statements graph do not lead to infinite loops.

@@ -641,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 data graph. + the [=rule set=] and the [=base graph=].

Evaluation starts with steps to @@ -664,15 +665,15 @@

Evaluation of a Rule Set

to the processor ().
  • - Check each rule is a [=well-formed rule=]. + Check that each rule is a [=well-formed rule=].
  • Calculate the [=dependency graph=].
  • 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 (). @@ -795,15 +796,13 @@

    Elements of the Abstract Syntax

    Expression
    - An [=expression=] is a function or a functional form; - the arguments are [=RDF terms=]. + An [=expression=] is an [=RDF term=], a [=variable=], + or the application of a function or a functional form to arguments, + where each argument is itself an [=expression=]. An expression is evaluated with respect to a [=solution mapping=], giving - an [=RDF term=] as the result. + an [=RDF term=] as the result, or evaluation results in an error. Expressions are compatible with - SPARQL expressions - and - SHACL list parameter functions. + SPARQL expressions.
    Data block
    @@ -815,9 +814,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=]. @@ -825,12 +824,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
    @@ -851,8 +857,12 @@

    Elements of the Abstract Syntax

    A [=negation element=] is a [=rule element=]. It has a negation element body - comprised of a sequence of [=triple pattern elements=] and + composed 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,17 +913,28 @@

    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 a blank node to help identify it.
    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=];
    • +
    • a [=triple template=] of the [=rule head=] has a template for a + [=triple term=] in which a [=variable=] occurs. +
    • +
    General rule
    @@ -928,24 +949,24 @@

    Elements of the Abstract Syntax

    a collection of zero or more [=data blocks=], and a collection of zero or more [=rule set imports=]. A resolved rule set is a [=rule set=] - which has no imports. + that has no imports. A [=resolved rule set=] is created from another [=rule set=] by applying the imports process.
    Base graph
    - A [=base graph=] is the [=RDF Graph=] given as input to the + A [=base graph=] is the [=RDF graph=] given as input to the evaluation process.
    Inference graph
    - An [=inference graph=] is an [=RDF Graph=] produced by + 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=].
    @@ -955,7 +976,7 @@

    Elements of the Abstract Syntax

    to a [=base graph=] to produce an [=inference graph=]. A rule evaluation is the process of evaluating a rule once. Evaluating a rule produces all the triples given by the [=rule head=] - given the evaluation of the [=rule body=], regardless of whether a + by the evaluation of the [=rule body=], regardless of whether a triple is in the [=base graph=], already inferred during [=rule set evaluation=], or is a new inferred triple. During [=rule set evaluation=], a rule may be evaluated more than once. @@ -1026,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. @@ -1043,8 +1064,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 +1093,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=]. @@ -1095,7 +1116,7 @@

    Well-formedness Conditions

    one that has not been used earlier in the rule body.

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

    @@ -1103,7 +1124,7 @@

    Well-formedness Conditions

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

      @@ -1139,13 +1160,13 @@

      Well-formedness Conditions

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

      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=], @@ -1158,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.
      @@ -1209,7 +1230,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=].

      @@ -1223,7 +1244,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 flag `.evaldata` set to `false` 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. @@ -1255,7 +1279,7 @@

      Rule Dependency

      -
      Triple pattern matching
      +
      Triple pattern matching

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

      Rule Dependency

      A [=triple pattern=] - depends on a [=triple template=] - if the [=triple pattern=] could possibly match 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 any [=triple pattern=] in the body of `R1`, - whether as a [=triple pattern element=] or inside a [=negation element=], - depends on - a [=triple template=] in the head of `R2`. + 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`.

      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` +
      • 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` - 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. +
      • Rule `R1` depends on rule `R2` + and `R1` is a [=run-once rule=].
      @@ -1309,8 +1333,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=].

      @@ -1318,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 + [=triple pattern=] such that replacing variables + in the pattern by the values gives a triple `T2` where `T2` equals `T1`.

      @@ -1338,9 +1360,8 @@

      Rule Dependency

      is used as the replacement.

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

      @@ -1381,7 +1402,7 @@

      Dependency Graph

      - The dependency graph is not affected by the data graph. + The dependency graph is not affected by the [=base graph=].

  • @@ -1400,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 @@ -1412,30 +1433,32 @@

    Dependency Graph Algorithm

    let edgeLabelMap be a map from pair (rule, rule) to label foreach rule R1 in ruleSet.rules: - # Classify each triple pattern TP in the rule as requiring "open" or "closed" - # depending on whether it is in a negation element or not. let bodyDependencies = {} - foreach rule element RBE in R1.body: - if RBE is a negation element: - foreach triple pattern TP in RBE.inner: - let item be a pair (TP, "closed") + + if R1.evaldata then: + # Classify each triple pattern TP in the rule as requiring "open" or "closed" + # depending on whether it is in a negation element or not. + foreach rule element RBE in R1.body: + if RBE is a negation element: + if RBE.evaldata then: + foreach triple pattern TP in RBE.inner: + let item be a pair (TP, "closed") + add item to bodyDependencies + endfor + endif + else if RBE is a triple pattern element of triple pattern TP: + let item be a pair (TP, "open") add item to bodyDependencies - endfor - else if RBE is a triple pattern element of triple pattern TP: - let item be a pair (TP, "open") - add item to bodyDependencies - else if RBE is a filter element: - # Do nothing - else if RBE is an assignment element: - # Do nothing - endif - endfor + else if RBE is a filter element: + # Do nothing + else if RBE is an assignment element: + # Do nothing + endif + endfor + 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. @@ -1478,9 +1501,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=].

    @@ -1490,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.

    @@ -1503,21 +1526,47 @@

    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=]; 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.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` is the set of remaining rules of the layer, + which are evaluated repeatedly until no new triples are inferred.

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

    +
    +

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

    Stratification Condition

    @@ -1536,9 +1585,11 @@

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

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

    @@ -1575,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 @@ -1701,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 @@ -1715,7 +1766,7 @@

    Relationship between SPARQL-RL and SPARQL

    does not include `UNION` or `OPTIONAL` syntax. These SPARQL elements can lead to unbound variables. The effect of `UNION` or `OPTIONAL` can be achieved using - [=well-formed rules=] so that the [=rule set=] can be analyzed. + [=well-formed rules=].
  • @@ -1724,24 +1775,25 @@

    Relationship between SPARQL-RL and SPARQL