SHACL rules infer new triples. The input is a data graph and a shape graph with rules, the output is a graph of inferred triples that do not occur in the data graph.
Whether, and how, the output graph is added back into the data graph is a separate decision.
@@Datalog-ish then a collection of "run once rules easy for defaulting"
?? Separate namespace sr:
/ http:///www.w3.org/ns/shacl-rules/
- overcrowding in
sh:
e.g.subject
(AF use? node expression function?) - now and in the future. - rules as distinct feature
This is a spec.
RFC 2119 keywords.
Data not (a-box, not t-box)
One rule language. Simple to complex implementations.
?? "Compile" to SPARQL for scale.
(Short rules tutorial)
FACT A :fatherOf X .
FACT B :motherOf X .
FACT C :motherOf A .
RULE { ?x :childOf ?y } WHERE { ?y :fatherOf ??x }
RULE { ?x :childOf ?y } WHERE { ?y :motherOf ??x }
RULE { ?x :descendedFrom ?y } WHERE { ?x :childOf ?z . ?z :childOf ?y }
Materialization
Query answering ("query" in datalog-speak is one triple pattern)
@@RAS -- SHACL Rules Abstract Syntax
Named variables.
- All variables are "named"
- the name only applies within a single rule
RDF terms - including triple terms
"concrete triples" - no variables. (RDF-concepts uses "ground" for no "blank nodes")
Expressions are functions that evaluate to an RDF term.
URI(arg, arg,..)
where "arg" is a named variable or an RDF term.
Compact syntax has operators and keywords for many functions - this is convenience.
One special expression is the triple term expression.
Triple template
A triple template is 3-tuple where each element is either a variable, an RDF term, or a triple term template.
A triple term template is an RDF triple term which also allows variables for subject/predicate/object.
Triple templates appear in the [=head=] of a [=rule=].
Position 1 is called the 'subject'.
Position 2 is called the 'predicate'.
Position 3 is called the 'object'.
Triple pattern
A triple pattern is 3-tuple where each element is either a variable, or an RDF term, or a triple term pattern.
A triple term pattern is an RDF term genralized to allow variables for subject/predicate/object.
Position 1 is called the 'subject'.
Position 2 is called the 'predicate'.
Position 3 is called the 'object'.
Condition Expression
An condition expression is a function, or functional form, that evaluates to true or false (or EBV?)
(A node expression is concrete, a rule expression is abstract)
Usually, a condition expression is a node expression[=ref=] that evaluates to an RDF term.
Assignment
An assignment is pair of
(assignment variable, assignment expression)
.
where
- assignment variableis a namaed variable.
- assignment expression is an expression
Rule
A rule is a pair:
- a rule head (often just 'head')
- a rule body (often just 'body')
Rule head
A rule head is a sequence of triple templates
Rule body
A rule body is a sequence of body elements where a body element is one of:
- a triple pattern
- an condition expression
- an assignment
RuleSet
A ruleset of a collection of rules. (sequence? bag?)
A rule is "well-formed" if:
-
For every variable in the sequence of triple templates for the head, there is an one or more occurences of a variable of the same name in the triple patterns in the body, or there is a single occurence as an assignment variable in the body.
-
For every variable in an expression at position i, there is a corresponding variable of the same name occuring in a triple pattern, or occuring as an assigned variable, at a position, j where j < i.
-
The assignment variable at position i does not occurs on any triple pattern at position j where j < i.
-
For every variable in an assignment expression, there is a corresponding variable in a triple pattern or is an assigned variable at position j where j < i.
Terminology
- variables are matched/defined by triple pattern matching or by assignment.
- variables in condition expressions or assignment expressions are used, not set.
Notes:
- "well-formedness" is a set of conditions on a rule parse tree (RPT) (i.e. after parsing)
- Fro well-frmed rules, instantiating head triple templates results in valid RDF triples (no variables)
@@ define well-defined body @@ define the set of variables defined by a rule body.
A ruleset is "well-formed" if and onyl if all its rules are "well-formed".
- this spec does not define the outcome of evaluating a ruleset with ill-formed rules.
Non-normative Discussion.
There are two concrete syntaxes defined by this specification. Each syntax produces Rule Abstract Syntax. Parsing either form produces a SHACL Rules Parse Tree (@@RPT), which an abstract syntax tree [=AST=] of the Rule Abstract Syntax (@@RAS).
- RDF Syntax
- Compact Syntax
The compact syntax has an equivalent RDF syntax form.
Well-formed RDF syntax can be translated to the compact syntax.
Illustration (click to expand)
Compact:
PREFIX : <http://example/>
DATA { :x :p 1 ; :q 2 . }
RULE { ?x :bothPositive true . } WHERE { ?x :p ?v1 FILTER ( ?v1 > 0 ) ?x :q ?v2 FILTER ( ?v2 > 0 ) }
RULE { ?x :oneIsZero true . } WHERE { ?x :p ?v1 ; :q ?v2 FILTER ( ( ?v1 = 0 ) || ( ?v2 = 0 ) ) }
RDF:
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX sparql: <http://www.w3.org/ns/sparql#>
:ruleSet-1
rdf:type sh:RuleSet;
sh:data (
<<( :x :p 1 )>>
<<( :x :q 2 )>>
);
sh:ruleSet (
[
rdf:type sh:Rule;
sh:body (
[
sh:object [ sh:var "v1" ];
sh:predicate :p;
sh:subject [ sh:var "x" ]
]
[
sh:expr [
sparql:greaterThan (
[ sh:var "v1" ]
0
)
]
]
[
sh:object [ sh:var "v2" ];
sh:predicate :q;
sh:subject [ sh:var "x" ]
]
[
sh:expr [
sparql:greaterThan (
[ sh:var "v2" ]
0
)
]
]
);
sh:head (
[
sh:object true;
sh:predicate :bothPositive;
sh:subject [ sh:var "x" ]
]
)
]
[
rdf:type sh:Rule;
sh:body (
[
sh:object [ sh:var "v1" ];
sh:predicate :p;
sh:subject [ sh:var "x" ]
]
[
sh:object [ sh:var "v2" ];
sh:predicate :q;
sh:subject [ sh:var "x" ]
]
[
sh:expr [
sparql:function-or (
[
sparql:equals (
[ sh:var "v1" ]
0
)
]
[
sparql:equals (
[ sh:var "v2" ]
0
)
]
)
]
]
);
sh:head (
[
sh:object true;
sh:predicate :oneIsZero;
sh:subject [ sh:var "x" ]
]
)
]
) .
RRS
RDF Rule Syntax : very close to RAS.
RDF Rule Syntax is well-formed if it generates RAS.
shacl-rules.ttl
CRS
(work-in-progress)
- node expressions written in RDF form.
DATA
block - these are datalog "facts" - a rule with a head and no body.
"Imports" is inclusion of the RPT - hence an import can be in RRS or CRS.
Imports are complete rules. Rules can not be split across imports.
@@Define parsing
This section defines the outcome of evaluating a rule set on given data. It does not prescribe the algorithm as the method of implementation. An implementation can use any algorithm that generates the same outcome.
Well-formed rule set.
evaluation(G,RS):
Produces a graph of inferred triples. The inferred triples does not include any triple present in the set of triples of G.
Let R be a well-formed rule.
Expressions valuation
Let F(arg1, arg2, ...) be an expression.
where arg1 is an RDF term.
Let [x/row] be
if x is an RDF term, the [x/row] is x
if x is a variable then [x/row] is the value of x in the row
## By well-formedness, it is an error if x is not in the row.
Triple terms.
eval(F(expr1, expr2), row) = ...
eval(FF(expr1, expr2) , row) = ...
For rule R = (head,body) = (H:list of triple templates, list of triple patter/expressions/assignments)
eval(R, G) is the set of triples that are not found in G that are generated by rule R.
evalBody = list of set of (var, RDF term) pairs
evalBody =
let R : map variable to RDF term as a set of pairs (variable, RDF term)
# "solution"
let T :list of B
Initial T = empty list
for each rule element rElt:
if rElt is a triple pattern:
T1 = empty list
for each row in T:
T1 = empty list
for each matches m set of (var,term)
row1 = row union (var, term)
add row1 to T1
endfor
T = T1
endif
if rElt is a condition expression F:
T1 = empty list
for each row in T:
if ( eval(F,B) )
add R to T1
endif
endfor
T = T1
if rElt is an assignment(V,Expr)
T1 = empty list
for each row in T:
let x = eval(expr, row)
let R1 = R union (V, x)
add R1 to T!
T = T1
endfor
endif
Let H = empty set
for each R in T:
Let S = set of triples obtained by replacing variables in teh triple templates of the head with values from R
define [head(R)/row]
H = H union S
endfor
result is H
## At this point, may include triples in the base graph.
Let G be the input RDF graph.
Let I be the set of triples generated by evaluation
Let RS be a rule set
Let finished = false
while !finished:
finished = true
foreach rule in RS
let GI = G union I
let X = eval(rule, GI)
let Y = those triples in X that are not in GI
if Y is not empty:
finished = false
let I = Y union I
endfor
endwhile
result is GI
Relationship to node expressions. (surely there is much less need for rules-on-shapes if node expressions are available)
ex:RectangleRulesShape
a sh:NodeShape ;
sh:targetClass ex:Rectangle ;
sh:rule [...]
is an extra condition { $this rdf:type ex:Rectangle }
for the bidy of the rule.
DATA
-- addition DRF triples. Axioms.
Certain forms that can be written as rules and are amenable to special implementation.
TRANSITIVE
-- declare a property as being transitive - allows for special implmentation
SYMMETRIC
-- declare a property as being symmetric. RDFS-Plus
INVERSE(p1, p2)
-- declare a property p1 as the inverse of p2.
Can go into infinite loops. (is there a static synatx test for this? No - but theer is for possible infinite loops by assignment-body-head analysis)
"Negation" is the property that a rule depends on the absnesce of triples in the data graph.
Possible:
application/rdf-rules
application/rdf-rules+turtle
application/rdf-rules+shacl-compact-syntax