How Semantica Validates Ontology Rules Using SHACL: A Complete Technical Guide

Semantica validates ontology constraints by generating SHACL shapes from internal OWL-style representations and executing them against RDF data graphs using the pySHACL library.

The semantica-agi/semantica repository implements a comprehensive validation pipeline that bridges high-level ontology definitions with W3C-standardized constraint checking. By translating OWL-style class and property definitions into executable SHACL shapes, Semantica ensures that knowledge graph data conforms strictly to schema requirements before ingestion or processing.

Generating SHACL Shapes from OWL Ontologies

At the core of Semantica’s validation system is the SHACLGenerator class located in semantica/ontology/ontology_generator.py. This component transforms dictionary-based ontology definitions into executable SHACL graphs through a structured six-stage pipeline.

The Six-Stage Transformation Pipeline

The generator processes ontology dictionaries through six distinct stages to produce valid SHACL shapes:

  1. Class indexing – Builds an internal index of all OWL classes defined in the ontology
  2. Node shape creation – Generates sh:NodeShape instances for each class
  3. Property shape synthesis – Creates sh:PropertyShape definitions mapping OWL properties to SHACL constraints
  4. Inheritance propagation – Propagates constraints through class hierarchies (subclass relationships)
  5. Quality-tier handling – Applies validation strictness levels based on configuration
  6. Serialization preparation – Finalizes the graph structure for export

Target Namespace Resolution

A critical feature of the generator is its handling of the target namespace. The _resolve_target_namespace method ensures that generated shapes reference the actual data vocabulary rather than the shapes’ own namespace. This prevents the common pitfall where sh:targetClass and sh:path IRIs incorrectly point to the ontology definition namespace instead of the instance data namespace.

The constructor accepts a target_namespace parameter that directs all generated constraints to validate against the correct URI space:

gen = SHACLGenerator(target_namespace="https://example.org/onto#")

Quality Tiers and Domain Constraints

Semantica supports three validation quality tiers: strict, standard, and basic. These tiers control the severity and comprehensiveness of generated constraints, allowing developers to balance validation thoroughness against performance requirements.

The generator also protects against the "domain-less property" anti-pattern. As verified in tests/ontology/test_shacl_target_namespace.py, the logic ensures that properties without explicit domain declarations are not automatically asserted on every class in the ontology. This prevents spurious validation failures when optional properties appear only on specific instances.

Serializing SHACL Shapes for Distribution

Once generated, the SHACLGraph can be serialized using the serialize method, which supports multiple RDF formats:

  • Turtle – Human-readable syntax suitable for version control
  • JSON-LD – JavaScript-friendly format for web APIs
  • N-Triples – Line-based format for streaming processing

This serialization capability allows generated shapes to be persisted, versioned, or transmitted to external validation services that conform to the SHACL standard.

Executing SHACL Validation with pySHACL

The actual validation logic resides in semantica/ontology/ontology_validator.py, specifically within the run_shacl_validation function. This component orchestrates the execution of generated shapes against instance data.

The Validation Pipeline

The validation process follows a strict execution flow:

  1. Graph parsing – Uses rdflib to parse both the data graph (containing instances) and the SHACL graph (containing constraints) into memory
  2. Constraint execution – Invokes pyshacl.validate with inference="none" and abort_on_first=False to check all constraints without OWL reasoning and without stopping at the first violation
  3. Result capture – Collects the boolean conforms flag, results graph, and textual report into a structured object

Structured Violation Reports

Validation results are encapsulated in the SHACLValidationReport dataclass, which contains:

  • Boolean conformance status – True only if all constraints pass
  • Violation list – SHACLViolation objects detailing each breach
  • Warning and info lists – Non-fatal constraint feedback
  • Explanation methods – explain_violations() generates human-readable descriptions of failures

Each SHACLViolation records specific metadata including the focus node (the failing resource), result path (the problematic property), constraint type, and severity level.

Practical Example: Validating RDF Data Against Generated Shapes

The following implementation demonstrates the complete workflow from ontology definition through violation detection:

from semantica.ontology.ontology_generator import SHACLGenerator
from semantica.ontology.ontology_validator import run_shacl_validation

