The DASH namespace includes a collection of SHACL constraint components that extend the Core of SHACL with new constraint types. This document introduces these additional constraint components.

This document uses the prefix dash which represents the DASH Data Shapes namespace http://datashapes.org/dash# which is accessible via its URL http://datashapes.org/dash.

Overview

SHACL [[shacl]] includes an extension mechanism that provides an RDF meta-language to represent new types of constraints as constraint components. The DASH namespace uses this extension mechanism to define new kinds of constraints that did not make it into the Core of SHACL itself, yet may be of general interest. As new use cases are explored, DASH will be continuously extended. Contributions and suggestions are more than welcome!

Value Type Constraint Components

The constraint components in this section have in common that they define restrictions on the type of the nodes.

dash:rootClass

For properties that take classes (e.g. instances of rdfs:Class) as their values, the property dash:rootClass can be used to express that all value nodes must be subclasses of the specified root class. This check includes transitive subclasses and the root class itself.

Constraint Component: dash:RootClassConstraintComponent

Parameters:
Property Value Type Summary
dash:rootClass rdfs:Class The class all value nodes must be a subclass of
TEXTUAL DEFINITION
A validation result must be produced for each value node that is neither equal to the given dash:rootClass nor a (transitive) subclass of that class.
SPARQL DEFINITION (Must evaluate to true for each value node $value)
ASK {
    $value rdfs:subClassOf* $rootClass .
}

In the following example scenario, instances of the class ex:Country must point at a subclass of ex:Address using the property ex:addressType.

ex:Country
	a rdfs:Class, sh:NodeShape ;
	sh:property [
		sh:path ex:addressType ;
		dash:rootClass ex:Address ;
	] .

In the following data graph, only ex:Germany is violating the ex:Country shape, because its value for ex:addressType is not declared to be a subclass of ex:Address.

ex:Address
	a rdfs:Class .

ex:AustralianAddress
	a rdfs:Class ;
	rdfs:subClassOf ex:Address .

ex:USAddress
	a rdfs:Class ;
	rdfs:subClassOf ex:Address .
	
ex:Country
	a rdfs:Class .
	
ex:Australia
	a ex:Country ;
	ex:addressType ex:AustralianAddress .
	
ex:USA
	a ex:Country ;
	ex:addressType ex:USAddress .
	
ex:Germany
	a ex:Country ;
	ex:addressType ex:GermanAddress .

String-based Constraint Components

The constraint components in this section have in common that they specify conditions on the string representation of value nodes.

dash:stem

The property dash:stem can be used to state that all value nodes must be IRIs starting with a given string.

Constraint Component: dash:StemConstraintComponent

Parameters:
Property Value Type Summary
dash:stem xsd:string The start of the IRIs
TEXTUAL DEFINITION
A validation result must be produced for each value node that is not an IRI or where the IRI does not start with $stem.
SPARQL DEFINITION (Must evaluate to true for each value node $value)
ASK {
	FILTER (isIRI($value) && STRSTARTS(str($value), $stem))
}

dash:singleLine

The property dash:singleLine can be used to state that all value nodes that are literals must have a lexical form that contains no line breaks ('\n' or '\r'). User interfaces may use the dash:singleLine flag to prefer a text field over a (multi-line) text area.

Constraint Component: dash:SingleLineConstraintComponent

Parameters:
Property Value Type Summary
dash:singleLine xsd:boolean True to state that the lexical form of literal value nodes must not contain any line breaks. False to state that line breaks are explicitly permitted.
TEXTUAL DEFINITION
If $singleLine is true then a validation result must be produced for each value node that is a literal that contains at least one of the line break characters \n or \r.
SPARQL DEFINITION (Must evaluate to true for each value node $value)
ASK {
    FILTER (!$singleLine || !isLiteral($value) || (!contains(str($value), '\n') && !contains(str($value), '\r')))
}
schema:PersonShape
	a sh:NodeShape ;
	sh:targetClass schema:Person ;
	sh:property [
		sh:path schema:givenName ;
		sh:name "given name" ;
		sh:description "A person's first/given name." ;
		sh:datatype xsd:string ;
		dash:singleLine true ;       # Cannot contain line breaks -> Text field for input
	] ;
	sh:property [
		sh:path schema:description ;
		sh:name "description" ;
		sh:datatype xsd:string ;
		dash:singleLine false ;      # Explicitly may have multiple lines -> Text area for input
	] .

