Semantic_Knowledge_Graph_Validation_Starter_Pack - mdebellis/SemanticKG-Design GitHub Wiki
Semantic Knowledge Graph Validation Starter Pack
This document defines a practical validation architecture for Semantic Knowledge Graph (SKG) development using:
- OWL for semantics and inference
- SHACL for conformance and validation
- SPARQL for diagnostics and auditing
This approach is designed for real-world engineering workflows, balancing rigor, usability, and interoperability.
1. Validation Architecture Overview
OWL → Semantic Meaning and Inference
Use OWL for:
- Class hierarchies
- Property hierarchies
- Domain and range (when semantically justified)
owl:inverseOf- Property characteristics (transitive, symmetric, functional)
- Disjointness
- Logical restrictions
Guideline: Use OWL to represent what is true about the domain, not what is merely desirable in data.
SHACL → Conformance and Engineering Rules
Use SHACL for:
- Required properties
- Cardinality constraints
- Datatype validation
- Structural expectations
- Data quality rules
- Warning vs. violation severity
Guideline: Use SHACL to enforce what data should look like in your system.
SPARQL → Diagnostics and Auditing
Use SPARQL for:
- Debugging
- Data inspection
- Detecting anomalies
- Ontology hygiene checks
- Cross-cutting analysis
- Portable validation
Guideline: Use SPARQL to find what looks wrong or suspicious.
2. SHACL Starter Pack
Prefixes
@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 owl: <http://www.w3.org/2002/07/owl#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dcat: <http://www.w3.org/ns/dcat#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix dp: <https://www.michaeldebellis.com/dp/> .
@prefix sf: <https://www.michaeldebellis.com/sf/> .
# A. Class Metadata Shape
dp:Class_Metadata_Shape
a sh:NodeShape ;
sh:targetClass owl:Class ;
sh:property [
sh:path rdfs:label ;
sh:minCount 1 ;
sh:severity sh:Warning ;
sh:message "Each class should have an rdfs:label."@en ;
] ;
sh:property [
sh:path skos:definition ;
sh:minCount 1 ;
sh:severity sh:Warning ;
sh:message "Each class should have a skos:definition."@en ;
] .
# B. Property Metadata Shape
dp:Property_Metadata_Shape
a sh:NodeShape ;
sh:targetClass owl:ObjectProperty ;
sh:property [
sh:path rdfs:label ;
sh:minCount 1 ;
sh:severity sh:Warning ;
] ;
sh:property [
sh:path skos:definition ;
sh:minCount 1 ;
sh:severity sh:Warning ;
] .
# (Repeat for DatatypeProperty and AnnotationProperty if needed)
# C. Dataset Must Have Label
dp:Dataset_Label_Shape
a sh:NodeShape ;
sh:targetClass dcat:Dataset ;
sh:property [
sh:path rdfs:label ;
sh:minCount 1 ;
sh:severity sh:Violation ;
] .
# D. Dataset Should Have Distribution
dp:Dataset_Distribution_Shape
a sh:NodeShape ;
sh:targetClass dcat:Dataset ;
sh:property [
sh:path dcat:distribution ;
sh:minCount 1 ;
sh:severity sh:Warning ;
] .
# E. Integer Datatype Example
dp:Row_Count_Shape
a sh:NodeShape ;
sh:targetSubjectsOf dp:row_count ;
sh:property [
sh:path dp:row_count ;
sh:datatype xsd:integer ;
sh:maxCount 1 ;
sh:severity sh:Violation ;
] .
# F. DateTime Datatype Example
dp:Created_At_Shape
a sh:NodeShape ;
sh:targetSubjectsOf dp:created_at ;
sh:property [
sh:path dp:created_at ;
sh:datatype xsd:dateTime ;
sh:severity sh:Violation ;
] .
# G. URI Datatype Example
dp:Access_URL_Shape
a sh:NodeShape ;
sh:targetSubjectsOf dp:access_url ;
sh:property [
sh:path dp:access_url ;
sh:datatype xsd:anyURI ;
sh:severity sh:Violation ;
] .
# H. Object Properties Should Have Inverses
dp:Object_Property_Inverse_Shape
a sh:NodeShape ;
sh:targetClass owl:ObjectProperty ;
sh:property [
sh:path owl:inverseOf ;
sh:minCount 1 ;
sh:severity sh:Warning ;
] .
# I. Activity Must Have Associated Agent
dp:Activity_Association_Shape
a sh:NodeShape ;
sh:targetClass prov:Activity ;
sh:property [
sh:path prov:wasAssociatedWith ;
sh:minCount 1 ;
sh:severity sh:Warning ;
] .
# 3. SPARQL Audit Pack
# A. Undeclared Properties
SELECT DISTINCT ?p
WHERE {
?s ?p ?o .
FILTER(isIRI(?p))
FILTER NOT EXISTS { ?p a owl:ObjectProperty }
FILTER NOT EXISTS { ?p a owl:DatatypeProperty }
FILTER NOT EXISTS { ?p a owl:AnnotationProperty }
}
ORDER BY ?p
# B. Undeclared Classes
SELECT DISTINCT ?class
WHERE {
?x a ?class .
FILTER(isIRI(?class))
FILTER NOT EXISTS { ?class a owl:Class }
}
ORDER BY ?class
# C. Classes Missing Labels
SELECT ?class
WHERE {
?class a owl:Class .
FILTER NOT EXISTS { ?class rdfs:label ?label }}
# D. Classes Missing Definitions
SELECT ?class
WHERE {
?class a owl:Class .
FILTER NOT EXISTS { ?class skos:definition ?def }}
# E. Properties Missing Definitions
SELECT ?property
WHERE {
?property a ?type .
FILTER(?type IN (owl:ObjectProperty, owl:DatatypeProperty))
FILTER NOT EXISTS { ?property skos:definition ?def }
}
# F. Object Properties Missing Inverses
SELECT ?property
WHERE {
?property a owl:ObjectProperty .
FILTER NOT EXISTS { ?property owl:inverseOf ?inv }
}
# G. Suspicious Annotation Property Usage
SELECT DISTINCT ?p
WHERE {
?s ?p ?o .
?p a owl:AnnotationProperty .
FILTER(isIRI(?o))
}
# H. Duplicate Labels
SELECT ?label (COUNT(?x) AS ?count)
WHERE {
?x rdfs:label ?label .
}
GROUP BY ?label
HAVING (COUNT(?x) > 1)
# I. Object Property Naming Violations
SELECT ?property
WHERE {
?property a owl:ObjectProperty .
BIND(REPLACE(STR(?property), '^.*[/#]', '') AS ?name)
FILTER(!STRSTARTS(?name, "has_") && !STRSTARTS(?name, "is_"))
}
# J. Datatype Properties Using "has_"
SELECT ?property
WHERE {
?property a owl:DatatypeProperty .
BIND(REPLACE(STR(?property), '^.*[/#]', '') AS ?name)
FILTER(STRSTARTS(?name, "has_"))
}```
# K. Entities Missing rdf:type
SELECT DISTINCT ?x
WHERE {
?x ?p ?o .
FILTER(isIRI(?x))
FILTER NOT EXISTS { ?x a ?t }}
4. Recommended Workflow
During Development Run SPARQL:
- undeclared properties
- naming issues
- duplicates
Before Merges / Snapshots Run SHACL:
- required metadata
- datatype checks
- cardinality
Before Release / Sharing Run BOTH:
- SHACL (conformance)
- SPARQL (hygiene)
5. Profiles (Optional but Recommended)
Development Profile
- permissive
- warnings instead of violations
- inverses required
Integration Profile
- tolerant of external data
- relaxed string/language constraints
Release Profile
- strict validation
- all metadata required
- no undeclared terms
6. Guiding Principle
- OWL for truth
- SHACL for quality gates
- SPARQL for investigation
7. Notes on Strings and Interoperability
Prefer flexibility over strict langString enforcement
Use SHACL (not OWL) for datatype rigor
Allow variation for integration scenarios
Enforce stricter rules only where needed