# Define OWL-style ontology structure

ontology = {
    "classes": [{"name": "Person", "uri": "https://example.org/onto#Person"}],
    "properties": [
        {"name": "fullName", "type": "datatype", "range": "string",
         "domain": "Person", "required": True}
    ],
    "namespace": {"base_uri": "https://example.org/onto#"},
}

# Generate SHACL shapes targeting the data namespace

gen = SHACLGenerator(target_namespace="https://example.org/onto#")
shacl_graph = gen.generate(ontology)
shacl_ttl = gen.serialize(shacl_graph, format="turtle")

# Create data graph with intentional violation (missing required property)

data_ttl = """
@prefix ex: <https://example.org/onto#> .
ex:alice a ex:Person .
"""

# Execute validation

report = run_shacl_validation(
    data_graph_str=data_ttl,
    shacl_str=shacl_ttl,
    data_graph_format="turtle",
    shacl_format="turtle"
)

# Process results

print(f"Conforms: {report.conforms}")  # False

print(f"Violations: {report.violation_count}")  # 1

# Generate human-readable explanations

report.explain_violations()
for violation in report.violations:
    print(violation.explanation)

This example creates a Person class with a required fullName property, then validates instance data missing that property. The resulting SHACLValidationReport correctly identifies the constraint breach and provides detailed metadata about the missing required field.

Test Coverage and Validation Assurance

The implementation is verified by comprehensive test suites in tests/ontology/test_shacl_target_namespace.py and tests/ontology/test_ontology_comprehensive.py. These tests validate that:

  • Generated shapes correctly target the instance namespace rather than the ontology namespace
  • Domain-less properties do not propagate to unrelated classes
  • Real constraint violations are detected and reported with accurate focus nodes and paths
  • Quality tiers correctly modulate constraint severity

Summary

Semantica implements ontology validation through a bidirectional pipeline that converts OWL definitions into executable SHACL constraints:

  • Shape generation occurs in semantica/ontology/ontology_generator.py via the SHACLGenerator class, which executes a six-stage pipeline supporting namespace resolution and quality tiers
  • Validation execution is handled by run_shacl_validation in semantica/ontology/ontology_validator.py, wrapping the pySHACL library to provide structured reporting
  • Result interpretation uses the SHACLValidationReport dataclass to provide both machine-parseable violation data and human-readable explanations
  • Correctness verification is maintained through targeted tests ensuring namespace accuracy and constraint precision

Frequently Asked Questions

What is SHACL and why does Semantica use it for ontology validation?

SHACL (Shapes Constraint Language) is a W3C standard for validating RDF graphs against a set of conditions specified via shapes. Semantica uses SHACL because it provides a standardized, declarative mechanism to enforce ontology constraints without requiring OWL reasoning engines, making validation faster and more predictable. The pySHACL implementation allows Semantica to check complex cardinality, datatype, and range constraints against instance data efficiently.

How does Semantica handle namespace conflicts when generating SHACL shapes?

Semantica resolves namespace conflicts through the target_namespace parameter in SHACLGenerator. The logic in _resolve_target_namespace ensures that generated sh:targetClass and sh:path IRIs reference the data vocabulary namespace (where instances live) rather than the shapes' own namespace. This prevents validation shapes from targeting the wrong URI space, a common error when ontology definitions and instance data use different base URIs.

What validation quality tiers does Semantica support?

Semantica supports three quality tiers: strict, standard, and basic. These tiers control the severity and comprehensiveness of generated SHACL constraints. The strict tier enforces all ontology constraints including optional recommendations as violations, while basic may relax certain cardinality or datatype checks for performance-critical applications. This allows developers to balance validation thoroughness against computational overhead.

How are SHACL validation violations reported in Semantica?

Violations are reported through the SHACLValidationReport dataclass returned by run_shacl_validation. Each violation is represented as a SHACLViolation object containing the focus node (the failing resource), result path (the property in violation), constraint component, and severity level. The report provides both machine-readable structured data and human-readable explanations via the explain_violations() method, which converts technical constraint failures into plain-language descriptions suitable for debugging and user interfaces.

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 →