Nanoarguments: Conformance Shapes
- License
- CC BY 4.0
Introduction
The Nanoarguments conformance shapes are a SHACL description of what counts as a well-formed Nanoarguments nanopublication, for validating instances produced by the templates or retrieved from the network. They are pure SHACL Core, so any conformant validator runs them.
Shapes
What each shape checks:
DiscourseContribution(schema:Statementorschema:Question): exactly onerdf:value;as:inReplyToat most once;cito:citesAsEvidencerepeatable. The CiTO stance predicate is unconstrained for statements; for questions seeQuestionStance.QuestionStance(schema:Question): no affirmative stance (cito:supports,cito:agreesWith,cito:extends,cito:confirms).Evidence(sio:SIO_001394): exactly onerdf:value.AssertionProvenance: the assertion isprov:wasAttributedToan agent;prov:wasDerivedFromis an IRI when present.Nanopublication: adct:creatoranddct:license; a missingdct:createdis a warning, not an error.
The Web Annotation layer of an annotation contribution (the oa:Annotation and its selectors) is
validated against the W3C Web Annotation model and its
test suite, not re-specified here; Nanoarguments-specific annotation shapes may be added later.
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix schema: <https://schema.org/> .
@prefix cito: <http://purl.org/spar/cito/> .
@prefix sio: <http://semanticscience.org/resource/> .
@prefix as: <https://www.w3.org/ns/activitystreams#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix nash: <https://w3id.org/nanoarguments/shapes/> .
# Nanoarguments conformance shapes (SHACL Core) for a signed nanopublication.
# Validate over the union of the nanopub's four graphs; see shapes.html to run it.
nash:DiscourseContribution a sh:NodeShape ;
rdfs:label "Discourse contribution (content node)" ;
sh:targetClass schema:Statement ;
sh:targetClass schema:Question ;
sh:property [
sh:path rdf:value ;
sh:name "statement or question text" ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:message "A discourse contribution needs exactly one rdf:value string." ;
] ;
sh:property [
sh:path as:inReplyTo ;
sh:name "in reply to" ;
sh:nodeKind sh:IRI ;
sh:maxCount 1 ;
] ;
sh:property [
sh:path cito:citesAsEvidence ;
sh:name "cites as evidence" ;
sh:nodeKind sh:IRI ;
] .
nash:QuestionStance a sh:NodeShape ;
rdfs:label "Question stance (non-affirmative)" ;
sh:targetClass schema:Question ;
sh:property [
sh:path cito:supports ;
sh:maxCount 0 ;
sh:message "A question must not take an affirmative stance (cito:supports); that would be an assertion." ;
] ;
sh:property [
sh:path cito:agreesWith ;
sh:maxCount 0 ;
sh:message "A question must not take an affirmative stance (cito:agreesWith); that would be an assertion." ;
] ;
sh:property [
sh:path cito:extends ;
sh:maxCount 0 ;
sh:message "A question must not take an affirmative stance (cito:extends); that would be an assertion." ;
] ;
sh:property [
sh:path cito:confirms ;
sh:maxCount 0 ;
sh:message "A question must not take an affirmative stance (cito:confirms); that would be an assertion." ;
] .
nash:Evidence a sh:NodeShape ;
rdfs:label "Evidence finding" ;
sh:targetClass sio:SIO_001394 ; # SIO "evidence"
sh:property [
sh:path rdf:value ;
sh:name "finding text" ;
sh:datatype xsd:string ;
sh:minCount 1 ;
sh:maxCount 1 ;
sh:message "An evidence finding needs exactly one rdf:value string." ;
] .
# The Web Annotation layer (oa:Annotation, oa:SpecificResource, oa:TextQuoteSelector)
# is validated against the W3C Web Annotation model and its test suite, not
# re-specified here. Nanoarguments-specific annotation shapes may be added later.
nash:AssertionProvenance a sh:NodeShape ;
rdfs:label "Assertion provenance" ;
sh:targetObjectsOf np:hasAssertion ;
sh:property [
sh:path prov:wasAttributedTo ;
sh:name "attributed to" ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
sh:message "The assertion needs prov:wasAttributedTo an agent." ;
] ;
sh:property [
sh:path prov:wasDerivedFrom ;
sh:name "derived from" ;
sh:nodeKind sh:IRI ;
] .
nash:Nanopublication a sh:NodeShape ;
rdfs:label "Nanopublication pubinfo" ;
sh:targetClass np:Nanopublication ;
sh:property [
sh:path dct:creator ;
sh:name "creator" ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
sh:message "The nanopublication needs a dct:creator." ;
] ;
sh:property [
sh:path dct:license ;
sh:name "license" ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
sh:message "The nanopublication needs a dct:license." ;
] ;
sh:property [
sh:path dct:created ;
sh:name "created" ;
sh:datatype xsd:dateTime ;
sh:minCount 1 ;
sh:severity sh:Warning ;
sh:message "The nanopublication has no dct:created timestamp." ;
] .
Canonical: shapes/conformance.shacl.ttl
Running the shapes (Python example)
Two of the shapes (AssertionProvenance, Nanopublication) read across a
nanopublication's four graphs, so validate the whole nanopublication, not a single extracted graph. The example
below uses Python (pySHACL and the
nanopub library); np.rdf holds all four
graphs, which pySHACL reads across.
import pyshacl
# np.rdf, from the nanopub Python library, holds all four of the nanopub's graphs
conforms, report_graph, report_text = pyshacl.validate(
np.rdf, shacl_graph="shapes/conformance.shacl.ttl")
A runnable end-to-end example, with a passing and a failing nanopublication, is in
notebooks/validation.ipynb.