UltipaDocs
Products
Solutions
Resources
Company
Start Free Trial
UltipaDocs
Start Free Trial
  • Introduction
    • RDF Import & Export
    • Working with RDF
    • Loading LinkML
    • Classes
    • Object Properties
    • Data Properties
  • Using Ontology Labels & IRIs
  • Inspecting Ontologies
  • Inference & Validation
  1. Docs
  2. /
  3. Ontology

Inference & Validation

Overview

An ontology in GQLDB does two jobs at runtime: it infers extra facts when you query, and it validates your data against constraints when you write. The two are independent: inference always runs, while validation is what the enforcement modes control.

This page draws that distinction, then covers the enforcement modes that tune validation, how to surface violations, and the transitive-inference depth control.

Inference vs. Validation

GQLDB acts on ontology axioms in two distinct ways, on opposite sides of a query:

  • Inference (read side). The engine derives facts at query time. Nothing is written to disk, the extra results are computed on read. Inference is always applied.
  • Validation (write side). The engine checks data against constraints at write time. The enforcement mode decides what happens when a violation is detected.
SideOntology features
InferenceSUBCLASS OF, EQUIVALENT TO, owl:unionOf/intersectionOf/oneOf/equivalentClass, SYMMETRIC, TRANSITIVE, REFLEXIVE, INVERSE OF, SUBPROPERTY OF, PROPERTY CHAIN, owl:equivalentProperty
ValidationDISJOINT WITH, DOMAIN/RANGE, ASYMMETRIC, FUNCTIONAL, INVERSE_FUNCTIONAL, IRREFLEXIVE, CARDINALITY, data-property XSD type

Enforcement Modes

Control how strictly ontology rules are validated with three modes:

ModeBehavior
STRICTViolations cause errors and block operations
WARNINGDefault. Violations are logged but operations proceed
OFFNo validation (useful for bulk imports)
GQL
-- Check current enforcement mode
SHOW ONTOLOGY ENFORCEMENT

-- Enable strict enforcement
SET ONTOLOGY ENFORCEMENT STRICT

-- Enable warning mode
SET ONTOLOGY ENFORCEMENT WARNING

-- Disable enforcement
SET ONTOLOGY ENFORCEMENT OFF

STRICT

In STRICT mode, any ontology constraint violation will cause an error and block the operation. Use this in production to ensure data quality.

GQL
-- Setup domain/range constraints
CREATE OBJECT PROPERTY @ex:worksFor DOMAIN @ex:Person RANGE @ex:Organization

SET ONTOLOGY ENFORCEMENT STRICT

-- This succeeds: Person -> Organization
INSERT (@ex:Person {name: 'Alice'})-[@ex:worksFor]->(@ex:Organization {name: 'Acme'})

-- This fails: Organization -> Organization violates DOMAIN
INSERT (@ex:Organization {name: 'Org1'})-[@ex:worksFor]->(@ex:Organization {name: 'Org2'})

WARNING

In WARNING mode, constraint violations are logged but operations proceed. Use this during migration or development to identify issues without blocking work.

GQL
SET ONTOLOGY ENFORCEMENT WARNING

-- This succeeds but logs a warning
-- Warning logged: Domain constraint violation - source should be @ex:Person
INSERT (@ex:Organization {name: 'Org1'})-[@ex:worksFor]->(@ex:Organization {name: 'Org2'})

View warnings after operations:

GQL
SHOW ONTOLOGY WARNINGS

Result:

