SHACL Validation and OWL Generation in Semantica: Technical Implementation Guide
Semantica's ontology subsystem provides integrated SHACL validation through the OntologyValidator class and flexible OWL generation via OWLGenerator, enabling automated structural validation and RDF serialization with optional rdflib integration and string-templating fallbacks.
The semantica-agi/semantica repository implements a comprehensive ontology management system that bridges raw Python data structures with semantic web standards. This article examines how the library handles SHACL validation and OWL generation through dedicated modules that parse, validate, and serialize ontology structures using intermediate dictionary representations.
SHACL Validation Architecture
The validation layer enforces structural constraints on ontology graphs using the W3C SHACL standard.
Building RDF and SHACL Graphs
In semantica/ontology/ontology_validator.py, the OntologyValidator class orchestrates the validation workflow. The _run_pyshacl method (lines 48‑73) uses rdflib to parse both the data graph (your ontology instance) and the shapes graph (constraint definitions).
You can supply custom SHACL shapes or rely on the internal SHACLGenerator class to derive constraints automatically from the ontology schema. The validator loads graphs via rdflib.Graph().parse and invokes pyshacl.validate to execute the conformance check.
Parsing Validation Results
Result extraction occurs in lines 106‑141, where the engine iterates over results_graph.subjects(SH.ValidationResult) to identify violations. For each result, the parser extracts:
- Focus node and path (the specific property or individual in violation)
- Severity level (violation, warning, or info)
- Human-readable message and offending value
Lines 150‑165 fetch real constraint parameters—such as minCount, maxCount, datatype, and class—from the shapes graph to enrich the violation context.
Structured Violation Reports
The SHACLValidationReport class (lines 60‑77) aggregates validation outcomes into three categorized lists:
violations: Critical constraint failureswarnings: Non-critical issuesinfos: Advisory notices
Each entry is a SHACLViolation object containing structured metadata. The explain_violations method (lines 82‑123) generates templated English explanations—such as "Node is missing required property "—populating the explanation field for human-readable output.
For convenience, the validate_ontology() function (lines 269‑288) wraps instantiation and execution, returning a plain dictionary summarizing validity, consistency, satisfiability, and collected messages.
OWL Generation Pipeline
The OWL module transforms Python ontology dictionaries into standard RDF serializations.
Rdflib Integration and Fallback Mechanisms
The OWLGenerator class in semantica/ontology/owl_generator.py detects rdflib availability at import time using the HAS_RDFLIB flag (lines 39‑46). If rdflib is absent, the module logs a warning (lines 90‑94) and falls back to lightweight string templating.
The generator provides two implementation paths:
_generate_with_rdflib(lines 110‑180): Full-featured graph construction using rdflib’sGraphAPI_generate_basic(lines 300‑375): Pure Python string concatenation producing valid Turtle syntax
Namespace and IRI Management
The _get_generation_namespace_manager method (lines 77‑86) constructs a NamespaceManager anchored to the ontology’s base URI. This manager mints IRIs via generate_class_iri and generate_property_iri, ensuring consistent identifier generation across both OWL and SHACL generation workflows.
Class and Property Emission
When using rdflib, the generator emits standard OWL/RDFS triples:
- Classes:
rdf:type owl:Class, optionalrdfs:label,rdfs:comment, andrdfs:subClassOfrelationships - Object Properties:
rdf:type owl:ObjectPropertywithrdfs:domainandrdfs:range - Datatype Properties:
rdf:type owl:DatatypePropertylinked to XSD or custom datatypes
The fallback implementation reproduces these triples using deterministic string formatting for environments without heavy dependencies.
Serialization and Export
The generate_owl method supports multiple RDF formats: Turtle, RDF/XML, JSON-LD, N-Triples, and N3. It returns either a serialized string or an rdflib.Graph object (lines 218‑229) depending on the format parameter.
For file output, export_owl (lines 315‑362) handles directory creation via ensure_directory and writes the serialized content to disk, making it suitable for build pipelines or deployment workflows.
Integration in the Generation Pipeline
The high-level OntologyGenerator class (in semantica/ontology/ontology_generator.py) orchestrates a six-stage pipeline that concludes with validation. At lines 197‑210, after constructing class and property structures, it invokes:
validation_result = self.validator.validate(ontology)
ontology["validation"] = {
"valid": validation_result.valid,
"consistent": validation_result.consistent,
"satisfiable": validation_result.satisfiable,
"errors": validation_result.errors,
"warnings": validation_result.warnings,
}
This ensures every generated ontology undergoes both SHACL structural validation and symbolic consistency checking (via HermiT/Pellet placeholders) before export to downstream formats.
Practical Code Examples
Validating an Ontology with SHACL
from semantica.ontology import OntologyValidator
my_ontology = {
"uri": "https://example.org/ontology/",
"classes": [{"name": "Person", "uri": "https://example.org/ontology/Person"}],
"properties": [
{
"name": "age",
"type": "datatype",
"range": "xsd:integer",
"domain": ["Person"],
"required": True,
}
],
}
validator = OntologyValidator()
report = validator.validate(my_ontology)
# Access structured violations
print(report.summary())
report.explain_violations()
for v in report.violations:
print(v.explanation)
Generating OWL Turtle Output
from semantica.ontology import OWLGenerator
owl_gen = OWLGenerator()
# Generate Turtle string
turtle_str = owl_gen.generate_owl(my_ontology, format="turtle")
# Or obtain rdflib Graph for manipulation
g = owl_gen.generate_owl(my_ontology) # Returns Graph object
g.serialize(destination="ontology.ttl", format="turtle")
Complete Pipeline: Generation to Export
from semantica.ontology import OntologyGenerator, OWLGenerator
# 1. Generate from raw data
generator = OntologyGenerator(base_uri="https://example.org/ontology/")
raw_data = {
"entities": [{"type": "Person", "name": "Alice"}],
"relationships": [{"type": "hasFriend", "source": "Alice", "target": "Bob"}],
}
ontology = generator.generate_ontology(raw_data)
# 2. Validate (SHACL + symbolic)
validation = generator.validator.validate(ontology)
print("Valid?", validation.valid)
# 3. Export OWL
owl_gen = OWLGenerator()
owl_gen.export_owl(ontology, "output/ontology.ttl")
Summary
-
SHACL validation occurs in
ontology_validator.pyusingOntologyValidator, which leveragespyshacland rdflib to check conformance against shapes graphs, producing structuredSHACLValidationReportobjects with human-readable explanations. -
OWL generation is handled by
OWLGeneratorinowl_generator.py, which supports multiple RDF serialization formats through rdflib or a lightweight string-templating fallback when dependencies are unavailable. -
Namespace management is centralized via
_get_generation_namespace_manager, ensuring consistent IRI generation for both validation and export workflows. -
Pipeline integration means every ontology created through
OntologyGeneratorautomatically undergoes SHACL validation and consistency checking before serialization, ensuring quality at the point of generation.
Frequently Asked Questions
How does Semantica handle missing rdflib dependencies?
When rdflib is not installed, OWLGenerator detects this via the HAS_RDFLIB flag (lines 39‑46 of owl_generator.py) and routes execution to _generate_basic (lines 300‑375), which constructs valid Turtle syntax through string concatenation rather than graph manipulation.
What specific constraint parameters does SHACL validation extract?
According to lines 150‑165 of ontology_validator.py, the validator extracts real constraint parameters including minCount, maxCount, datatype, and class from the shapes graph to populate SHACLViolation objects with detailed context for error messages.
Can I validate an ontology without generating OWL output?
Yes. The OntologyValidator class operates independently of the OWLGenerator. You can instantiate OntologyValidator directly and call validate() or _run_pyshacl() on any ontology dictionary conforming to the expected schema, without triggering RDF serialization.
What serialization formats does the OWL generator support?
As implemented in lines 218‑229 of owl_generator.py, the generator supports Turtle, RDF/XML, JSON-LD, N-Triples, and N3 formats. The export_owl method handles file I/O and directory creation automatically.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →