From 11ede3fe2e8b66fd1b9855071f24f5a4e951be9c Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Wed, 17 Jun 2026 14:19:25 +0100 Subject: [PATCH 01/23] Editorial changes (rules) --- shacl12-rules/index.html | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 08df10d8..5f02a251 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -262,10 +262,6 @@

Document Conventions

srl: http://www.w3.org/ns/shacl-rules# - - shnex: - http://www.w3.org/ns/shacl-node-expr# - xsd: http://www.w3.org/2001/XMLSchema# @@ -317,7 +313,7 @@

Document Conventions

-

@@Needs adjusting and links

+

This specification defines conformance criteria for:

From 0806497fc5dac3126e0781a6cf5a419f14e191ce Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Wed, 24 Jun 2026 12:19:09 +0100 Subject: [PATCH 10/23] Need assignment examples --- shacl12-rules/index.html | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 8bb37d3f..02119401 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -591,17 +591,29 @@

Assignment and Creating RDF Terms

- This can be combined with testing for the absence of a triple - already recording the distance in kilometers. + Blank nodes can be used in the rule head, and these generate a fresh blank node + each time rule evaluation generates triples.

-            RULE { ?x :distanceKm ?kilometers }
+            # @@ example.
+            RULE { [] :distanceKm ?kilometers }
             WHERE { 
-            ?x :distanceMiles ?miles
-            NOT { ?x :distanceKm ?km }
-            SET ( ?kilometers := ?miles * 1.60934 )
+              . . .
             }
+          
+
+

+ Also: +

+
+
+           RULE { [] :effectiveDistanceKm ?kilometers }
+           WHERE { 
+              ?x :distanceMiles ?miles
+              NOT { ?x :distanceKm ?km }
+              SET ( ?kilometers := ?miles * 1.60934 )
+          }
           

From 78cf0b4ccbfa7e8b3f6a68a14921efbc1f0cfa1a Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Wed, 24 Jun 2026 16:22:14 +0100 Subject: [PATCH 11/23] Restyle (rules) --- shacl12-rules/index.html | 371 +++++++++++++++++++-------------------- 1 file changed, 184 insertions(+), 187 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 02119401..4be4ca39 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -73,69 +73,6 @@ @@ -300,9 +277,13 @@

Document Conventions

Reset. Use reSpec default appearance where appropiate.

-
        # This box represents rules
-
        # This box represents input data
-
        # This box represents inferred data
+ +
        # This box represents rules
+ +
       # This box represents input data
+ +
        # This box represents inferred data
+ @@ -416,46 +397,44 @@

Basic Patterns

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

-
-
+        
- -
-
+          
             RULE { ?x :childOf ?y } WHERE { ?y :fatherOf ?x }
             RULE { ?x :childOf ?y } WHERE { ?y :motherOf ?x }
           
-
-

The above rules, applied to the data, will conclude - that: `:X` is the `:childOf` `:A` and `:B`: -

-
-
+          
             :X :childOf :A .
             :X :childOf :B .
             :A :childOf :C .
           
-
+ + +

The above rules, applied to the data, will conclude + that: `:X` is the `:childOf` `:A` and `:B`: +

+

We can then derive `:descendedFrom` relationships by adding a rule that depends on `:childOf` triples produced by the other rules:

-
-
+        
+        
-

- The outcome is: -

-
-
+          
             :A :descendedFrom :C .
             :X :descendedFrom :B .
             :X :descendedFrom :A .
@@ -463,7 +442,8 @@ 

Basic Patterns

:X :childOf :A . :A :childOf :C .
-
+ +

Recursion

@@ -471,17 +451,15 @@

Recursion

We can add a rule that depends on `:descendedFrom` triples to infer that `:X` is `:descendedFrom` `:C`:

-
-
+
+        
-

giving:

-
-
+          
             :A :descendedFrom :C .
             :X :descendedFrom :C .
             :X :descendedFrom :B .
@@ -490,7 +468,8 @@ 

Recursion

:X :childOf :A . :A :childOf :C .
-
+ +

This adds the triple `:X :descendedFrom :C`.

This last rule is a recursive rule, the body of the rule @@ -508,22 +487,23 @@

Filtering

we can infer a class for towns with a population greater than 1500:

-
-
+        
-
-
-            RULE { ?x rdf:type :largeTown } WHERE { ?x :population ?p . FILTER(?p > 1500) }
-          
-
-
-
+          
+
+            RULE { ?x rdf:type :largeTown } 
+            WHERE { 
+                ?x :population ?p 
+                FILTER(?p > 1500)
+            }
+          
+
             :town2 rdf:type :largeTown .
-          
-
+ + +

`FILTER` evaluates an expression and keeps the current set of variable bindings if the expression evaluates to true, and it discards the @@ -548,8 +528,9 @@

Negation

on all the relevant possible triples, whether from the data or from inferred triples inferred by other rules.