Property Pair Constraint Components

The constraint components in this section restrict the sets of value nodes in relation to other properties.

dash:coExistsWith

The property dash:coExistsWith can be used to state that if there are any value nodes (for the given path in the property shape) then there must also be values for a specified property, and if there are no value nodes then there cannot be any values for a specified property either.

Constraint Component: dash:CoExistsWithConstraintComponent

Parameters:
Property Value Type Summary
dash:coExistsWith rdf:Property The property that must co-exist with the given path
TEXTUAL DEFINITION
A validation result must be produced if either there is at least one value node but there is no value for $coExistsWith at the focus node, or if there is no value node but there is at least one value for $coExistsWith at the focus node.
SPARQL DEFINITION
SELECT $this
WHERE {
	{
    	FILTER (EXISTS { $this $PATH ?any } && NOT EXISTS { $this $coExistsWith ?any })
	}
	UNION
	{
    	FILTER (NOT EXISTS { $this $PATH ?any } && EXISTS { $this $coExistsWith ?any })
	}
}

In the following example scenario, if an instance of the class ex:Measurement has any value for the property ex:minValue then it must also have value(s) for ex:maxValue.

ex:Measurement
	a rdfs:Class, sh:NodeShape ;
	sh:property [
		sh:path ex:minValue ;
		dash:coExistsWith ex:maxValue ;
	] .

dash:subSetOf

The property dash:subSetOf can be used to state that all value nodes must also be values of a specified other property at the same focus node.

Constraint Component: dash:SubSetOfConstraintComponent

Parameters:
Property Value Type Summary
dash:subSetOf rdf:Property The property that must also have all values of the given path
TEXTUAL DEFINITION
A validation result must be produced for each value node that is not also a value of the given property (specified via dash:subSetOf) for the same focus node as subject.
SPARQL DEFINITION (Must evaluate to true for each value node $value)
ASK {
    $this $subSetOf $value .
}

In the following example scenario, instances of the class ex:Person can have values for the properties ex:child and ex:favoriteChild, but the favorite child must also be one of the children.

ex:Person
	a rdfs:Class, sh:NodeShape ;
	sh:property [
		sh:path ex:favoriteChild ;
		dash:subSetOf ex:child ;
	] .

Relationship Constraint Components

The constraint components in this section define constraints on relationships between nodes.

dash:nonRecursive

The property dash:nonRecursive can be used to express that a property or path must not point back to itself. For example, "a person cannot have itself as parent" can be expressed by setting dash:nonRecursive to true for a given property ex:parent. To express that a person cannot have itself among any of its (recursive) parents, use a sh:path with the + operator such as ex:parent+.

Constraint Component: dash:NonRecursiveConstraintComponent

Parameters:
Property Value Type Summary
dash:nonRecursive xsd:boolean True to specify that the property must be non-recursive
TEXTUAL DEFINITION
If dash:nonRecursive is true, then a validation result must be produced for each focus node where the set of value nodes includes the focus node itself.
SPARQL DEFINITION
SELECT $this ($this AS ?value)
WHERE {
	{
		FILTER (?nonRecursive)
	}
	$this $PATH $this .
}
ex:Person
	a rdfs:Class, sh:NodeShape ;
	sh:property [
		dash:nonRecursive true ;
		sh:path [
			sh:oneOrMorePath ex:parent ;
		] ;
	] .

dash:symmetric

The property dash:symmetric can be used to express that a property is symmetric. For symmetric properties, if A relates to B then B must relate to A.

Constraint Component: dash:SymmetricConstraintComponent

Parameters:
Property Value Type Summary
dash:symmetric xsd:boolean True to specify that the property is symmetric
TEXTUAL DEFINITION
If dash:symmetric is true, then a validation result must be produced for each value node ?value where there exists no match ?value $PATH $this for the given focus node $this and the path $PATH.
SPARQL DEFINITION
SELECT $this ?value {
	FILTER ($symmetric) .
	$this $PATH ?value .
	FILTER NOT EXISTS {
    	?value $PATH $this .
	}
}

Other Constraint Components

The constraint components in this section do not fit into the other categories.

dash:closedByTypes

The property dash:closedByTypes can be used to declare that focus nodes are "closed" based on their value of rdf:type, meaning that focus nodes may only have values for the properties that are explicitly enumerated via sh:property/sh:path in property shapes at their types and the superclasses of those. This assumes that the type classes are also shapes.

Constraint Component: dash:ClosedByTypesConstraintComponent

Parameters:
Property Value Type Summary
dash:closedByTypes xsd:boolean True to specify that instances of the shape are closed by their types
TEXTUAL DEFINITION
If dash:closedByTypes is true, a validation result must be produced for each value v of property p of the focus node where p is not defined as the sh:path of any sh:property constraints attached to any of the SHACL types of the focus node, and p is not rdf:type. In the produced validation results, p is the value for sh:resultPath and v is the value for sh:value.
SPARQL DEFINITION
SELECT $this (?predicate AS ?path) ?value
WHERE {
	FILTER ($closedByTypes) .
    $this ?predicate ?value .
	FILTER (?predicate != rdf:type) .
	FILTER NOT EXISTS {
		$this rdf:type ?type .
		?type rdfs:subClassOf* ?class .
		GRAPH $shapesGraph {
			?class sh:property/sh:path ?predicate .
		}
	}
}

In the following example, note that the classes are also declared to be node shapes.

ex:SuperClass
	a rdfs:Class, sh:NodeShape ;
	dash:closedByTypes true ;
	sh:property [
		sh:path ex:superProperty ;
    ] .
    
ex:MiddleClass
	a rdfs:Class, sh:NodeShape ;
	rdfs:subClassOf ex:SuperClass ;
	sh:property [
		sh:path ex:middleProperty ;
	] .
	
ex:SubClass
	a rdfs:Class, sh:NodeShape ;
	rdfs:subClassOf ex:MiddleClass ;
	sh:property [
		sh:path ex:subProperty ;
    ] .

With the following data graph, ex:InvalidInstance1 is violating the sh:closedByTypes constraint because it has a value sub for ex:subProperty but it is only declared to have type ex:MiddleClass while ex:subProperty is defined outside of the shapes associated with the types of ex:InvalidInstance1. ex:ValidInstance1 does not produce validation results because it only uses properties that are either rdf:type or declared in the shapes associated with either ex:MiddleClass or its superclass.

ex:SuperClass
	a rdfs:Class .
    
ex:MiddleClass
	a rdfs:Class ;
	rdfs:subClassOf ex:SuperClass .
	
ex:SubClass
	a rdfs:Class ;
	rdfs:subClassOf ex:MiddleClass .

ex:InvalidInstance1
	a ex:MiddleClass ;
	ex:subProperty "sub" .

ex:ValidInstance1
	a ex:MiddleClass ;
	ex:middleProperty "A" ;
	ex:superProperty "A" .

dash:hasValueIn

The property dash:hasValueIn can be used to state that at least one value node must be a member of a provided SHACL list. This constraint component only makes sense for property shapes. It takes a list argument similar to sh:in but is "open" like sh:hasValue since it allows values outside of the list.

Constraint Component: dash:HasValueInConstraintComponent

Parameters:
Property Value Type Summary
dash:hasValueIn SHACL list At least one of the value nodes must be a member of this list
TEXTUAL DEFINITION
A validation result must be produced if none of the value nodes is a member of $hasValueIn.

Note that matching of literals needs to be exact, e.g. "04"^^xsd:byte does not match "4"^^xsd:integer.

SPARQL DEFINITION
SELECT $this
WHERE {
	FILTER NOT EXISTS {
    	$this $PATH ?value .
    	GRAPH $shapesGraph {
    		$hasValueIn (rdf:rest*)/rdf:first ?value
    	}
	}
}
ex:ExampleShape
	a sh:NodeShape ;
	sh:targetClass ex:Agent ;
	sh:property [
		sh:path ex:type ;
		dash:hasValueIn ("person" "organization") ;
  ].

With the following data graph, the first two nodes conform although they have extra values for ex:type. The last two nodes do not conform because no ex:type literal matches exactly one of the list members.

ex:Person1 a ex:Agent; ex:type "person",       "investor".
ex:Org1    a ex:Agent; ex:type "organization", "investor".
ex:Person2 a ex:Agent; ex:type "person"@en.
ex:Org2    a ex:Agent; ex:type "organisation".
        

dash:hasValueWithClass

The property dash:hasValueWithClass can be used to state that one of the value nodes must be an instance of a given class. This constraint component only really makes sense for property shapes.

Constraint Component: dash:HasValueWithClassConstraintComponent

Parameters:
Property Value Type Summary
dash:hasValueWithClass rdfs:Class The class that at least one of the value nodes must have
TEXTUAL DEFINITION
A validation result must be produced if none of the value nodes is a SHACL instance of $hasValueWithClass.
SPARQL DEFINITION
SELECT $this
WHERE {
	FILTER NOT EXISTS {
		$this $PATH ?value .
		?value a ?type .
		?type rdfs:subClassOf* $hasValueWithClass .
	}
}
ex:ExampleShape
	a sh:NodeShape ;
	sh:targetNode ex:InvalidInstance1, ex:ValidInstance1 ;
	sh:property [
		sh:path ex:property ;
		dash:hasValueWithClass ex:SuperClass ;
    ] .

With the following data graph, only ex:InvalidInstance1 is violated because none of its values for ex:property are instances of ex:SuperClass.

ex:SuperClass
	a rdfs:Class .

ex:SubClass
	a rdfs:Class ;
	rdfs:subClassOf ex:SuperClass .

ex:SubClassInstance a ex:SubClass .

ex:InvalidInstance1
	ex:property ex:SomeInstance .

ex:ValidInstance1
	ex:property ex:SomeInstance, ex:SubClassInstance .

Note that the property dash:hasValueWithClass is primarily syntactic sugar for the following qualified value constraint. It is also very similar to owl:someValuesFrom.

ex:ExampleShape
	a sh:NodeShape ;
	sh:property [
		sh:path ex:property ;
		sh:qualifiedMinCount 1 ;
		sh:qualifiedValueShape [ sh:class ex:SuperClass ] ;
    ] .

dash:uniqueValueForClass

In some cases, property values must be unique for all members of a class. Examples include Social Security Numbers. The property dash:uniqueValueForClass can be used to enforce such constraints.

Constraint Component: dash:UniqueValueForClassConstraintComponent

Parameters:
Property Value Type Summary
dash:uniqueValueForClass rdfs:Class The class for which the property values must be unique.
TEXTUAL DEFINITION
A validation result must be produced for each value node that is also a value node for another focus node that is instance of $uniqueValueForClass.
SPARQL DEFINITION
SELECT DISTINCT $this ?value ?other
WHERE {
	{
    	$this $PATH ?value .
		?other $PATH ?value .
		FILTER (?other != $this) .
	}
	?other a ?type .
	?type rdfs:subClassOf* $uniqueValueForClass .
}

Note that this constraint type can only be used in property shapes. It will always produce pairs of constraint violations for each duplicate value.

The following example declares that all values of the property ex:ssn must be unique among instances of ex:Person.

ex:PersonShape
	a sh:NodeShape ;
	sh:targetClass ex:Person ;
	sh:property [
		sh:path ex:ssn ;
		sh:datatype xsd:string ;
		sh:maxCount 1 ;
		dash:uniqueValueForClass ex:Person ;
	] .

dash:uriStart

Enforces a constraint that the given property (sh:path) serves as primary key for all focus nodes of the shape. If a property has been declared to be the primary key then each focus node must have exactly one value for that property. Furthermore, the URIs of those focus nodes must start with a given string (dash:uriStart), followed by the URL-encoded primary key value. For example if dash:uriStart is "http://example.org/country-" and the primary key for an instance is "de" then the URI must be "http://example.org/country-de". Finally, as a result of the URI policy, there can not be any other focus node with the same value under the same primary key policy.

Constraint Component: dash:PrimaryKeyConstraintComponent

Parameters:
Property Value Type Summary
dash:uriStart xsd:string The start of URIs of the focus nodes. Can only be used in property shapes.
TEXTUAL DEFINITION
A validation result must be produced for each focus node that is not an IRI, or where the IRI does not start with the $uriStart, or where the focus node does not have exactly one value for the path property, or where the IRI is not equal to the concatenation of $uriStart and the string representation of the value of the property path.