110110 }
111111
112112 .algorithm {
113- /*
113+ /* <pre> written as CSS
114114 font-family: monospace;
115- font-size: 16px
116115 white-space: pre;
117116 */
118117 color : # 444 ;
119118 }
120119 </ style >
121-
122120
123121 </ head >
122+
124123 < body >
125124 < section id ="abstract ">
126125 < p > This document describes Shapes Constraint Language (SHACL) Rules.</ p >
@@ -806,19 +805,16 @@ <h4>Evaluation of an Expression</h4>
806805 < p class =ednote > Sketch</ p >
807806
808807< pre class ="algorithm ">
809-
810- Let F(arg1, arg2, ...) be an expression.
811- where arg1, arg2 are RDF terms.
812- @@
813-
814- Let [x/< var > μ</ var > ] be
815- if x is an RDF term, then [x/row] is x
816- if x is a variable, then [x/row] is < var > μ</ var > (x)
817- ## By well-formedness, it is an error if x is not in the row.
818-
819- eval(F(expr1, expr2 ...), row) = F(eval(expr1, row), eval(expr2, row), ...)
820- ...
821- eval(FF(expr1, expr2) , row) = ... things that are not functions like `IF`
808+ @@ Reference SPARQL expression evaluation < a data-cite ="SPARQL12-QUERY/#expression-evaluation "> EXPR</ a >
809+ @@ Reference SPARQL EBV < a data-cite ="SPARQL12-QUERY/#expression-evaluation "> EXPR</ a >
810+
811+ define evalFunction(F, < var > μ</ var > ):
812+ Let [x/< var > μ</ var > ] be
813+ if x is an RDF term, then [x/row] is x
814+ if x is a variable, then [x/row] is < var > μ</ var > (x)
815+ ## By well-formedness, it is an error if x is not in the row.
816+ eval(F(expr1, expr2 ...), row) = F(eval(expr1, row), eval(expr2, row), ...)
817+ eval(FF(expr1, expr2) , row) = ... things that are not functions like `IF`
822818</ pre >
823819 </ section >
824820
@@ -833,66 +829,76 @@ <h4>Evaluation of a Rule</h4>
833829
834830< pre class ="algorithm ">
835831let R be a well-formed rule.
832+
836833let rule R = (H, B) where
837834 H is the sequence of triple templates in the head
838- B is the sequence of triple patterns, condition expressions,
835+ B is the sequence of triple patterns,
836+ condition expressions, negation elements,
839837 and assignments in the body
840838
841- let R : map variable to RDF term as a set of pairs (variable, RDF term)
839+ # Solution sequence of one solution that does not map any variables.
840+ let SEQ0: Solution sequence = { < var > μ</ var > < sub > 0</ sub > }
842841
843- ## Solution sequence of one solution that does not map any variables.
844- ## (This is the join identity)
845-
846- let SEQ: Solution sequence = { < var > μ</ var > < sub > 0</ sub > }
847842let G = < a > evaluation graph</ a >
848843
849- # Start::
850-
851- Replace each blank node in B with a fresh
852- variable that does not occur in the rule body.
853-
854844# Evaluate rule body
855-
856- for each rule element rElt in B
857- if rElt is a triple pattern TP:
858- X = graphMatch(G, TP)
859- SEQ1 = {}
860- for each < var > μ</ var > < sub > 1</ sub > in X:
861- for each < var > μ</ var > < sub > 2</ sub > in SEQ:
862- if compatible(< var > μ</ var > < sub > 1</ sub > , < var > μ</ var > < sub > 2</ sub > )
863- < var > μ</ var > < sub > 3</ sub > = merge(< var > μ</ var > 1, < var > μ</ var > < sub > 2</ sub > )
864- add < var > μ</ var > < sub > 3</ sub > to SEQ1
865- endfor
866- endif
867-
868- if rElt is a condition expression F:
869- SEQ1 = {}
870- for each solution < var > μ</ var > in SEQ:
871- ## EBV = Effective boolean value.
872- ## TODO: Eval errors.
873- if ( EBV(eval(< var > μ</ var > , F)) is true )
874- add < var > μ</ var > to SEQ1
875- endif
876- endfor
877- endif
878-
879- if rElt is an assignment(V, expr)
880- SEQ1 = {}
881- for each solution S in SEQ:
882- let x = eval(expr, S)
883- add(V, x) to S
884- add S to SEQ1
885- endfor
886- endif
887-
888- if SEQ1 is empty
889- SEQ = {}
890- exit
891- endif
892-
893- SEQ = SEQ1
894-
895- endfor
845+ # This function returns a sequence of solutions
846+ define evalRuleElements(B, SEQ, G):
847+
848+ for each rule element rElt in B:
849+
850+ if rElt is a triple pattern TP:
851+ X = graphMatch(G, TP)
852+ SEQ1 = {}
853+ for each < var > μ</ var > < sub > 1</ sub > in X:
854+ for each < var > μ</ var > < sub > 2</ sub > in SEQ:
855+ if compatible(< var > μ</ var > < sub > 1</ sub > , < var > μ</ var > < sub > 2</ sub > )
856+ < var > μ</ var > < sub > 3</ sub > = merge(< var > μ</ var > 1, < var > μ</ var > < sub > 2</ sub > )
857+ add < var > μ</ var > < sub > 3</ sub > to SEQ1
858+ endfor
859+ endif
860+
861+ if rElt is a condition expression with expression F:
862+ SEQ1 = {}
863+ for each solution < var > μ</ var > in SEQ:
864+ if evalFunction(F, < var > μ</ var > ) is < var > true< var > :
865+ add < var > μ</ var > to SEQ1
866+ endif
867+ endfor
868+ endif
869+
870+ if rElt is a negation expression with body elements N:
871+ SEQ1 = {}
872+ for each solution < var > μ</ var > in SEQ:
873+ S = sequence{ < var > μ</ var > }
874+ NEG = evalRuleElements(N, S, G)
875+ if NEG is empty
876+ add < var > μ</ var > to SEQ1
877+ endif
878+ endfor
879+ endif
880+
881+ if rElt is an assignment with variable V and expression expr
882+ SEQ1 = {}
883+ for each solution S in SEQ:
884+ let x = eval(expr, S)
885+ add(V, x) to S
886+ add S to SEQ1
887+ endfor
888+ endif
889+
890+ if SEQ1 is empty
891+ SEQ = {}
892+ return SEQ
893+ endif
894+
895+ SEQ = SEQ1
896+ endfor
897+
898+ return SEQ
899+ enddefine
900+
901+ let SEQ = evalRuleElements(B, SEQ0, G)
896902
897903# Evaluate rule head
898904let H = empty set
@@ -905,7 +911,6 @@ <h4>Evaluation of a Rule</h4>
905911 endfor
906912
907913result eval(R, G) is H
908-
909914</ pre >
910915 < p > Note that `H` may contain triples that are also in the data graph.</ p >
911916 </ section >
0 commit comments