2. History Lesson: Protégé-2000
• Frame-based, closed-world modeling tool
• Declarative core language, extended by
• Protégé Axiom Language (PAL)
Source: http://protege.stanford.edu/plugins/paltabs/pal-quickguide/PALTutorial.pdf
3. Where did PAL go?
• Lack of Standardization
• Lack of support outside of academia
• Wave of Open-World RDFS/OWL enthusiasm
• Fundamentally different situation with SPARQL
• SHACL can stand on the shoulders of giants
4. SHACL Draft Status
• This draft includes contributions from almost
everyone in the WG
• Covers all approved requirements
• Prototype (Open Source Jena API & TBC Free)
could be made available anytime
• TopQuadrant’s interests align with community
• Able to evolve quickly, willing to listen
5. Basic Principles
• Simple, declarative vocabulary for common
cases (“Core” or “Lite”)
• Fully integrated mechanism for complex cases
– SPARQL, but adding JavaScript etc is easy
• Macro facility to make complex cases simple
• Core language itself is defined as Macros
• Very consistent design, easy to implement
• Designed for both the Web and Intranets
6. Vocabulary
• Focus node: currently validated RDF node
• Constraint: condition that can be validated,
producing errors or warnings
• Shape: collection of constraints about the
same focus node
• Template: reusable constraint wrapped into
new high-level vocabulary term
8. User Story 1
s1:PropertyMustHaveDomainShape
a sh:Shape ;
rdfs:comment "Every rdf:Property must have at least one rdfs:domain statement." ;
sh:scopeClass rdf:Property ;
sh:property [
sh:predicate rdfs:domain ;
sh:minCount 1 ;
] .
9. User Story 2
s2:PersonShape
a sh:Shape ;
rdfs:comment "Persons must have at least one name (xsd:string)." ;
sh:scopeClass s2:Person ;
sh:property [
sh:predicate s2:name ;
sh:datatype xsd:string ;
sh:minCount 1 ;
] .
10. User Story 2 (with ShapeClass)
s2b:Person
a sh:ShapeClass ;
rdfs:label "Person" ;
sh:property [
sh:predicate s2b:name ;
sh:datatype xsd:string ;
sh:minCount 1 ;
rdfs:comment "Persons must have at least one name (xsd:string)." ;
] .
{
"@id" : "s2b:Person",
"@type" : "sh:ShapeClass",
"label" : "Person",
"property" : {
"predicate" : "s2b:name",
"datatype" : "xsd:string",
"minCount" : 1,
"comment" : "Persons must have at least one name (xsd:string)."
}
}
Turtle
JSON-LD
11. User Story 3
s3:PersonMarriageShape
a sh:Shape ;
sh:scopeClass s3:Person ;
sh:constraint [
sh:message "Same-sex marriage is not permitted (in this model) – spouse is {?gender}." ;
sh:predicate s3:spouse ;
sh:severity sh:Warning ;
sh:sparql """
SELECT ?this (?this AS ?subject) (?spouse AS ?object) ?gender
WHERE {
?this s3:gender ?gender .
?this s3:spouse ?spouse .
?spouse s3:gender ?gender .
}""" ;
] .
12. User Story 4 (1/4)
• Issue tracker with context-specific constraints
• Issues may be assigned, unassigned, resolved
– Resolved issues must not have assignedTo
– The submitter of unresolved issues must have
email address
• Also: IssueShape is closed, i.e. only the three
enumerated properties are permitted
14. s4:PendingIssueShape
a sh:Shape ;
rdfs:comment "Shape for Issues that are not resolved yet." ;
sh:scopeClass s4:Issue ;
sh:scopeShape [
sh:property [
sh:predicate s4:status ;
sh:allowedValues ( s4:assigned s4:unassigned ) ;
sh:minCount 1 ;
] ;
] ;
sh:property [
rdfs:comment "Pending issues must be submitted by someone who has an email address." ;
sh:predicate s4:submittedBy ;
sh:valueShape [
sh:property [
sh:predicate s4:email ;
sh:minCount 1 ;
] ;
] ;
] .
User Story 4 (3/4)
Scope for which this shape applies
15. s4:ResolvedIssueShape
a sh:Shape ;
rdfs:comment "Shape for Issues that are resolved." ;
sh:scopeClass s4:Issue ;
sh:scopeShape [
sh:property [
sh:predicate s4:status ;
sh:hasValue s4:resolved ;
] ;
] ;
sh:property [
sh:predicate s4:assignedTo ;
rdfs:comment "Resolved issues must not be assigned to anyone." ;
sh:maxCount 0 ;
] .
User Story 4 (4/4)
Scope for which this shape applies
17. User Story 21
s21:UniqueLanguagePropertyConstraint
a sh:ConstraintTemplate ;
rdfs:label "Unique language property constraint" ;
rdfs:subClassOf sh:AbstractPropertyConstraint ;
sh:message "Language {?lang} is used more than once for {?predicate}" ;
sh:sparql """
SELECT ?this (lang(?label1) AS ?lang) (?this AS ?subject) ?predicate (?label1 AS ?object)
WHERE {
?this ?predicate ?label1 .
?this ?predicate ?label2 .
FILTER ((lang(?label1) = lang(?label2)) && (?label1 != ?label2)) .
}""" .
Reusable constraint macro
s21:SKOSConceptShape
a sh:Shape ;
sh:scopeClass skos:Concept ;
sh:constraint [
a s21:UniqueLanguagePropertyConstraint ;
sh:predicate skos:prefLabel ;
] .
18. User Story 23 (1/3)
s23:FlightReservationShape
a sh:Shape ;
sh:scopeClass schema:FlightReservation ;
sh:property [
sh:predicate schema:reservationFor ;
sh:valueShape [
sh:constraint [
sh:message "A future date is required to show a boarding pass."
sh:predicate schema:departureTime ;
sh:sparql """
SELECT ?this (?this AS ?subject) (?t AS ?object)
WHERE {
?this schema:departureTime ?t .
FILTER (?t <= NOW())
}""" ;
] ;
] ;
] .
19. User Story 23 (2/3)
s23:IrreflexiveChildrenShape
a sh:Shape ;
sh:scopeClass schema:Person ;
sh:property [
a s23:IrreflexivePropertyConstraint ;
sh:predicate schema:children ;
sh:valueType schema:Person ;
] .
s23:IrreflexivePropertyConstraint
a sh:ConstraintTemplate ;
rdfs:subClassOf sh:PropertyConstraint ;
rdfs:comment "Detects triples where ?this points to itself." ;
sh:message "For {?predicate} a focus not cannot point to itself." ;
sh:sparql """
SELECT ?this (?this AS ?subject) ?predicate (?this AS ?object)
WHERE {
?this ?predicate ?this
}""" .
s23:MrSelfie
a schema:Person ;
schema:children s23:MrSelfie .
20. User Story 23 (3/3)
s23:OrderedPropertyPairConstraint
a sh:ConstraintTemplate ;
rdfs:subClassOf sh:TemplateConstraint ;
sh:argument [
rdfs:label "The property with the smaller values." ;
sh:predicate s23:property1 ;
sh:valueType rdf:Property ;
] ;
sh:argument [
rdfs:label "The property with the larger values." ;
sh:predicate s23:property2 ;
sh:valueType rdf:Property ;
] ;
sh:message "{?property1} cannot be larger than {?property2}" ;
sh:sparql """
SELECT ?this (?this AS ?subject) (?property1 AS ?predicate) (?value1 AS ?object) ?property1 ?property2
WHERE {
?this ?property1 ?value1 .
?this ?property2 ?value2 .
FILTER (?value1 > ?value2)
}""" .
s23:MsImpossible
a schema:Person ;
schema:birthDate "2015-05-10"^^xsd:date ;
schema:deathDate "2015-05-09"^^xsd:date .
s23:BirthAndDeathDateShape
a sh:Shape ;
sh:scopeClass schema:Person ;
sh:constraint [
a s23:OrderedPropertyPairConstraint ;
s23:property1 schema:birthDate ;
s23:property2 schema:deathDate ;
] .
Same for start & end date
and other pairs
21. Reuse of Templates for EDM
rda:Person
a sh:ShapeClass ;
sh:constraint [
a edmsh:OrderedPropertyPairConstraint ;
edmsh:property1 rdaGr2:dateOfBirth ;
edmsh:property2 rdaGr2:dateOfDeath ;
rdfs:comment "#4 rdaGr2:dateofBirth must be earlier than
rdaGr2:dateOfDeath and rdaGr2:dateOfDeath must be later than
rdaGr2:dateofBirth (DC:R-43) (W3:R-6.6) (W3:R-5.9.1)" ;
] .
rdfs:Resource
sh:constraint [
a edmsh:LanguageShouldBePresentPropertyConstraint ;
sh:predicate skos:prefLabel ;
rdfs:comment "#5 Ideally the language tag should be present for skos:prefLabel" ;
] ;
sh:constraint [
a edmsh:UniqueLanguagePropertyConstraint ;
sh:predicate skos:prefLabel ;
rdfs:comment "#5 We must have only one skos:prefLabel per language." ;
] .
22. SHACL Design Axis
• Pragmatic design for real-world problems
• Based on many years of industry experience
• Trade-off between declarative and expressive
• Half of the examples needed SPARQL
• Declarative sub-languages can have
non-SPARQL implementations
Declarativeness Expressiveness
SPARQL JavaScriptSHACL Core Other SHACL Templates
Popular Templates evolve into Standards
24. Elements of the Draft
• Self-contained, consistent document
• “Core” and “Advanced” parts
• Plenty of examples (we can wait with Primer)
• Open Issues/TODOs are clearly marked
• Includes SHACL system vocabulary in Turtle
• SHACL is defined in itself
28. A Future-Proof SHACL
• Most W3C languages were not really designed for
the Web, have hard-coded syntax and semantics
• Templates: new high-level language elements
• Functions: SPARQL extensions
– Some with SPARQL bodies
– Some with other executable languages (JS etc)
– Some provided by custom extensions (e.g. GeoSPARQL)
• Directly benefits from SPARQL’s evolution,
new SPARQL end points, database features etc
• Open to future developments (JSON-LD etc)
• sh:rule could be added consistently