-
-
+
+        
-
-
-            RULE { ?x rdf:type :UnclassifiedSize } WHERE { 
-            ?x rdf:type :Place .
-            NOT { ?x :population ?p . }
+          
+            RULE { ?x rdf:type :UnclassifiedSize } 
+            WHERE { 
+                ?x rdf:type :Place .
+                NOT { ?x :population ?p . }
             }
           
-
-
-
+          
             :X3 rdf:type :UnclassifiedSize .
           
-
+ +
@@ -581,41 +560,32 @@

Assignment and Creating RDF Terms

in the body of a rule. This can be used to create new RDF terms based on the data.

-
-
-            RULE { ?x :distanceKm ?kilometers }
+
+        
+ + +

Blank nodes can be used in the rule head, and these generate a fresh blank node each time rule evaluation generates triples.

-
-
-            # @@ example.
-            RULE { [] :distanceKm ?kilometers }
+
+        
-

- Also: -

-
-
-           RULE { [] :effectiveDistanceKm ?kilometers }
-           WHERE { 
-              ?x :distanceMiles ?miles
-              NOT { ?x :distanceKm ?km }
-              SET ( ?kilometers := ?miles * 1.60934 )
-          }
-          
-
+ + +

Rules involving [=assignments=] and rules that create blank nodes in their [=rule head=] are [=run-once rules=]. @@ -661,14 +631,25 @@

Data Blocks

@@examples to be updated

-
-
+        
+ + +
+ +
+

Rule Set Execution

+

+ @@Rules form rule sets. +

+

+ @@evaluation is a graph and a rule set +

@@ -1069,19 +1050,29 @@

Rule Dependency

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

-

In this first example, the first rule depends on the second rule. It is an open dependency.

-
-
-    RULE { ?x :descendedFrom ?y } WHERE { ?x :childOf ?y }
-    RULE { ?x :childOf ?y } WHERE { ?y :fatherOf ?x }
-
-
-

In this second example, the first rule depends on the second rule. It is a closed dependency.

-
-
-    RULE @@
-
-
+

+ In this first example, the first rule depends on the second rule. + It is an open dependency. +

+ + + +

+ In this second example, the first rule depends on the second rule. + It is a closed dependency. +

+ + +
Triple pattern matching
@@ -1300,16 +1291,17 @@

Dependency Graph Algorithm

Examples:

-
-
-            @@ Examples of triple patttern dependencies.
+
+        
-
-
-            @@ Examples of rule dependencies.
+        
+        
+
@@ -1492,23 +1484,26 @@

Concrete Syntax forms for the Shape Rules Language

Shape Rules Language:

-
-
-PREFIX : <http://example/>
 
-DATA { :x :p 1 ; :q 2 . }
+      
 
-RULE { ?x :oneIsZero true . }
-WHERE { ?x :p ?v1 ;  :q ?v2  FILTER ( ( ?v1 = 0 ) || ( ?v2 = 0 ) )  }
-
-

RDF Rules syntax:

-
+        
+

Shape Rules Language syntax

@@ -1630,7 +1626,8 @@

RDF Rules Syntax

@@ Illustration: SHACL rule set in text and RDF syntaxes: all features:

-
+        
+
 PREFIX :        <http://example/>
 
 DATA { :s :p :o }
@@ -1640,7 +1637,7 @@ 

RDF Rules Syntax

RULE { ?x :q ?o } WHERE { ?x :p :o . SET (?o := 18) } RULE { ?x :q ?o } WHERE { ?x :p :o . NOT { ?s :p ?o . FILTER(?o < 18) } }
-
+
 PREFIX :       <http://example/>
 PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
 PREFIX sh:     <http://www.w3.org/ns/shacl#>

From 1a921e0fe2b0c85f9bc038cacc72158fccddf273 Mon Sep 17 00:00:00 2001
From: Andy Seaborne 
Date: Wed, 24 Jun 2026 16:25:22 +0100
Subject: [PATCH 12/23] Update shacl12-rules/index.html

Co-authored-by: Ted Thibodeau Jr 
---
 shacl12-rules/index.html | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html
index 4be4ca39..88b54346 100644
--- a/shacl12-rules/index.html
+++ b/shacl12-rules/index.html
@@ -668,7 +668,7 @@ 

Relationship between SHACL Rules and SPARQL

A rule body has restrictions compared to SPARQL `CONSTRUCT`, such as not having `OPTIONAL`. These ensure that variables are always bound, where in SPARQL, some - variables may not be bound in all pattern solutions. + variables might not be bound in all pattern solutions.
  • The rules `SET` form and SPARQL `BIND` form have different error handling behavior. An error encountered in `SET` causes the current solution to be filtered out. @@ -686,7 +686,7 @@

    Relationship between SHACL Rules and SPARQL

    There are no hash functions. There is no `RAND`, which has different results each time it is called; `NOW()` is permitted and is defined to return - the same point in time through a rule set evaluation, similar + the same point in time throughout a rule set evaluation, similar to the behavior in SPARQL.
  • @@ -1948,9 +1948,9 @@

    Evaluation of an Expression

     define evalFunction(F, μ):
    -    ## Evaluation of F may be defined specifically for F
    -    ## For example `COALESCE` only evaluates arguments until one evaluation of an
    -    ##   expression does not return an error.
    +    ## Evaluation of F may be defined specifically for F.
    +    ## For example, `COALESCE` only evaluates arguments until
    +    ##   one evaluation of an expression does not return an error.
         let [x/μ] be
             if x is an RDF term, then [x/row] equals x
             if x is a variable, then [x/row] is μ(x):
    @@ -2399,7 +2399,7 @@ 

    Grammar

    Notes:

    1. - The entry point into the grammar is RuleSet. + The entry point of the grammar is RuleSet.
    2. Keywords are case-insensitive except for From eff24f8d334f97b1506bd64b80632aa6f4a9fd0b Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Thu, 25 Jun 2026 12:27:06 +0100 Subject: [PATCH 13/23] Informal overview of evaluation --- shacl12-rules/index.html | 43 +++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 88b54346..a2d7efaa 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -642,14 +642,47 @@

      Data Blocks

    -
    -

    Rule Set Execution

    +
    +

    Rule Set Evaluation

    - @@Rules form rule sets. + Rules are organised into [=rule sets=]. + A rule set and data graph (the [=base graph=]) are inputs to evaluation. + The output is a graph of inferred triples where the + inferred triples do not appear in the data graph.

    - @@evaluation is a graph and a rule set -

    + During evaluation, the inferred triples from 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. +

    +

    + Evaluation starts with two steps to + prepare a rule set + before the rules themselves are evaluated: +

    +
      +
    • + The imports of input rule set are resolved to form a + rule set that includes all the rules of all + imported rule sets. + (). +
    • +
    • + A [=stratification=] is calculated ( + so that [=negation elements=] and [=assignment elements=] produce consistent, + predictable outcomes. [=Stratification=] involves inspecting the dependencies + between rules + (). +
    • +
    +

    + Once a [=rule set=] has been prepared, evaluation proceeds + by taking each layer from the stratification, in order, + and evaluating the rules in that layer to completion, + then moving on to the next layer. +

    From 4d097599055a56b9f48e62a680dc682cf5e8d606 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 27 Jun 2026 18:31:14 +0100 Subject: [PATCH 14/23] Update shacl12-rules/index.html Co-authored-by: Ted Thibodeau Jr --- shacl12-rules/index.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index a2d7efaa..5ced99f6 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -651,7 +651,7 @@

    Rule Set Evaluation

    inferred triples do not appear in the data graph.

    - During evaluation, the inferred triples from one rule are + 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 @@ -662,9 +662,9 @@

    Rule Set Evaluation

    prepare a rule set before the rules themselves are evaluated:

    -
      +
      1. - The imports of input rule set are resolved to form a + The imports of the input rule set are resolved to form a rule set that includes all the rules of all imported rule sets. (). @@ -676,12 +676,12 @@

        Rule Set Evaluation

        between rules ().
      2. -
    +

    Once a [=rule set=] has been prepared, evaluation proceeds by taking each layer from the stratification, in order, - and evaluating the rules in that layer to completion, - then moving on to the next layer. + evaluating the rules in that layer to completion, + and then moving on to the next layer.

    From d1ece7f5a09934a86f98bef924048b8b39da8180 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Sat, 27 Jun 2026 18:37:11 +0100 Subject: [PATCH 15/23] Edits - resolved and imports --- shacl12-rules/index.html | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 5ced99f6..316e9d09 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -647,8 +647,8 @@

    Rule Set Evaluation

    Rules are organised into [=rule sets=]. A rule set and data graph (the [=base graph=]) are inputs to evaluation. - The output is a graph of inferred triples where the - inferred triples do not appear in the data graph. + The output is a graph, called the [=inference graph=], + where the inferred triples do not appear in the data graph.

    During evaluation, triples inferred based on one rule are @@ -898,9 +898,10 @@

    Elements of the Abstract Syntax

    A [=rule set=] is a collection of zero or more [=rules=], a collection of zero or more [=data blocks=], and a collection of zero or more [=rule imports=]. - A resolved rule set is a rule formed by applying the - imports process. - A resolved rule set has no imports. + A resolved rule set is a [=rule set=] + which has no imports. + A [=resolved rule set=] is created from another [=rule set=] + by applying the imports process.
    Base graph
    @@ -1907,9 +1908,9 @@

    Preparation for Evaluation

    Process Imports

    - All rule sets mentioned in the imports of a [=rule set=] - are recursively read to form a single rule set with the reachable rules and data - and with no imports. + A [=resolved rule set=] is produced from another rule set by + recursively reading all rule sets mentioned + in the imports of that other [=rule set=].

    @@ -1935,7 +1936,7 @@

    Process Imports

     define imports(rule set RS, set of URLs V), returning rule set
         let I = the set of import URLs declared for the rule set RS
    -    let RS2 = RS
    +    let RS2 be a rule set formed from RS.rules and RS.data
         foreach URL x in I:
             if x ∉ V:
                 V = V ∪︀ { x }
    
    From 0b6c962de2775eadd3efdf8e4e0907ae179387a1 Mon Sep 17 00:00:00 2001
    From: Andy Seaborne 
    Date: Mon, 29 Jun 2026 09:10:01 +0100
    Subject: [PATCH 16/23] SET equivalent to BIND+FILTER
    
    ---
     shacl12-rules/index.html | 11 ++++++++---
     1 file changed, 8 insertions(+), 3 deletions(-)
    
    diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html
    index 316e9d09..e490cbf3 100644
    --- a/shacl12-rules/index.html
    +++ b/shacl12-rules/index.html
    @@ -704,7 +704,11 @@ 

    Relationship between SHACL Rules and SPARQL

    variables might not be bound in all pattern solutions.
  • The rules `SET` form and SPARQL `BIND` form have different error handling behavior. An - error encountered in `SET` causes the current solution to be filtered out. + error encountered in `SET` causes the current solution to be filtered out, whereas + `BIND` does not set the the variable in the current solution. + `SET(?var := expr)` would be the same as + `BIND(expr AS ?var) FILTER(BOUND(?var))`. +
  • Rules `NOT`, unlike SPARQL `EXISTS` and `NOT EXISTS`, has a body restricted to @@ -1983,8 +1987,9 @@

    Evaluation of an Expression

     define evalFunction(F, μ):
         ## Evaluation of F may be defined specifically for F.
    -    ## For example, `COALESCE` only evaluates arguments until
    -    ##   one evaluation of an expression does not return an error.
    +    ## For example, `IF` only evaluates one or other of 
    +    ## the 2nd and 3rd arguments, based on the outcome of
    +    ## the first argument.
         let [x/μ] be
             if x is an RDF term, then [x/row] equals x
             if x is a variable, then [x/row] is μ(x):
    
    From 41b40ccaf1c270f5a27ed722f71c6496df5255c2 Mon Sep 17 00:00:00 2001
    From: Andy Seaborne 
    Date: Tue, 30 Jun 2026 09:00:00 +0100
    Subject: [PATCH 17/23] GH-516: Refine SET and BIND/FILTER
    
    ---
     shacl12-rules/index.html | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html
    index e490cbf3..3e961fc2 100644
    --- a/shacl12-rules/index.html
    +++ b/shacl12-rules/index.html
    @@ -706,8 +706,10 @@ 

    Relationship between SHACL Rules and SPARQL

    The rules `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 the variable in the current solution. - `SET(?var := expr)` would be the same as - `BIND(expr AS ?var) FILTER(BOUND(?var))`. + SET(?var := expr) would be the same as + SPARQL with + BIND(expr AS ?var) followed by + FILTER(BOUND(?var)).
  • From 15d80251ec100636810a6892af1195deb828c0ab Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 30 Jun 2026 09:02:21 +0100 Subject: [PATCH 18/23] Revise grammar: add BodyBasicNotTriples. Fixes --- shacl12-rules/shapes-rule-language.bnf | 413 ++++++++++++------------ shacl12-rules/shapes-rule-language.html | 247 +++++++------- 2 files changed, 334 insertions(+), 326 deletions(-) diff --git a/shacl12-rules/shapes-rule-language.bnf b/shacl12-rules/shapes-rule-language.bnf index f4ede1f6..009c3da9 100644 --- a/shacl12-rules/shapes-rule-language.bnf +++ b/shacl12-rules/shapes-rule-language.bnf @@ -1,209 +1,210 @@ -RuleSet ::= RuleOrDataBlock -RuleOrDataBlock ::= Prologue ( RuleOrData+ ( Prologue1 RuleOrData? )* )? -RuleOrData ::= Rule | Data -Prologue ::= Prologue1* -Prologue1 ::= BaseDecl | PrefixDecl | VersionDecl | ImportsDecl -BaseDecl ::= 'BASE' IRIREF -PrefixDecl ::= 'PREFIX' PNAME_NS IRIREF -VersionDecl ::= 'VERSION' VersionSpecifier -VersionSpecifier ::= STRING_LITERAL1 | STRING_LITERAL2 -ImportsDecl ::= 'IMPORTS' iri -Rule ::= Rule1 | Rule2 | Declaration -Rule1 ::= 'RULE' HeadTemplate 'WHERE' BodyPattern -Rule2 ::= 'IF' BodyPattern 'THEN' HeadTemplate -Declaration ::= ( 'TRANSITIVE' '(' iri ')' | 'SYMMETRIC' '(' iri ')' | 'INVERSE' '(' iri ',' iri ')' ) -Data ::= 'DATA' '{' TriplesDataBlock? '}' -TriplesDataBlock ::= TriplesSameSubject ( '.' TriplesDataBlock? )? -HeadTemplate ::= '{' HeadTemplateBlock? '}' -BodyPattern ::= '{' BodyTriplesBlock? ( BodyNotTriples BodyTriplesBlock? )* '}' -BodyNotTriples ::= Filter | Negation | Assignment -BodyTriplesBlock ::= TriplesBlock -Negation ::= 'NOT' '{' BodyBasic '}' -BodyBasic ::= BodyTriplesBlock? ( Filter BodyTriplesBlock? )* -HeadTemplateBlock ::= TriplesBlock -TriplesBlock ::= TriplesSameSubjectPath ( '.' TriplesBlock? )? -ReifiedTripleBlock ::= ReifiedTriple PropertyList -ReifiedTripleBlockPath ::= ReifiedTriple PropertyListPath -Assignment ::= 'SET' '(' Var ':=' Expression ')' -Reifier ::= '~' VarOrReifierId? -VarOrReifierId ::= Var | iri | BlankNode -Filter ::= 'FILTER' Constraint -Constraint ::= BrackettedExpression | BuiltInCall | FunctionCall -FunctionCall ::= iri ArgList -ArgList ::= NIL | '(' Expression ( ',' Expression )* ')' -ExpressionList ::= NIL | '(' Expression ( ',' Expression )* ')' -TriplesSameSubject ::= VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock -PropertyList ::= PropertyListNotEmpty? -PropertyListNotEmpty ::= Verb ObjectList ( ';' ( Verb ObjectList )? )* -Verb ::= VarOrIri | 'a' -ObjectList ::= Object ( ',' Object )* -Object ::= GraphNode Annotation -TriplesSameSubjectPath ::= VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath -PropertyListPath ::= PropertyListPathNotEmpty? -PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )* -VerbPath ::= Path -VerbSimple ::= Var -ObjectListPath ::= ObjectPath ( ',' ObjectPath )* -ObjectPath ::= GraphNodePath AnnotationPath -Path ::= PathSequence -PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )* -PathEltOrInverse ::= PathElt | '^' PathElt -PathElt ::= PathPrimary -PathPrimary ::= iri | 'a' | '(' Path ')' -TriplesNode ::= Collection | BlankNodePropertyList -BlankNodePropertyList ::= '[' PropertyListNotEmpty ']' -TriplesNodePath ::= CollectionPath | BlankNodePropertyListPath -BlankNodePropertyListPath ::= '[' PropertyListPathNotEmpty ']' -Collection ::= '(' GraphNode+ ')' -CollectionPath ::= '(' GraphNodePath+ ')' -AnnotationPath ::= ( Reifier | AnnotationBlockPath )* -AnnotationBlockPath ::= '{|' PropertyListPathNotEmpty '|}' -Annotation ::= ( Reifier | AnnotationBlock )* -AnnotationBlock ::= '{|' PropertyListNotEmpty '|}' -GraphNode ::= VarOrTerm | TriplesNode | ReifiedTriple -GraphNodePath ::= VarOrTerm | TriplesNodePath | ReifiedTriple -VarOrTerm ::= Var | RDFTerm -RDFTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm -ReifiedTriple ::= '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>' -ReifiedTripleSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple -ReifiedTripleObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm -TripleTerm ::= '<<(' TripleTermSubject Verb TripleTermObject ')>>' -TripleTermSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode -TripleTermObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm -TripleTermData ::= '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>' -TripleTermDataSubject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral -TripleTermDataObject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData -VarOrIri ::= Var | iri -Var ::= VAR1 | VAR2 -Expression ::= ConditionalOrExpression -ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )* -ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )* -ValueLogical ::= RelationalExpression -RelationalExpression ::= NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )? -NumericExpression ::= AdditiveExpression -AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )* -MultiplicativeExpression ::= UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )* -UnaryExpression ::= '!' PrimaryExpression - | '+' PrimaryExpression - | '-' PrimaryExpression - | PrimaryExpression -PrimaryExpression ::= BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm -ExprTripleTerm ::= '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>' -ExprTripleTermSubject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var -ExprTripleTermObject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm -BrackettedExpression ::= '(' Expression ')' -BuiltInCall ::= 'STR' '(' Expression ')' - | 'LANG' '(' Expression ')' - | 'LANGMATCHES' '(' Expression ',' Expression ')' - | 'LANGDIR' '(' Expression ')' - | 'DATATYPE' '(' Expression ')' - | 'IRI' '(' Expression ')' - | 'URI' '(' Expression ')' - | 'BNODE' ( '(' Expression ')' | NIL ) - | 'ABS' '(' Expression ')' - | 'CEIL' '(' Expression ')' - | 'FLOOR' '(' Expression ')' - | 'ROUND' '(' Expression ')' - | 'CONCAT' ExpressionList - | 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')' - | 'STRLEN' '(' Expression ')' - | 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')' - | 'UCASE' '(' Expression ')' - | 'LCASE' '(' Expression ')' - | 'ENCODE_FOR_URI' '(' Expression ')' - | 'CONTAINS' '(' Expression ',' Expression ')' - | 'STRSTARTS' '(' Expression ',' Expression ')' - | 'STRENDS' '(' Expression ',' Expression ')' - | 'STRBEFORE' '(' Expression ',' Expression ')' - | 'STRAFTER' '(' Expression ',' Expression ')' - | 'YEAR' '(' Expression ')' - | 'MONTH' '(' Expression ')' - | 'DAY' '(' Expression ')' - | 'HOURS' '(' Expression ')' - | 'MINUTES' '(' Expression ')' - | 'SECONDS' '(' Expression ')' - | 'TIMEZONE' '(' Expression ')' - | 'TZ' '(' Expression ')' - | 'NOW' NIL - | 'UUID' NIL - | 'STRUUID' NIL - | 'IF' '(' Expression ',' Expression ',' Expression ')' - | 'STRLANG' '(' Expression ',' Expression ')' - | 'STRLANGDIR' '(' Expression ',' Expression ',' Expression ')' - | 'STRDT' '(' Expression ',' Expression ')' - | 'sameTerm' '(' Expression ',' Expression ')' - | 'isIRI' '(' Expression ')' - | 'isURI' '(' Expression ')' - | 'isBLANK' '(' Expression ')' - | 'isLITERAL' '(' Expression ')' - | 'isNUMERIC' '(' Expression ')' - | 'hasLANG' '(' Expression ')' - | 'hasLANGDIR' '(' Expression ')' - | 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')' - | 'isTRIPLE' '(' Expression ')' - | 'TRIPLE' '(' Expression ',' Expression ',' Expression ')' - | 'SUBJECT' '(' Expression ')' - | 'PREDICATE' '(' Expression ')' - | 'OBJECT' '(' Expression ')' -iriOrFunction ::= iri ArgList? -RDFLiteral ::= String ( LANG_DIR | '^^' iri )? -NumericLiteral ::= NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative -NumericLiteralUnsigned ::= INTEGER | DECIMAL | DOUBLE -NumericLiteralPositive ::= INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE -NumericLiteralNegative ::= INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE -BooleanLiteral ::= 'true' | 'false' -String ::= STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 -iri ::= IRIREF | PrefixedName -PrefixedName ::= PNAME_LN | PNAME_NS -BlankNode ::= BLANK_NODE_LABEL | ANON +[1] RuleSet ::= RuleOrDataBlock +[2] RuleOrDataBlock ::= Prologue ( RuleOrData+ ( Prologue1 RuleOrData? )* )? +[3] RuleOrData ::= Rule | Data +[4] Prologue ::= Prologue1* +[5] Prologue1 ::= BaseDecl | PrefixDecl | VersionDecl | ImportsDecl +[6] BaseDecl ::= 'BASE' IRIREF +[7] PrefixDecl ::= 'PREFIX' PNAME_NS IRIREF +[8] VersionDecl ::= 'VERSION' VersionSpecifier +[9] VersionSpecifier ::= STRING_LITERAL1 | STRING_LITERAL2 +[10] ImportsDecl ::= 'IMPORTS' iri +[11] Rule ::= Rule1 | Rule2 | Declaration +[12] Rule1 ::= 'RULE' iri? HeadTemplate 'WHERE' BodyPattern +[13] Rule2 ::= 'IF' BodyPattern 'THEN' HeadTemplate +[14] Declaration ::= ( 'TRANSITIVE' '(' iri ')' | 'SYMMETRIC' '(' iri ')' | 'INVERSE' '(' iri ',' iri ')' ) +[15] Data ::= 'DATA' '{' TriplesDataBlock? '}' +[16] TriplesDataBlock ::= TriplesSameSubject ( '.' TriplesDataBlock? )? +[17] HeadTemplate ::= '{' HeadTemplateBlock? '}' +[18] BodyPattern ::= '{' BodyTriplesBlock? ( BodyNotTriples '.'? BodyTriplesBlock? )* '}' +[19] BodyNotTriples ::= Filter | Negation | Assignment +[20] BodyTriplesBlock ::= TriplesBlock +[21] Negation ::= 'NOT' '{' BodyBasic '}' +[22] BodyBasic ::= BodyTriplesBlock? ( BodyBasicNotTriples '.'? BodyTriplesBlock? )* +[23] BodyBasicNotTriples ::= Filter +[24] HeadTemplateBlock ::= TriplesBlock +[25] TriplesBlock ::= TriplesSameSubjectPath ( '.' TriplesBlock? )? +[26] ReifiedTripleBlock ::= ReifiedTriple PropertyList +[27] ReifiedTripleBlockPath ::= ReifiedTriple PropertyListPath +[28] Assignment ::= 'SET' '(' Var ':=' Expression ')' +[29] Reifier ::= '~' VarOrReifierId? +[30] VarOrReifierId ::= Var | iri | BlankNode +[31] Filter ::= 'FILTER' Constraint +[32] Constraint ::= BrackettedExpression | BuiltInCall | FunctionCall +[33] FunctionCall ::= iri ArgList +[34] ArgList ::= NIL | '(' Expression ( ',' Expression )* ')' +[35] ExpressionList ::= NIL | '(' Expression ( ',' Expression )* ')' +[36] TriplesSameSubject ::= VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock +[37] PropertyList ::= PropertyListNotEmpty? +[38] PropertyListNotEmpty ::= Verb ObjectList ( ';' ( Verb ObjectList )? )* +[39] Verb ::= VarOrIri | 'a' +[40] ObjectList ::= Object ( ',' Object )* +[41] Object ::= GraphNode Annotation +[42] TriplesSameSubjectPath ::= VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath +[43] PropertyListPath ::= PropertyListPathNotEmpty? +[44] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )* +[45] VerbPath ::= Path +[46] VerbSimple ::= Var +[47] ObjectListPath ::= ObjectPath ( ',' ObjectPath )* +[48] ObjectPath ::= GraphNodePath AnnotationPath +[49] Path ::= PathSequence +[50] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )* +[51] PathEltOrInverse ::= PathElt | '^' PathElt +[52] PathElt ::= PathPrimary +[53] PathPrimary ::= iri | 'a' | '(' Path ')' +[54] TriplesNode ::= Collection | BlankNodePropertyList +[55] BlankNodePropertyList ::= '[' PropertyListNotEmpty ']' +[56] TriplesNodePath ::= CollectionPath | BlankNodePropertyListPath +[57] BlankNodePropertyListPath ::= '[' PropertyListPathNotEmpty ']' +[58] Collection ::= '(' GraphNode+ ')' +[59] CollectionPath ::= '(' GraphNodePath+ ')' +[60] AnnotationPath ::= ( Reifier | AnnotationBlockPath )* +[61] AnnotationBlockPath ::= '{|' PropertyListPathNotEmpty '|}' +[62] Annotation ::= ( Reifier | AnnotationBlock )* +[63] AnnotationBlock ::= '{|' PropertyListNotEmpty '|}' +[64] GraphNode ::= VarOrTerm | TriplesNode | ReifiedTriple +[65] GraphNodePath ::= VarOrTerm | TriplesNodePath | ReifiedTriple +[66] VarOrTerm ::= Var | RDFTerm +[67] RDFTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm +[68] ReifiedTriple ::= '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>' +[69] ReifiedTripleSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm +[70] ReifiedTripleObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm +[71] TripleTerm ::= '<<(' TripleTermSubject Verb TripleTermObject ')>>' +[72] TripleTermSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm +[73] TripleTermObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm +[74] TripleTermData ::= '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>' +[75] TripleTermDataSubject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral +[76] TripleTermDataObject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData +[77] VarOrIri ::= Var | iri +[78] Var ::= VAR1 | VAR2 +[79] Expression ::= ConditionalOrExpression +[80] ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )* +[81] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )* +[82] ValueLogical ::= RelationalExpression +[83] RelationalExpression ::= NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )? +[84] NumericExpression ::= AdditiveExpression +[85] AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )* +[86] MultiplicativeExpression ::= UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )* +[87] UnaryExpression ::= '!' PrimaryExpression + | '+' PrimaryExpression + | '-' PrimaryExpression + | PrimaryExpression +[88] PrimaryExpression ::= BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm +[89] ExprTripleTerm ::= '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>' +[90] ExprTripleTermSubject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var +[91] ExprTripleTermObject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm +[92] BrackettedExpression ::= '(' Expression ')' +[93] BuiltInCall ::= 'STR' '(' Expression ')' + | 'LANG' '(' Expression ')' + | 'LANGMATCHES' '(' Expression ',' Expression ')' + | 'LANGDIR' '(' Expression ')' + | 'DATATYPE' '(' Expression ')' + | 'IRI' '(' Expression ')' + | 'URI' '(' Expression ')' + | 'BNODE' ( '(' Expression ')' | NIL ) + | 'ABS' '(' Expression ')' + | 'CEIL' '(' Expression ')' + | 'FLOOR' '(' Expression ')' + | 'ROUND' '(' Expression ')' + | 'CONCAT' ExpressionList + | 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')' + | 'STRLEN' '(' Expression ')' + | 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')' + | 'UCASE' '(' Expression ')' + | 'LCASE' '(' Expression ')' + | 'ENCODE_FOR_URI' '(' Expression ')' + | 'CONTAINS' '(' Expression ',' Expression ')' + | 'STRSTARTS' '(' Expression ',' Expression ')' + | 'STRENDS' '(' Expression ',' Expression ')' + | 'STRBEFORE' '(' Expression ',' Expression ')' + | 'STRAFTER' '(' Expression ',' Expression ')' + | 'YEAR' '(' Expression ')' + | 'MONTH' '(' Expression ')' + | 'DAY' '(' Expression ')' + | 'HOURS' '(' Expression ')' + | 'MINUTES' '(' Expression ')' + | 'SECONDS' '(' Expression ')' + | 'TIMEZONE' '(' Expression ')' + | 'TZ' '(' Expression ')' + | 'NOW' NIL + | 'UUID' NIL + | 'STRUUID' NIL + | 'IF' '(' Expression ',' Expression ',' Expression ')' + | 'STRLANG' '(' Expression ',' Expression ')' + | 'STRLANGDIR' '(' Expression ',' Expression ',' Expression ')' + | 'STRDT' '(' Expression ',' Expression ')' + | 'sameTerm' '(' Expression ',' Expression ')' + | 'isIRI' '(' Expression ')' + | 'isURI' '(' Expression ')' + | 'isBLANK' '(' Expression ')' + | 'isLITERAL' '(' Expression ')' + | 'isNUMERIC' '(' Expression ')' + | 'hasLANG' '(' Expression ')' + | 'hasLANGDIR' '(' Expression ')' + | 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')' + | 'isTRIPLE' '(' Expression ')' + | 'TRIPLE' '(' Expression ',' Expression ',' Expression ')' + | 'SUBJECT' '(' Expression ')' + | 'PREDICATE' '(' Expression ')' + | 'OBJECT' '(' Expression ')' +[94] iriOrFunction ::= iri ArgList? +[95] RDFLiteral ::= String ( LANG_DIR | '^^' iri )? +[96] NumericLiteral ::= NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative +[97] NumericLiteralUnsigned ::= INTEGER | DECIMAL | DOUBLE +[98] NumericLiteralPositive ::= INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE +[99] NumericLiteralNegative ::= INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE +[100] BooleanLiteral ::= 'true' | 'false' +[101] String ::= STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 +[102] iri ::= IRIREF | PrefixedName +[103] PrefixedName ::= PNAME_LN | PNAME_NS +[104] BlankNode ::= BLANK_NODE_LABEL | ANON @terminals -IRIREF ::= '<' ([^<>"{}|^`\]-[#x00-#x20] | )* '>' -PNAME_NS ::= PN_PREFIX? ':' -PNAME_LN ::= PNAME_NS PN_LOCAL -BLANK_NODE_LABEL ::= '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)? -VAR1 ::= '?' VARNAME -VAR2 ::= '$' VARNAME -LANG_DIR ::= '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)? -INTEGER ::= [0-9]+ -DECIMAL ::= [0-9]* '.' [0-9]+ -DOUBLE ::= ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+ -INTEGER_POSITIVE ::= '+' INTEGER -DECIMAL_POSITIVE ::= '+' DECIMAL -DOUBLE_POSITIVE ::= '+' DOUBLE -INTEGER_NEGATIVE ::= '-' INTEGER -DECIMAL_NEGATIVE ::= '-' DECIMAL -DOUBLE_NEGATIVE ::= '-' DOUBLE -STRING_LITERAL1 ::= "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'" -STRING_LITERAL2 ::= '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"' -STRING_LITERAL_LONG1 ::= "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''" -STRING_LITERAL_LONG2 ::= '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""' -ECHAR ::= '\' [tbnrf\"'] -UCHAR ::= ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX) -NIL ::= '(' WS* ')' -WS ::= #x20 | #x9 | #xD | #xA -ANON ::= '[' WS* ']' -PN_CHARS_BASE ::= [A-Z] - | [a-z] - | [#x00C0-#x00D6] - | [#x00D8-#x00F6] - | [#x00F8-#x02FF] - | [#x0370-#x037D] - | [#x037F-#x1FFF] - | [#x200C-#x200D] - | [#x2070-#x218F] - | [#x2C00-#x2FEF] - | [#x3001-#xD7FF] - | [#xF900-#xFDCF] - | [#xFDF0-#xFFFD] - | [#x10000-#xEFFFF] -PN_CHARS_U ::= PN_CHARS_BASE | '_' -VARNAME ::= ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )* -PN_CHARS ::= PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] -PN_PREFIX ::= PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)? -PN_LOCAL ::= (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )? -PLX ::= PERCENT | PN_LOCAL_ESC -PERCENT ::= '%' HEX HEX -HEX ::= [0-9] | [A-F] | [a-f] -PN_LOCAL_ESC ::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' ) +[105] IRIREF ::= '<' ([^<>"{}|^`\]-[#x00-#x20] | UCHAR )* '>' +[106] PNAME_NS ::= PN_PREFIX? ':' +[107] PNAME_LN ::= PNAME_NS PN_LOCAL +[108] BLANK_NODE_LABEL ::= '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)? +[109] VAR1 ::= '?' VARNAME +[110] VAR2 ::= '$' VARNAME +[111] LANG_DIR ::= '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)? +[112] INTEGER ::= [0-9]+ +[113] DECIMAL ::= [0-9]* '.' [0-9]+ +[114] DOUBLE ::= ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+ +[115] INTEGER_POSITIVE ::= '+' INTEGER +[116] DECIMAL_POSITIVE ::= '+' DECIMAL +[117] DOUBLE_POSITIVE ::= '+' DOUBLE +[118] INTEGER_NEGATIVE ::= '-' INTEGER +[119] DECIMAL_NEGATIVE ::= '-' DECIMAL +[120] DOUBLE_NEGATIVE ::= '-' DOUBLE +[121] STRING_LITERAL1 ::= "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'" +[122] STRING_LITERAL2 ::= '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"' +[123] STRING_LITERAL_LONG1 ::= "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''" +[124] STRING_LITERAL_LONG2 ::= '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""' +[125] ECHAR ::= '\' [tbnrf\"'] +[126] UCHAR ::= ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX) +[127] NIL ::= '(' WS* ')' +[128] WS ::= #x20 | #x9 | #xD | #xA +[129] ANON ::= '[' WS* ']' +[130] PN_CHARS_BASE ::= [A-Z] + | [a-z] + | [#x00C0-#x00D6] + | [#x00D8-#x00F6] + | [#x00F8-#x02FF] + | [#x0370-#x037D] + | [#x037F-#x1FFF] + | [#x200C-#x200D] + | [#x2070-#x218F] + | [#x2C00-#x2FEF] + | [#x3001-#xD7FF] + | [#xF900-#xFDCF] + | [#xFDF0-#xFFFD] + | [#x10000-#xEFFFF] +[131] PN_CHARS_U ::= PN_CHARS_BASE | '_' +[132] VARNAME ::= ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )* +[133] PN_CHARS ::= PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] +[134] PN_PREFIX ::= PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)? +[135] PN_LOCAL ::= (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )? +[136] PLX ::= PERCENT | PN_LOCAL_ESC +[137] PERCENT ::= '%' HEX HEX +[138] HEX ::= [0-9] | [A-F] | [a-f] +[139] PN_LOCAL_ESC ::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' ) diff --git a/shacl12-rules/shapes-rule-language.html b/shacl12-rules/shapes-rule-language.html index 5ab37c65..2dc15441 100644 --- a/shacl12-rules/shapes-rule-language.html +++ b/shacl12-rules/shapes-rule-language.html @@ -83,7 +83,7 @@ [12]   Rule1   ::=   - 'RULE' HeadTemplate 'WHERE' BodyPattern + 'RULE' iri? HeadTemplate 'WHERE' BodyPattern @@ -125,7 +125,7 @@ [18]   BodyPattern   ::=   - '{' BodyTriplesBlock? ( BodyNotTriples BodyTriplesBlock? )* '}' + '{' BodyTriplesBlock? ( BodyNotTriples '.'? BodyTriplesBlock? )* '}' @@ -153,571 +153,578 @@ [22]   BodyBasic   ::=   - BodyTriplesBlock? ( Filter BodyTriplesBlock? )* + BodyTriplesBlock? ( BodyBasicNotTriples '.'? BodyTriplesBlock? )* [23]   + BodyBasicNotTriples +   ::=   + Filter + + + + [24]   HeadTemplateBlock   ::=   TriplesBlock - [24]   + [25]   TriplesBlock   ::=   TriplesSameSubjectPath ( '.' TriplesBlock? )? - [25]   + [26]   ReifiedTripleBlock   ::=   ReifiedTriple PropertyList - [26]   + [27]   ReifiedTripleBlockPath   ::=   ReifiedTriple PropertyListPath - [27]   + [28]   Assignment   ::=   'SET' '(' Var ':=' Expression ')' - [28]   + [29]   Reifier   ::=   '~' VarOrReifierId? - [29]   + [30]   VarOrReifierId   ::=   Var | iri | BlankNode - [30]   + [31]   Filter   ::=   'FILTER' Constraint - [31]   + [32]   Constraint   ::=   BrackettedExpression | BuiltInCall | FunctionCall - [32]   + [33]   FunctionCall   ::=   iri ArgList - [33]   + [34]   ArgList   ::=   NIL | '(' Expression ( ',' Expression )* ')' - [34]   + [35]   ExpressionList   ::=   NIL | '(' Expression ( ',' Expression )* ')' - [35]   + [36]   TriplesSameSubject   ::=   VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock - [36]   + [37]   PropertyList   ::=   PropertyListNotEmpty? - [37]   + [38]   PropertyListNotEmpty   ::=   Verb ObjectList ( ';' ( Verb ObjectList )? )* - [38]   + [39]   Verb   ::=   VarOrIri | 'a' - [39]   + [40]   ObjectList   ::=   Object ( ',' Object )* - [40]   + [41]   Object   ::=   GraphNode Annotation - [41]   + [42]   TriplesSameSubjectPath   ::=   VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath - [42]   + [43]   PropertyListPath   ::=   PropertyListPathNotEmpty? - [43]   + [44]   PropertyListPathNotEmpty   ::=   ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )* - [44]   + [45]   VerbPath   ::=   Path - [45]   + [46]   VerbSimple   ::=   Var - [46]   + [47]   ObjectListPath   ::=   ObjectPath ( ',' ObjectPath )* - [47]   + [48]   ObjectPath   ::=   GraphNodePath AnnotationPath - [48]   + [49]   Path   ::=   PathSequence - [49]   + [50]   PathSequence   ::=   PathEltOrInverse ( '/' PathEltOrInverse )* - [50]   + [51]   PathEltOrInverse   ::=   PathElt | '^' PathElt - [51]   + [52]   PathElt   ::=   PathPrimary - [52]   + [53]   PathPrimary   ::=   iri | 'a' | '(' Path ')' - [53]   + [54]   TriplesNode   ::=   Collection | BlankNodePropertyList - [54]   + [55]   BlankNodePropertyList   ::=   '[' PropertyListNotEmpty ']' - [55]   + [56]   TriplesNodePath   ::=   CollectionPath | BlankNodePropertyListPath - [56]   + [57]   BlankNodePropertyListPath   ::=   '[' PropertyListPathNotEmpty ']' - [57]   + [58]   Collection   ::=   '(' GraphNode+ ')' - [58]   + [59]   CollectionPath   ::=   '(' GraphNodePath+ ')' - [59]   + [60]   AnnotationPath   ::=   ( Reifier | AnnotationBlockPath )* - [60]   + [61]   AnnotationBlockPath   ::=   '{|' PropertyListPathNotEmpty '|}' - [61]   + [62]   Annotation   ::=   ( Reifier | AnnotationBlock )* - [62]   + [63]   AnnotationBlock   ::=   '{|' PropertyListNotEmpty '|}' - [63]   + [64]   GraphNode   ::=   VarOrTerm | TriplesNode | ReifiedTriple - [64]   + [65]   GraphNodePath   ::=   VarOrTerm | TriplesNodePath | ReifiedTriple - [65]   + [66]   VarOrTerm   ::=   Var | RDFTerm - [66]   + [67]   RDFTerm   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm - [67]   + [68]   ReifiedTriple   ::=   '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>' - [68]   + [69]   ReifiedTripleSubject   ::=   - Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple + Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm - [69]   + [70]   ReifiedTripleObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm - [70]   + [71]   TripleTerm   ::=   '<<(' TripleTermSubject Verb TripleTermObject ')>>' - [71]   + [72]   TripleTermSubject   ::=   - Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode + Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm - [72]   + [73]   TripleTermObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm - [73]   + [74]   TripleTermData   ::=   '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>' - [74]   + [75]   TripleTermDataSubject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral - [75]   + [76]   TripleTermDataObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData - [76]   + [77]   VarOrIri   ::=   Var | iri - [77]   + [78]   Var   ::=   VAR1 | VAR2 - [78]   + [79]   Expression   ::=   ConditionalOrExpression - [79]   + [80]   ConditionalOrExpression   ::=   ConditionalAndExpression ( '||' ConditionalAndExpression )* - [80]   + [81]   ConditionalAndExpression   ::=   ValueLogical ( '&&' ValueLogical )* - [81]   + [82]   ValueLogical   ::=   RelationalExpression - [82]   + [83]   RelationalExpression   ::=   NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )? - [83]   + [84]   NumericExpression   ::=   AdditiveExpression - [84]   + [85]   AdditiveExpression   ::=   MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )* - [85]   + [86]   MultiplicativeExpression   ::=   UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )* - [86]   + [87]   UnaryExpression   ::=     '!' PrimaryExpression
    | '+' PrimaryExpression
    | '-' PrimaryExpression
    | PrimaryExpression
    - [87]   + [88]   PrimaryExpression   ::=   BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm - [88]   + [89]   ExprTripleTerm   ::=   '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>' - [89]   + [90]   ExprTripleTermSubject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var - [90]   + [91]   ExprTripleTermObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm - [91]   + [92]   BrackettedExpression   ::=   '(' Expression ')' - [92]   + [93]   BuiltInCall   ::=     'STR' '(' Expression ')'
    | 'LANG' '(' Expression ')'
    | 'LANGMATCHES' '(' Expression ',' Expression ')'
    | 'LANGDIR' '(' Expression ')'
    | 'DATATYPE' '(' Expression ')'
    | 'IRI' '(' Expression ')'
    | 'URI' '(' Expression ')'
    | 'BNODE' ( '(' Expression ')' | NIL )
    | 'ABS' '(' Expression ')'
    | 'CEIL' '(' Expression ')'
    | 'FLOOR' '(' Expression ')'
    | 'ROUND' '(' Expression ')'
    | 'CONCAT' ExpressionList
    | 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
    | 'STRLEN' '(' Expression ')'
    | 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
    | 'UCASE' '(' Expression ')'
    | 'LCASE' '(' Expression ')'
    | 'ENCODE_FOR_URI' '(' Expression ')'
    | 'CONTAINS' '(' Expression ',' Expression ')'
    | 'STRSTARTS' '(' Expression ',' Expression ')'
    | 'STRENDS' '(' Expression ',' Expression ')'
    | 'STRBEFORE' '(' Expression ',' Expression ')'
    | 'STRAFTER' '(' Expression ',' Expression ')'
    | 'YEAR' '(' Expression ')'
    | 'MONTH' '(' Expression ')'
    | 'DAY' '(' Expression ')'
    | 'HOURS' '(' Expression ')'
    | 'MINUTES' '(' Expression ')'
    | 'SECONDS' '(' Expression ')'
    | 'TIMEZONE' '(' Expression ')'
    | 'TZ' '(' Expression ')'
    | 'NOW' NIL
    | 'UUID' NIL
    | 'STRUUID' NIL
    | 'IF' '(' Expression ',' Expression ',' Expression ')'
    | 'STRLANG' '(' Expression ',' Expression ')'
    | 'STRLANGDIR' '(' Expression ',' Expression ',' Expression ')'
    | 'STRDT' '(' Expression ',' Expression ')'
    | 'sameTerm' '(' Expression ',' Expression ')'
    | 'isIRI' '(' Expression ')'
    | 'isURI' '(' Expression ')'
    | 'isBLANK' '(' Expression ')'
    | 'isLITERAL' '(' Expression ')'
    | 'isNUMERIC' '(' Expression ')'
    | 'hasLANG' '(' Expression ')'
    | 'hasLANGDIR' '(' Expression ')'
    | 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
    | 'isTRIPLE' '(' Expression ')'
    | 'TRIPLE' '(' Expression ',' Expression ',' Expression ')'
    | 'SUBJECT' '(' Expression ')'
    | 'PREDICATE' '(' Expression ')'
    | 'OBJECT' '(' Expression ')'
    - [93]   + [94]   iriOrFunction   ::=   iri ArgList? - [94]   + [95]   RDFLiteral   ::=   String ( LANG_DIR | '^^' iri )? - [95]   + [96]   NumericLiteral   ::=   NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative - [96]   + [97]   NumericLiteralUnsigned   ::=   INTEGER | DECIMAL | DOUBLE - [97]   + [98]   NumericLiteralPositive   ::=   INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE - [98]   + [99]   NumericLiteralNegative   ::=   INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE - [99]   + [100]   BooleanLiteral   ::=   'true' | 'false' - [100]   + [101]   String   ::=   STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 - [101]   + [102]   iri   ::=   IRIREF | PrefixedName - [102]   + [103]   PrefixedName   ::=   PNAME_LN | PNAME_NS - [103]   + [104]   BlankNode   ::=   BLANK_NODE_LABEL | ANON @@ -729,245 +736,245 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 2e7e5d6ba76f28e185d7c641ed3527aa02f34b3f Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Tue, 30 Jun 2026 09:15:04 +0100 Subject: [PATCH 19/23] CHANGES (Rules) --- shacl12-rules/CHANGES.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 shacl12-rules/CHANGES.md diff --git a/shacl12-rules/CHANGES.md b/shacl12-rules/CHANGES.md new file mode 100644 index 00000000..abfe8b3b --- /dev/null +++ b/shacl12-rules/CHANGES.md @@ -0,0 +1,12 @@ +# SHACL 1.2. Rules -- CHANGES + +This document records major changes and new material that would be of inter2st to +implementers. + +It is not a comprehensive list of changes to the specification. + +This file is temporary while the specification is in-development - it is not +intended for publication. + + +## 2026-07-01 Start From 62fe63fbe7cccefb0238f753840f6c875c6a7a26 Mon Sep 17 00:00:00 2001 From: Andy Seaborne Date: Wed, 1 Jul 2026 17:41:07 +0100 Subject: [PATCH 20/23] Updates from review shacl12-rules/index.html Co-authored-by: simon --- shacl12-rules/index.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/shacl12-rules/index.html b/shacl12-rules/index.html index 3e961fc2..0b8a9128 100644 --- a/shacl12-rules/index.html +++ b/shacl12-rules/index.html @@ -275,7 +275,7 @@

    Document Conventions

    bindings given above.

    - Reset. Use reSpec default appearance where appropiate. + Reset. Use reSpec default appearance where appropriate.

            # This box represents rules
    @@ -529,7 +529,7 @@

    Negation

    from inferred triples inferred by other rules.

    -
    [104]  [105]   IRIREF   ::=   '<' ([^<>"{}|^`\]-[#x00-#x20] | UCHAR )* '>'
    [105]  [106]   PNAME_NS   ::=   PN_PREFIX? ':'
    [106]  [107]   PNAME_LN   ::=   PNAME_NS PN_LOCAL
    [107]  [108]   BLANK_NODE_LABEL   ::=   '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
    [108]  [109]   VAR1   ::=   '?' VARNAME
    [109]  [110]   VAR2   ::=   '$' VARNAME
    [110]  [111]   LANG_DIR   ::=   '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)?
    [111]  [112]   INTEGER   ::=   [0-9]+
    [112]  [113]   DECIMAL   ::=   [0-9]* '.' [0-9]+
    [113]  [114]   DOUBLE   ::=   ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+
    [114]  [115]   INTEGER_POSITIVE   ::=   '+' INTEGER
    [115]  [116]   DECIMAL_POSITIVE   ::=   '+' DECIMAL
    [116]  [117]   DOUBLE_POSITIVE   ::=   '+' DOUBLE
    [117]  [118]   INTEGER_NEGATIVE   ::=   '-' INTEGER
    [118]  [119]   DECIMAL_NEGATIVE   ::=   '-' DECIMAL
    [119]  [120]   DOUBLE_NEGATIVE   ::=   '-' DOUBLE
    [120]  [121]   STRING_LITERAL1   ::=   "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
    [121]  [122]   STRING_LITERAL2   ::=   '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
    [122]  [123]   STRING_LITERAL_LONG1   ::=   "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
    [123]  [124]   STRING_LITERAL_LONG2   ::=   '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
    [124]  [125]   ECHAR   ::=   '\' [tbnrf\"']
    [125]  [126]   UCHAR   ::=   ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
    [126]  [127]   NIL   ::=   '(' WS* ')'
    [127]  [128]   WS   ::=   #x20 | #x9 | #xD | #xA
    [128]  [129]   ANON   ::=   '[' WS* ']'
    [129]  [130]   PN_CHARS_BASE   ::=   [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
    [130]  [131]   PN_CHARS_U   ::=   PN_CHARS_BASE | '_'
    [131]  [132]   VARNAME   ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
    [132]  [133]   PN_CHARS   ::=   PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
    [133]  [134]   PN_PREFIX   ::=   PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
    [134]  [135]   PN_LOCAL   ::=   (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
    [135]  [136]   PLX   ::=   PERCENT | PN_LOCAL_ESC
    [136]  [137]   PERCENT   ::=   '%' HEX HEX
    [137]  [138]   HEX   ::=   [0-9] | [A-F] | [a-f]
    [138]  [139]   PN_LOCAL_ESC   ::=   '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )