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

> Learn how Semantica validates ontology rules with SHACL. Discover the process of generating SHACL shapes from OWL and executing them against RDF data using pySHACL for robust validation.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-09-12

---

**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`](https://github.com/semantica-agi/semantica/blob/main/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:

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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:

```python
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`](https://github.com/semantica-agi/semantica/blob/main/tests/ontology/test_shacl_target_namespace.py) and [`tests/ontology/test_ontology_comprehensive.py`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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.