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 validation
  • result_path – the property path where the violation occurred
  • constraint – the constraint type that was violated
  • severity – sh:Violation, sh:Warning, or sh:Info
  • message – the human-readable violation message
  • value – the actual value that caused the violation
  • shape – 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 overview
  • explain_violations() – generates plain-English explanations using the enriched constraint parameters
  • to_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:

  1. Parse graphs using rdflib – loads both the data graph (ontology instance) and the shapes graph (SHACL constraints)
  2. Execute validation via pyshacl – internally invokes the Jena SHACL validator through Python bindings
  3. Walk result graph – traverses sh:ValidationResult nodes in the pyshacl output
  4. Extract constraint parameters – pulls values like sh:minCount, sh:datatype from sh:sourceShape to populate SHACLViolation fields
  5. 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 classes and properties keys
  • 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:

  1. Entry – CLI or engine.py calls validate_ontology() convenience wrapper
  2. Instantiation – Creates OntologyValidator with configured reasoner
  3. Structure check – _validate_structure() verifies required dictionary keys
  4. Symbolic reasoning – Optional consistency and satisfiability checks (HermiT/Pellet)
  5. SHACL enforcement – If shapes provided, _run_pyshacl() executes constraint validation
  6. 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →