Summary
Generate a SHACL shape from a nanopublication template, so that nanopublications created from that template can be validated by any standard SHACL engine (rdf4j-shacl, pySHACL, TopBraid …) — independently of nanodash, and producing a standard sh:ValidationReport.
This is Part B of the design doc docs/shacl-alignment.md.
Is it structurally possible?
Yes — as a lossy projection over a well-defined subset, not an isomorphism. The generative-vs-descriptive mismatch is not the blocker for validation export (validation never needs SHACL to construct anything). The existing inward bridge (Template.processShaclTemplate()) already delineates the exportable subset — this is essentially that correspondence table run backwards.
Projects faithfully into core SHACL (most production templates)
- Fixed-subject, fixed-predicate, placeholder-object triples →
sh:PropertyShape.
- Fixed triples (constant S/P/O) →
sh:hasValue / sh:targetClass.
- Optional / required / repeatable →
sh:minCount / sh:maxCount.
- Inline restricted choice →
sh:in.
- A placeholder reused as the subject of several triples → property shapes on the same NodeShape; anchored groups →
sh:node / sh:qualifiedValueShape.
Needs SHACL-AF (sh:sparql) — possible but non-core
- Predicate-position placeholders (
?s ?relation ?o): sh:path cannot be a variable.
- Arbitrary cross-placeholder value-equality joins (beyond
sh:equals).
- Live value sources (
nt:possibleValuesFromApi): snapshot into sh:in, or SPARQL target.
Dropped (not data-validity concerns)
nt:hasNanopubLabelPattern, nt:hasTag, nt:AdvancedStatement, minting roles, nt:hasDefaultProvenance, nt:hasRequiredPubinfoElement.
Semantic caveats
- Looser than generation. SHACL (open-world) only checks required triples are present and constraints hold; it does not reject extra triples. A generated shape means "conformant to the template's constraints," not "produced by template T" (the latter is the
nt:wasCreatedFromTemplate pubinfo triple).
- Targetability varies.
sh:targetClass works when the template introduces a typed resource; otherwise fall back to sh:targetSubjectsOf/sh:targetObjectsOf. sh:targetNode is unusable (minted IRI unknown in advance).
Suggested scope
Document each generated shape as a validation projection, not a round-trip. Suggest shipping core-only shapes first (drop the SPARQL-needing constructs and log what was dropped), add SHACL-AF later. Consider publishing shapes as nanopublications keyed via dct:isVersionOf / nt:wasCreatedFromTemplate.
See docs/shacl-alignment.md for the full design.
Summary
Generate a SHACL shape from a nanopublication template, so that nanopublications created from that template can be validated by any standard SHACL engine (rdf4j-shacl, pySHACL, TopBraid …) — independently of nanodash, and producing a standard
sh:ValidationReport.This is Part B of the design doc
docs/shacl-alignment.md.Is it structurally possible?
Yes — as a lossy projection over a well-defined subset, not an isomorphism. The generative-vs-descriptive mismatch is not the blocker for validation export (validation never needs SHACL to construct anything). The existing inward bridge (
Template.processShaclTemplate()) already delineates the exportable subset — this is essentially that correspondence table run backwards.Projects faithfully into core SHACL (most production templates)
sh:PropertyShape.sh:hasValue/sh:targetClass.sh:minCount/sh:maxCount.sh:in.sh:node/sh:qualifiedValueShape.Needs SHACL-AF (
sh:sparql) — possible but non-core?s ?relation ?o):sh:pathcannot be a variable.sh:equals).nt:possibleValuesFromApi): snapshot intosh:in, or SPARQL target.Dropped (not data-validity concerns)
nt:hasNanopubLabelPattern,nt:hasTag,nt:AdvancedStatement, minting roles,nt:hasDefaultProvenance,nt:hasRequiredPubinfoElement.Semantic caveats
nt:wasCreatedFromTemplatepubinfo triple).sh:targetClassworks when the template introduces a typed resource; otherwise fall back tosh:targetSubjectsOf/sh:targetObjectsOf.sh:targetNodeis unusable (minted IRI unknown in advance).Suggested scope
Document each generated shape as a validation projection, not a round-trip. Suggest shipping core-only shapes first (drop the SPARQL-needing constructs and log what was dropped), add SHACL-AF later. Consider publishing shapes as nanopublications keyed via
dct:isVersionOf/nt:wasCreatedFromTemplate.See
docs/shacl-alignment.mdfor the full design.