Semantica Ontology Validator Architecture: How SHACL Enforcement and Structural Validation Work
Semantica's ontology validator separates structural checks, symbolic reasoning, and SHACL constraint enforcement through a layered architecture centered in semantica/ontology/ontology_validator.py.
Semantica is an open-source AGI framework that generates and validates OWL ontologies programmatically. Understanding its ontology validator and SHACL enforcement internals helps developers debug constraint violations, extend validation logic, and integrate semantic checks into automated pipelines. This article breaks down the implementation as found in the semantica-agi/semantica repository.
Core Data Models: SHACLViolation and SHACLValidationReport
The foundation of SHACL enforcement rests on two dataclasses that model validation outcomes.
SHACLViolation
Each constraint failure becomes a SHACLViolation object with the following fields as defined in ontology_validator.py:
focus_node– the RDF resource that failed validationresult_path– the property path where the violation occurredconstraint– the constraint type that was violatedseverity–sh:Violation,sh:Warning, orsh:Infomessage– the human-readable violation messagevalue– the actual value that caused the violationshape– the SHACL shape that triggered the check
Crucially, the dataclass also stores concrete constraint parameters extracted from the source shape: min_count, max_count, datatype, and class_. This enrichment enables precise, context-aware error reporting that goes beyond generic SHACL messages.
SHACLValidationReport
The SHACLValidationReport aggregates individual violations into a complete validation result:
| Property | Type | Purpose |
|---|---|---|
conforms |
bool |
Whether the data graph satisfies all shapes |
violations |
List[SHACLViolation] |
Critical constraint failures |
warnings |
List[SHACLViolation] |
Non-critical issues (severity sh:Warning) |
infos |
List[SHACLViolation] |
Informational notes |
violation_count |
int |
Computed property for quick status checks |
warning_count |
int |
Computed property for quick status checks |
The report provides three key methods:
summary()– high-level status overviewexplain_violations()– generates plain-English explanations using the enriched constraint parametersto_dict()– serializes the entire report for API responses or logging
The SHACL Engine: _run_pyshacl Function
All SHACL validation flows through _run_pyshacl() in semantica/ontology/ontology_validator.py. This function implements a five-step pipeline:
- Parse graphs using rdflib – loads both the data graph (ontology instance) and the shapes graph (SHACL constraints)
- Execute validation via pyshacl – internally invokes the Jena SHACL validator through Python bindings
- Walk result graph – traverses
sh:ValidationResultnodes in the pyshacl output - Extract constraint parameters – pulls values like
sh:minCount,sh:datatypefromsh:sourceShapeto populateSHACLViolationfields - Build report – constructs and returns a
SHACLValidationReport
The function runs with abort_on_first=False and no inference, ensuring complete violation discovery without side effects on the input data.
OntologyValidator: The Public Orchestration Layer
The OntologyValidator class serves as the primary entry point for Semantica's validation pipeline. It coordinates three distinct validation modes.
Constructor Configuration
OntologyValidator(
reasoner='hermit', # 'hermit', 'pellet', or 'auto'
check_consistency=True, # Run symbolic consistency check
check_satisfiability=True, # Check class satisfiability
**kwargs # Additional reasoner options
)
The validator supports pluggable reasoners through an auto-selector mechanism, with HermiT and Pellet as built-in options.
Validation Dispatch
The validate(ontology) method accepts either:
- A Python dictionary with
classesandpropertieskeys - A path to an OWL file (loaded and parsed internally)
It returns a ValidationResult with flags for valid, consistent, and satisfiable, plus collected errors and warnings.
Structural Integrity Checks
The _validate_structure(ontology, result) method enforces minimal ontology requirements:
def _validate_structure(self, ontology, result):
if 'classes' not in ontology:
result.warnings.append("Missing 'classes' section")
if 'properties' not in ontology:
result.warnings.append("Missing 'properties' section")
Missing sections generate warnings but do not halt validation, allowing partial ontologies to pass through with annotations.
Extensibility Hooks
The check_constraint(constraint) method provides a placeholder for ad-hoc SPARQL-based validation rules, enabling domain-specific constraints beyond standard SHACL.
Complete Validation Workflow
Understanding how components interact clarifies integration points:
- Entry – CLI or
engine.pycallsvalidate_ontology()convenience wrapper - Instantiation – Creates
OntologyValidatorwith configured reasoner - Structure check –
_validate_structure()verifies required dictionary keys - Symbolic reasoning – Optional consistency and satisfiability checks (HermiT/Pellet)
- SHACL enforcement – If shapes provided,
_run_pyshacl()executes constraint validation - Assembly –
validate_ontology()returns serializable dictionary for downstream consumption
Key Source Files
| File | Responsibility |
|---|---|
semantica/ontology/ontology_validator.py |
Core validator, SHACL runner, all data models |
semantica/ontology/ontology_generator.py |
Injects OntologyValidator for generation-time sanity checks |
semantica/ontology/engine.py |
Workflow orchestration that can trigger SHACL validation |
semantica/ontology/__init__.py |
Public API exports (OntologyValidator, validate_ontology) |
Practical Usage Examples
Basic Structural Validation
from semantica.ontology import OntologyValidator
validator = OntologyValidator()
result = validator.validate({"classes": [], "properties": []})
print(result.valid) # True
print(result.warnings) # [] (no missing sections)
Full SHACL Enforcement with Violation Analysis
from semantica.ontology import _run_pyshacl
# data_ttl: ontology serialized as Turtle
# shacl_ttl: SHACL shapes defining constraints
report = _run_pyshacl(data_ttl, shacl_ttl)
print(f"Conforms: {report.conforms}")
print(f"Violations: {report.violation_count}")
# Generate human-readable explanations
report.explain_violations()
for v in report.violations:
print(f"- {v.message} (expected {v.min_count}, found value {v.value})")
# Export for API response
json_report = report.to_dict()
Summary
- Semantica ontology validator implements three-layer architecture: data models (
SHACLViolation,SHACLValidationReport), execution engine (_run_pyshacl), and orchestration (OntologyValidator) - SHACL enforcement relies on pyshacl wrapping Jena, with rdflib for graph parsing and enriched violation reporting through source shape introspection
- Structural validation guarantees minimum ontology completeness without blocking on warnings
- Symbolic reasoning integrates HermiT and Pellet via configurable reasoner selection
- Extension points include SPARQL-based constraint hooks and custom severity handling
Frequently Asked Questions
How does Semantica extract detailed constraint parameters from SHACL violations?
The _run_pyshacl() function traverses the sh:sourceShape of each sh:ValidationResult and extracts concrete values like sh:minCount, sh:maxCount, sh:datatype, and sh:class. These populate the SHACLViolation dataclass fields, enabling explain_violations() to generate messages like "expected at least 1 value, found 0" rather than generic failure notices.
Can I use the validator without SHACL shapes?
Yes. The OntologyValidator performs structural checks and optional symbolic reasoning independently. Simply omit SHACL shape graphs when calling validation methods. The validate() method is designed to be modular—SHACL enforcement is an optional downstream step, not a hard dependency.
What reasoners does Semantica support for ontology consistency checking?
The validator accepts 'hermit', 'pellet', or 'auto' as reasoner parameter values. HermiT serves as the default. The implementation预留s extension points for owlready2 integration, though the current codebase focuses on these two established reasoners for OWL-DL consistency and satisfiability analysis.
Where does SHACL validation fit in the Semantica generation pipeline?
The OntologyGenerator class in ontology_generator.py instantiates OntologyValidator for generation-time sanity checks. For full constraint enforcement, engine.py workflows can invoke _run_pyshacl() directly after ontology serialization, ensuring shaped compliance before downstream consumption.
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 →