From ec708095914229ef38c440a1c86dd833d7500442 Mon Sep 17 00:00:00 2001
From: Holger Knublauch
+ SHACL includes vocabulary that can be used to define new node expression functions
+ by wrapping another (parameterized) node expression.
+
+ TODO: Describe syntax and semantics
+
+ The following example defines a new node expression function
+ This new node expression function can the be used as follows:
+
+ The following example defines a new node expression function
+ This new node expression function can the be used as follows:
+
From 17296aeeec98106b8aff93d07aa3a406d069856b Mon Sep 17 00:00:00 2001
From: Holger Knublauch
- TODO: Describe syntax and semantics
+ TODO: Describe syntax and semantics.
+ In a nutshell, these declarations use the same syntax as the built-in functions,
+ but also carry a sh:expressionBody.
+ In this body, you can access the input node expressions using shnex:arg.
+ This will recursively evaluate those nested expressions.
+ As these are lists, we cannot use shnex:var (which only supports individual nodes).
+
+ A blank node that is the subject of the following properties
+ is called an arg expression with the function name
+ Let The remainder of this section is informative.
+ Both
- SHACL includes vocabulary that can be used to define new node expression functions
+ SHACL includes vocabulary terms that can be used to define new node expression functions
by wrapping another (parameterized) node expression.
+ This makes it possible to extend the library of available SHACL node expressions without hard-coded
+ changes to an engine.
TODO: Describe syntax and semantics.
In a nutshell, these declarations use the same syntax as the built-in functions,
- but also carry a sh:expressionBody.
+ but also carry a sh:bodyExpression.
In this body, you can access the input node expressions using shnex:arg.
This will recursively evaluate those nested expressions.
As these are lists, we cannot use shnex:var (which only supports individual nodes).
@@ -2168,7 +2170,7 @@
+ Custom node expressions can use
A blank node that is the subject of the following properties
@@ -2266,9 +2271,9 @@ The remainder of this section is informative.
- Both
- Using this extra information, we can now define a
- During validation, a Dynamic SHACL engine will evaluate the path expression at
SHACL includes vocabulary terms that can be used to define new node expression functions
- by wrapping another (parameterized) node expression.
- This makes it possible to extend the library of available SHACL node expressions without hard-coded
- changes to an engine.
+ by wrapping other (parameterized) node expressions.
+ This makes it possible to extend the library of available SHACL node expressions without having to
+ hard-code changes to an engine.
- TODO: Describe syntax and semantics.
- In a nutshell, these declarations use the same syntax as the built-in functions,
- but also carry a sh:bodyExpression.
- In this body, you can access the input node expressions using shnex:arg.
- This will recursively evaluate those nested expressions.
- As these are lists, we cannot use shnex:var (which only supports individual nodes).
-
+
+ A custom named parameter function is an IRI in a shapes graph
+ that is a SHACL instance of
+
+ A custom named parameter expression is a node expression
+ represented by a blank node that has exactly one value for at least one of
+ the key parameters.
+
+
+ Let The remainder of this section is informative.
The following example defines a new node expression function
+
+ A custom list parameter function is an IRI in a shapes graph
+ that is a SHACL instance of
+
+ A custom list parameter expression is a node expression
+ represented by a blank node that is the subject of exactly one triple
+ and the predicate of that triple is the list parameter property of a
+ custom list parameter function in the shapes graph.
+
+
+ Let The remainder of this section is informative.
The following example defines a new node expression function InstancesOf Expressions
+ Custom Node Expressions
+ Example: User-Defined Named Parameter Function
+ ex:AverageExpression
+ that takes another node expression as input using the key parameter ex:average
+ and then calculates the sum of all input nodes and divides it by the number of nodes,
+ returning the average value of these nodes.
+ Example: User-Defined List Parameter Function
+ ex:spacedConcat
+ that takes two nodes as input and returns a string concatenating the two nodes with a space in between.
+ Constraint Components
Custom Node Expressions
by wrapping another (parameterized) node expression.
Example: User-Defined Named Parameter Function
@@ -2128,7 +2133,7 @@ Example: User-Defined Named Parameter Function
ex:AverageExpression
a sh:NamedParameterExpressionFunction ;
rdfs:label "Average expression"@en ;
- rdfs:comment "Computes the average of the nodes provided by ex:average." ;
+ rdfs:comment "Computes the average of the nodes provided by ex:average." ;
rdfs:subClassOf sh:NamedParameterExpression ;
sh:parameter ex:AverageExpression-average ;
sh:expressionBody [
@@ -2140,9 +2145,9 @@ Example: User-Defined Named Parameter Function
.
ex:AverageExpression-average
a sh:Parameter ;
- sh:path ex:average ;
- sh:name "average" ;
- sh:description "The nodes of which the average shall be computed." ;
+ sh:path ex:average ;
+ sh:name "average" ;
+ sh:description "The nodes of which the average shall be computed." ;
.
From bda7a178a51140ffdef19a2e66ec07a1df401203 Mon Sep 17 00:00:00 2001
From: Holger Knublauch Node Expressions
During evaluation, the engine can access triples related to expr
in the shapes graph.
focusGraph
is a graph, called the focus graph. This is the default query graph for the evaluation of the node expression.focusNode
is a node, called the input focus node. This variable may have no value.scope
is a map from variable names to individual nodes.
+ scope
is a map from (key) nodes to individual (value) nodes.
The empty map is written as {}
.
Example: User-Defined Named Parameter Function
sh:path ex:average ;
sh:name "average" ;
sh:description "The nodes of which the average shall be computed." ;
+ sh:keyParameter true ;
.
@@ -2196,9 +2197,9 @@ Example: User-Defined Named Parameter Function
sh:datatype xsd:decimal ;
sh:values [
ex:average [
- shnex:path ( ex:employee ex:income )
+ shnex:pathValues ( ex:employee ex:income )
]
- ]
+ ] .
@@ -2247,6 +2248,60 @@ Example: User-Defined List Parameter Function
Arg Expressions
+ shnex:ArgExpression
:
+
+
+
+
+ Property
+ Constraints
+ Description
+
+
+
+
+
+
+ shnex:arg
+
+
+ sh:or (
+ [ sh:nodeKind sh:IRI ]
+ [ sh:datatype xsd:integer ]
+ )
+
+
+ The argument key, e.g.
+ ex:myParameter
or 1
.
+ arg
be the value of shnex:arg
in the arg expression.
+ The output nodes of the var expression are computed as follows, in order:
+
+
+ arg
is in the scope
and has the value a
then
+ evalExpr(expr, focusGraph, focusNode, scope) -> evalExpr(a, focusGraph, focusNode, {})
+ evalExpr(expr, focusGraph, focusNode, scope) -> []
shnex:arg
and shnex:var
access values from the scope.
+ The difference is that shnex:arg
interprets the values as node expressions, while
+ shnex:var
treats the values as individual nodes.
+ As a result, a custom node expression can evaluate nested node expressions that as passed in as arguments.
+ InstancesOf Expressions
Custom Node Expressions
Example: User-Defined Named Parameter Function
rdfs:comment "Computes the average of the nodes provided by ex:average." ;
rdfs:subClassOf sh:NamedParameterExpression ;
sh:parameter ex:AverageExpression-average ;
- sh:expressionBody [
+ sh:bodyExpression [
sparql:divide (
[ shnex:sum [ shnex:arg ex:average ] ]
[ shnex:count [ shnex:arg ex:average ] ]
@@ -2217,7 +2219,7 @@ Example: User-Defined List Parameter Function
a sh:ListParameterExpressionFunction ;
rdfs:label "Spaced concat expression"@en ;
rdfs:subClassOf sh:ListParameterExpression ;
- sh:expressionBody [
+ sh:bodyExpression [
sparql:concat (
[ shnex:arg 0 ]
" "
@@ -2251,6 +2253,9 @@ Example: User-Defined List Parameter Function
Arg Expressions
+ shnex:arg
to access the arguments.
+ Arg Expressions
shnex:arg
@@ -2296,7 +2301,7 @@
- sh:or (
- [ sh:nodeKind sh:IRI ]
- [ sh:datatype xsd:integer ]
+ sh:or (
+ [ sh:nodeKind sh:IRI ]
+ [ sh:datatype xsd:integer ]
)
Arg Expressions
shnex:arg
and shnex:var
access values from the scope.
+ Both shnex:arg
and shnex:var
access values from the scope.
The difference is that shnex:arg
interprets the values as node expressions, while
shnex:var
treats the values as individual nodes.
As a result, a custom node expression can evaluate nested node expressions that as passed in as arguments.
@@ -2961,7 +2966,7 @@ Example: Dynamic Enumerations
sh:in
constraint using a Path Expression:
+ Using this extra information, we can now define a sh:in
constraint using a Path Values Expression:
sh:in
+ During validation, a Dynamic SHACL engine will evaluate the path values expression at sh:in
and use the resulting nodes as members of the allowed values.
Thus, when the value of ex:country
is ex:USA
, it will look up the
state codes that are linked to ex:USA
.
diff --git a/shacl12-vocabularies/shacl.ttl b/shacl12-vocabularies/shacl.ttl
index 71d6333a..ed980e9b 100644
--- a/shacl12-vocabularies/shacl.ttl
+++ b/shacl12-vocabularies/shacl.ttl
@@ -1386,6 +1386,13 @@ sh:ListParameterExpression
rdfs:subClassOf sh:NodeExpression ;
rdfs:isDefinedBy sh: .
+sh:bodyExpression
+ a rdf:Property ;
+ rdfs:label "body expression"@en ;
+ rdfs:comment "A node expression that is the implementation/body of a custom node expression function."@en ;
+ rdfs:domain sh:NodeExpressionFunction ;
+ rdfs:isDefinedBy sh: .
+
# General SPARQL execution support --------------------------------------------
From 33472b9c59e2151a40e10cd8228ffac19da06295 Mon Sep 17 00:00:00 2001
From: Holger Knublauch InstancesOf Expressions
Custom Node Expressions
Example: User-Defined Named Parameter Function
+
+ Custom Named Parameter Functions
+ sh:NamedParameterExpressionFunction
and
+ a SHACL subclass of sh:NamedParameterExpression
.
+ It has a single value for sh:bodyExpression
that is a well-formed
+ node expression.
+
+ A custom named parameter function declares one or more parameters as values
+ of sh:parameter
, where each such parameter has exactly one value for
+ sh:path
and that value is an IRI.
+ At least one of the parameters has sh:keyParameter true
, declaring the key parameters
+ for the function.
+ The key parameters of all node expression functions
+ (including the built-in ones from the shnex:
namespace) must be disjoint.
+
+ Custom named parameter functions can reference the declared parameters using an
+ arg expression such as [ shnex:arg ex:param ]
, where the value of shnex:arg
+ matches the IRI of the parameter's sh:path
.
+
+ expr
be a custom named parameter expression with the
+ custom named parameter function f
.
+ Let body
be the value of sh:bodyExpression
at f
+ in the shapes graph.
+
+ Let argScope
be a map of (parameter) nodes as keys and (argument) nodes
+ as values, so that each parameter of f
has the value of the parameter's
+ sh:path
from expr
.
+ For example, if f
declares just one parameter with sh:path
ex:param
+ and expr
is [ ex:param 42 ]
then argScope
is { ex:param : 42 }
.
+
+ The output nodes of expr
are computed using
+ evalExpr(expr, focusGraph, focusNode, scope) -> evalExpr(body, focusGraph, focusNode, argScope)
+ ex:AverageExpression
that takes another node expression as input using the key parameter ex:average
@@ -2175,7 +2215,7 @@ Example: User-Defined Named Parameter Function
[ shnex:sum [ shnex:arg ex:average ] ]
[ shnex:count [ shnex:arg ex:average ] ]
)
- ]
+ ] ;
.
ex:AverageExpression-average
a sh:Parameter ;
@@ -2206,8 +2246,51 @@ Example: User-Defined Named Parameter Function
Example: User-Defined List Parameter Function
+
+ Custom List Parameter Functions
+ sh:ListParameterExpressionFunction
and
+ a SHACL subclass of sh:ListParameterExpression
.
+ The IRI of a custom list parameter function is its list parameter property.
+ It has a single value for sh:bodyExpression
that is a well-formed
+ node expression.
+
+ Custom list parameter functions can reference the arguments using an
+ arg expression such as [ shnex:arg 0 ]
and [ shnex:arg 1 ]
+ where the xsd:integer
n
corresponds to the n
th member
+ of the arguments list, starting with 0
as the first member.
+
+ expr
be a custom list parameter expression with the
+ custom list parameter function f
.
+ Let body
be the value of sh:bodyExpression
at f
+ in the shapes graph.
+
+ Let argScope
be a map of (parameter index) nodes as keys and (argument) nodes
+ as values, so that each list argument of expr
has the index of the argument as an
+ xsd:integer
as key, starting with 0
for the first argument.
+ For example, if expr
has arguments ( 38 4 )
then the
+ argScope
is { 0 : 38, 1 : 4 }
.
+
+ The output nodes of expr
are computed using
+ evalExpr(expr, focusGraph, focusNode, scope) -> evalExpr(body, focusGraph, focusNode, argScope)
+ ex:spacedConcat
that takes two nodes as input and returns a string concatenating the two nodes with a space in between.
@@ -2304,7 +2387,7 @@ Arg Expressions
Both shnex:arg
and shnex:var
access values from the scope.
The difference is that shnex:arg
interprets the values as node expressions, while
shnex:var
treats the values as individual nodes.
- As a result, a custom node expression can evaluate nested node expressions that as passed in as arguments.
+ As a result, a custom node expression can evaluate nested node expressions that are passed in as arguments.
Custom List Parameter Functions
The output nodes of expr
are computed using
evalExpr(expr, focusGraph, focusNode, scope) -> evalExpr(body, focusGraph, focusNode, argScope)
+ where an evaluation failure is reported when there is more than 1 output node.
The remainder of this section is informative.
From eb2b21a32b1e74f6d761eba88d5cc64efea47c78 Mon Sep 17 00:00:00 2001 From: Holger Knublauch
- Examples of shnex:arg
can be found in the examples
- and .
+ Examples of shnex:arg
can be found in
+ and .