Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 74 additions & 69 deletions shacl12-rules/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,16 @@
}

.algorithm {
/*
/* <pre> written as CSS
font-family: monospace;
font-size: 16px
white-space: pre;
*/
color: #444;
}
</style>


</head>

<body>
<section id="abstract">
<p>This document describes Shapes Constraint Language (SHACL) Rules.</p>
Expand Down Expand Up @@ -806,19 +805,16 @@ <h4>Evaluation of an Expression</h4>
<p class=ednote>Sketch</p>

<pre class="algorithm">

Let F(arg1, arg2, ...) be an expression.
where arg1, arg2 are RDF terms.
@@

Let [x/<var>μ</var>] be
if x is an RDF term, then [x/row] is x
if x is a variable, then [x/row] is <var>μ</var>(x)
## By well-formedness, it is an error if x is not in the row.

eval(F(expr1, expr2 ...), row) = F(eval(expr1, row), eval(expr2, row), ...)
...
eval(FF(expr1, expr2) , row) = ... things that are not functions like `IF`
@@ Reference SPARQL expression evaluation <a data-cite="SPARQL12-QUERY/#expression-evaluation">EXPR</a>
@@ Reference SPARQL EBV <a data-cite="SPARQL12-QUERY/#expression-evaluation">EXPR</a>

define evalFunction(F, <var>μ</var>):
Let [x/<var>μ</var>] be
if x is an RDF term, then [x/row] is x
if x is a variable, then [x/row] is <var>μ</var>(x)
## By well-formedness, it is an error if x is not in the row.
eval(F(expr1, expr2 ...), row) = F(eval(expr1, row), eval(expr2, row), ...)
eval(FF(expr1, expr2) , row) = ... things that are not functions like `IF`
</pre>
</section>

Expand All @@ -833,66 +829,76 @@ <h4>Evaluation of a Rule</h4>

<pre class="algorithm">
let R be a well-formed rule.

let rule R = (H, B) where
H is the sequence of triple templates in the head
B is the sequence of triple patterns, condition expressions,
B is the sequence of triple patterns,
condition expressions, negation elements,
and assignments in the body

let R : map variable to RDF term as a set of pairs (variable, RDF term)
# Solution sequence of one solution that does not map any variables.
let SEQ0: Solution sequence = { <var>μ</var><sub>0</sub> }

## Solution sequence of one solution that does not map any variables.
## (This is the join identity)

let SEQ: Solution sequence = { <var>μ</var><sub>0</sub> }
let G = <a>evaluation graph</a>

# Start::

Replace each blank node in B with a fresh
variable that does not occur in the rule body.

# Evaluate rule body

for each rule element rElt in B
if rElt is a triple pattern TP:
X = graphMatch(G, TP)
SEQ1 = {}
for each <var>μ</var><sub>1</sub> in X:
for each <var>μ</var><sub>2</sub> in SEQ:
if compatible(<var>μ</var><sub>1</sub>, <var>μ</var><sub>2</sub>)
<var>μ</var><sub>3</sub> = merge(<var>μ</var>1, <var>μ</var><sub>2</sub>)
add <var>μ</var><sub>3</sub> to SEQ1
endfor
endif

if rElt is a condition expression F:
SEQ1 = {}
for each solution <var>μ</var> in SEQ:
## EBV = Effective boolean value.
## TODO: Eval errors.
if ( EBV(eval(<var>μ</var>, F)) is true )
add <var>μ</var> to SEQ1
endif
endfor
endif

if rElt is an assignment(V, expr)
SEQ1 = {}
for each solution S in SEQ:
let x = eval(expr, S)
add(V, x) to S
add S to SEQ1
endfor
endif

if SEQ1 is empty
SEQ = {}
exit
endif

SEQ = SEQ1

endfor
# This function returns a sequence of solutions
define evalRuleElements(B, SEQ, G):

for each rule element rElt in B:

if rElt is a triple pattern TP:
X = graphMatch(G, TP)
SEQ1 = {}
for each <var>μ</var><sub>1</sub> in X:
for each <var>μ</var><sub>2</sub> in SEQ:
if compatible(<var>μ</var><sub>1</sub>, <var>μ</var><sub>2</sub>)
<var>μ</var><sub>3</sub> = merge(<var>μ</var>1, <var>μ</var><sub>2</sub>)
add <var>μ</var><sub>3</sub> to SEQ1
endfor
endif

if rElt is a condition expression with expression F:
SEQ1 = {}
for each solution <var>μ</var> in SEQ:
if evalFunction(F, <var>μ</var>) is <var>true<var>:
add <var>μ</var> to SEQ1
endif
endfor
endif

if rElt is a negation expression with body elements N:
SEQ1 = {}
for each solution <var>μ</var> in SEQ:
S = sequence{ <var>μ</var> }
NEG = evalRuleElements(N, S, G)
if NEG is empty
add <var>μ</var> to SEQ1
endif
endfor
endif

if rElt is an assignment with variable V and expression expr
SEQ1 = {}
for each solution S in SEQ:
let x = eval(expr, S)
add(V, x) to S
add S to SEQ1
endfor
endif

if SEQ1 is empty
SEQ = {}
return SEQ
endif

SEQ = SEQ1
endfor

return SEQ
enddefine

let SEQ = evalRuleElements(B, SEQ0, G)

# Evaluate rule head
let H = empty set
Expand All @@ -905,7 +911,6 @@ <h4>Evaluation of a Rule</h4>
endfor

result eval(R, G) is H

</pre>
<p>Note that `H` may contain triples that are also in the data graph.</p>
</section>
Expand Down