typemessagetimestamp
DOMAIN_MISMATCHSource node does not match domain constraint for @ex:worksFor (expected: [http://example.org/Person])1779101828

Bulk Import Note

For large imports, use WARNING mode: constraint violations are logged (not blocking) as each row is written, so the import runs to completion and you can review the issues afterward.

GQL
SET ONTOLOGY ENFORCEMENT WARNING

-- Bulk import; violations are logged, not blocked
INSERT (@ex:Person {name: 'Alice'})
INSERT (@ex:Person {name: 'Bob'})
INSERT (@ex:Organization {name: 'Acme'})
// thousands more inserts ...

-- Review what was flagged during the import
SHOW ONTOLOGY WARNINGS
VALIDATE ONTOLOGY

OFF is faster still as it skips the constraint checks entirely, but no warnings are logged. Use OFF only for data you already trust; to check OFF-imported data you must re-run the writes under WARNING or STRICT.

Validating Ontology

VALIDATE ONTOLOGY returns a one-row snapshot: the ontology counts plus the number of warnings currently in the warning store. It does not rescan stored data, it just reports the violations already logged at write time (as INSERTs ran under WARNING mode), not a fresh audit of the graph. So it never surfaces problems in data written under OFF, or in data that predates the constraint. For the individual violations, use SHOW ONTOLOGY WARNINGS.

GQL
VALIDATE ONTOLOGY

Example output:

statusontologiesclassespropertieswarnings
OK11880

Returned columns:

ColumnDescription
statusOK when the warnings count is zero, WARNINGS otherwise.
ontologiesNumber of registered ontologies (one per LOAD ONTOLOGY import plus an optional local one for inline CREATE definitions).
classesTotal class count across all ontologies.
propertiesTotal object + data property count across all ontologies.
warningsNumber of warnings currently in the warning store. Cleared by CLEAR ONTOLOGY WARNINGS.

Worked example — set up a constraint, plant a violation under WARNING, then check the report:

GQL
CREATE OBJECT PROPERTY @ex:employs DOMAIN @ex:Organization RANGE @ex:Person

SET ONTOLOGY ENFORCEMENT WARNING

-- DOMAIN_MISMATCH: source should be @ex:Organization, not @ex:Person
INSERT (@ex:Person {name: 'Alice'})-[@ex:employs]->(@ex:Person {name: 'Bob'})

VALIDATE ONTOLOGY

The report increments warnings and flips status to WARNINGS, while the per-row details are available via SHOW ONTOLOGY WARNINGS.

VALIDATE ONTOLOGY also accepts an optional mode that updates the current enforcement before running:

GQL
VALIDATE ONTOLOGY STRICT
VALIDATE ONTOLOGY WARNING

Validation Types

The ontology validator checks for the following types of constraint violations. The same types appear in SHOW ONTOLOGY WARNINGS and in VALIDATE ONTOLOGY output.

TypeTriggered by
CLASS_NOT_FOUNDNode has an ontology label for an undefined class
DOMAIN_MISMATCHEdge source doesn't match the property's DOMAIN
RANGE_MISMATCHEdge target doesn't match the property's RANGE
DISJOINT_VIOLATIONNode carries labels from two DISJOINT WITH classes
ASYMMETRIC_VIOLATIONAn ASYMMETRIC property has the reverse edge, or a self-loop
IRREFLEXIVE_VIOLATIONAn IRREFLEXIVE property has a self-loop
FUNCTIONAL_VIOLATIONMore than one outgoing edge for a FUNCTIONAL (i.e. CARDINALITY {0,1}) property
INVERSE_FUNCTIONAL_VIOLATIONAn INVERSE_FUNCTIONAL property's target already has a different source
CARDINALITY_VIOLATIONValue/edge count falls outside the declared CARDINALITY bounds
TYPE_MISMATCHData property value doesn't match the declared XSD type

Domain violation example:

GQL
CREATE OBJECT PROPERTY @ex:employs DOMAIN @ex:Organization RANGE @ex:Person

-- Wrong: Person cannot employ (domain is Organization)
-- DOMAIN_MISMATCH: source must be @ex:Organization
INSERT (@ex:Person {name: 'Alice'})-[@ex:employs]->(@ex:Person {name: 'Bob'})

Range violation example:

GQL
-- Wrong: Organization cannot be employed (range is Person)
-- RANGE_MISMATCH: target must be @ex:Person
INSERT (@ex:Organization {name: 'Acme'})-[@ex:employs]->(@ex:Organization {name: 'Other'})

Viewing Warnings

When using WARNING mode, violations are stored in a warnings log that you can query.

GQL
SHOW ONTOLOGY WARNINGS

Example output:

typemessagetimestamp
TYPE_MISMATCHProperty age expects http://www.w3.org/2001/XMLSchema#integer, got types.StringValue1779101357
CARDINALITY_VIOLATIONProperty fullName requires at least 1 value(s), got 01779101357

Reset the accumulated warnings log:

GQL
CLEAR ONTOLOGY WARNINGS

Transitive Inference Depth

TRANSITIVE object properties expand inference chains across edges. Use SET ONTOLOGY TRANSITIVE DEPTH to cap how many hops the engine will traverse — useful in deep graphs where unbounded expansion is too expensive.

GQL
SET ONTOLOGY TRANSITIVE DEPTH 5

The depth is the maximum length of the real-edge chain that produces an inferred edge. With 5, source-to-target chains of 1–5 real edges yield an inferred edge; chains of 6 or more do not.

For a chain A → B → C → D → E → F → G (each → a real TRANSITIVE edge):

SourceInferred edge toReal-chain lengthCreated?
AB1✓ (also the real edge)
AC2✓
AD3✓
AE4✓
AF5✓
AG6✗

The value must be a positive integer (>= 1), or the sentinel -1 for unbounded expansion. 0 and any other negative value are rejected. The default when never set is 10.

GQL
-- Unbounded expansion (no depth cap)
SET ONTOLOGY TRANSITIVE DEPTH -1

Use -1 deliberately;1 unbounded expansion on a deep graph can be expensive.