OWL Generation vs SHACL Validation in Semantica's Ontology Module

Semantica integrates SHACL validation and OWL generation into a unified six-stage pipeline, using OntologyValidator to enforce structural constraints via pySHACL before OWLGenerator serializes valid ontologies to Turtle, RDF/XML, or JSON-LD formats.

Semantica's ontology subsystem provides complementary capabilities for OWL generation vs SHACL validation, enabling developers to construct standards-compliant RDF graphs while verifying their structural integrity against defined shapes. The implementation spans three core modules in the semantica/ontology package—ontology_validator.py, owl_generator.py, and ontology_generator.py—each handling distinct phases of the ontology lifecycle from raw data to validated semantic output.

SHACL Validation Architecture

The validation subsystem centers on the OntologyValidator class in semantica/ontology/ontology_validator.py, which orchestrates structural constraint checking through a multi-step workflow involving rdflib parsing, pySHACL execution, and structured report generation.

Parsing and Execution Flow

The private method _run_pyshacl (lines 48-73) handles the core validation logic by loading data graphs and SHACL shapes into rdflib Graph objects. When pyshacl.validate executes, the validator processes results through a structured extraction loop (lines 106-141) that iterates over SH.ValidationResult subjects to identify specific constraint violations.

This extraction captures critical metadata including focus nodes, property paths, severity levels, violation messages, and source constraint components. The system additionally fetches real constraint parameters—such as minCount, maxCount, datatype, and class—from the shape graph (lines 150-165) to populate human-readable explanations in violation reports.

Structured Violation Reporting

Validation results aggregate into SHACLValidationReport (lines 60-77), which maintains boolean conforms status and three categorized lists of SHACLViolation objects: violations, warnings, and infos. The report's explain_violations method (lines 82-123) applies templated English messages to each violation, generating explanations like "Node is missing required property …" through string templates beginning at line 84.

For convenient access, the module-level function validate_ontology(ontology, method) (lines 269-288) instantiates OntologyValidator and returns a plain dictionary summarizing validity, consistency, satisfiability, and diagnostic messages.

OWL Generation Implementation

The OWLGenerator class in semantica/ontology/owl_generator.py transforms plain-Python ontology dictionaries into standard OWL/RDF serializations, implementing a dual-path generation strategy based on environment capabilities.

Rdflib Integration and Fallback Handling

At import time (lines 39-46), the module detects rdflib availability through the HAS_RDFLIB flag, logging warnings when the library is absent (lines 90-94). When rdflib is present, _generate_with_rdflib (lines 110-180) constructs an in-memory Graph, registers namespaces via _get_generation_namespace_manager (lines 77-86), and emits triples for ontology metadata, classes (owl:Class), subclasses (rdfs:subClassOf), and both object properties (owl:ObjectProperty) and datatype properties (owl:DatatypeProperty).

If rdflib is unavailable, the _generate_basic fallback (lines 300-375) produces equivalent Turtle syntax through string concatenation, ensuring functionality in lightweight environments without external dependencies.

Serialization and Export Functions

The public API exposes generate_owl and export_owl methods. The former returns either a serialized string or an rdflib.Graph object depending on the format parameter—supporting Turtle, RDF/XML, JSON-LD, N-Triples, and N3—while export_owl (lines 315-362) handles filesystem persistence, automatically creating output directories via ensure_directory and writing the generated content to disk.

Pipeline Integration: Validation Before Generation

The OntologyGenerator class in semantica/ontology/ontology_generator.py unifies these capabilities through a six-stage pipeline (lines 197-210). After building class and property structures from raw data, the generator invokes validation as a final quality gate:

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 integration ensures every ontology undergoes both logical consistency checking (via HermiT/Pellet symbolic reasoners) and structural SHACL compliance before downstream export to OWLGenerator. The validation step prevents invalid ontologies from reaching serialization, coupling symbolic reasoning with shape-based constraints.

Practical Implementation Examples

Validating Ontologies with SHACL

To validate a Python dictionary representing an ontology structure:

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 with explanations

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

The SHACLValidationReport provides both programmatic access to violation objects and human-readable explanations through its templated messaging system.

Generating OWL Serializations

To convert an ontology dictionary to Turtle format:

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 further manipulation

graph = owl_gen.generate_owl(my_ontology)
graph.serialize(destination="output.ttl", format="turtle")

The generate_owl method automatically selects the appropriate implementation based on rdflib availability, returning either a string or Graph object for maximum flexibility.

Complete Pipeline Execution

For end-to-end ontology construction that combines both capabilities:

from semantica.ontology import OntologyGenerator, OWLGenerator

# 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)

# Validate (includes SHACL and symbolic checking)

validation = generator.validator.validate(ontology)

# Export if valid

if validation.valid:
    OWLGenerator().export_owl(ontology, "output/ontology.ttl")

This workflow demonstrates how OWL generation vs SHACL validation operate sequentially, with validation acting as a prerequisite for export operations to ensure semantic quality.

Summary

  • SHACL validation in semantica/ontology/ontology_validator.py enforces structural constraints using pySHACL, producing structured SHACLValidationReport objects with templated human-readable explanations via the explain_violations method.
  • OWL generation in semantica/ontology/owl_generator.py supports dual implementation paths—rdflib-backed for full functionality and string-templating fallback for lightweight environments—outputting Turtle, RDF/XML, JSON-LD, N-Triples, or N3 formats.
  • The OntologyGenerator pipeline automatically invokes validation (lines 197-210) before serialization, coupling symbolic reasoners (HermiT/Pellet) with SHACL checks to ensure logical consistency and structural compliance.
  • Both systems share namespace management infrastructure through namespace_manager.py, ensuring consistent IRI generation for classes and properties across validation and generation workflows.

Frequently Asked Questions

What is the primary difference between SHACL validation and OWL generation in Semantica?

SHACL validation focuses on structural constraint checking, verifying that ontology instances conform to defined shapes and property requirements using the OntologyValidator class and pySHACL. OWL generation transforms internal ontology dictionaries into standard RDF/OWL serializations using the OWLGenerator class. While validation ensures data quality and conformance through the _run_pyshacl method (lines 48-73), generation produces exchangeable semantic formats suitable for external consumption and knowledge graph publishing.

Can I use OWL generation without installing rdflib?

Yes. The OWLGenerator includes a fallback _generate_basic implementation (lines 300-375 in owl_generator.py) that produces valid Turtle syntax through string concatenation when rdflib is unavailable, controlled by the HAS_RDFLIB flag checked at import time (lines 39-46). However, the SHACL validation subsystem requires rdflib for graph parsing and cannot operate without it.

Which serialization formats does OWLGenerator support?

According to the source code in owl_generator.py (lines 218-229), the generator supports Turtle, RDF/XML, JSON-LD, N-Triples, and N3 formats. The export_owl method handles file persistence for any of these formats, automatically creating output directories via ensure_directory when writing to disk (lines 315-362).

How does Semantica handle SHACL shape generation?

The ontology_validator.py module includes an internal SHACLGenerator class that automatically constructs SHACL node and property shapes from OWL ontology dictionaries. This generator creates constraints based on property definitions—such as required fields mapping to sh:minCount constraints—enabling automatic validation without manual shape authoring, invoked automatically during the OntologyValidator.validate() workflow.

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 →