mixle.reason.ontology module

Ontology objects for typed constraints on knowledge graphs.

A knowledge graph without a schema will happily assert (paris, employs, france). An Ontology is the typed contract that rules such triples out structurally: a class hierarchy, relation signatures (employs: Organization -> Person), per-relation axioms (functional, symmetric, asymmetric, irreflexive), and disjoint-class declarations. Ontology.check_triple() names every violation of one assertion; Ontology.check_graph() audits a whole triple set, including the cross-triple axioms (a functional relation asserted with two different tails).

The same contract turns a fitted KG embedding into an ontology-constrained distribution: OntologyConstrainedKG wraps a KnowledgeGraphDistribution and masks the tail posterior to range-conforming entities, renormalizing – so the model literally cannot place probability on a triple the ontology forbids. Constrained extraction or decoding can apply the same mask before accepting generated triples.

Everything is symbolic and dependency-free: entities/relations are strings, entity types are supplied as a {entity: class} map (the entity-linking output). Violations are named, never silent.

class Ontology(classes=<factory>, relations=<factory>, axioms=<factory>, disjoint=<factory>)[source]

Bases: object

A typed schema over knowledge: class hierarchy + relation signatures + axioms + disjointness.

Parameters:
classes: dict[str, str | None]
relations: dict[str, tuple[str, str]]
axioms: dict[str, set[str]]
disjoint: list[tuple[str, str]]
add_class(name, parent=None)[source]
Parameters:
  • name (str)

  • parent (str | None)

Return type:

Ontology

add_relation(name, domain, range_, *axioms)[source]
Parameters:
Return type:

Ontology

add_disjoint(a, b)[source]
Parameters:
Return type:

Ontology

is_a(cls, ancestor)[source]

Whether cls is ancestor or a descendant of it (walks the parent chain).

Parameters:
Return type:

bool

check_triple(h, r, t, types)[source]

Every named violation of (h, r, t) given entity types ({} means unconstrained).

Parameters:
Return type:

list[str]

check_graph(triples, types)[source]

Audit a triple set: per-triple violations plus the cross-triple axioms (functional/asymmetric).

Returns {consistent, n_triples, violations: [{triple, problems}]} – every problem named.

Parameters:
Return type:

dict[str, Any]

filter_triples(triples, types)[source]

Split triples into (kept, rejected-with-reasons) by per-triple consistency – the decode mask.

Parameters:
Return type:

tuple[list[tuple], list[dict[str, Any]]]

class OntologyConstrainedKG(kg, ontology, *, entities, relations, types)[source]

Bases: object

A fitted KG embedding, typed by an ontology: probability mass only on schema-consistent triples.

Wraps a KnowledgeGraphDistribution (entities and relations as integer indices) together with the symbolic ontology and the index<->name maps. The tail posterior is masked to entities whose class conforms to the relation’s range and renormalized, so completion can never propose an ontology-violating tail – Graph(ontology) as a distribution.

Parameters:
tail_posterior(head, relation)[source]

p(tail | head, relation) over ONLY the range-conforming entities (renormalized).

Parameters:
Return type:

dict[str, float]

complete(head, relation)[source]

The most probable ontology-consistent tail (or None when the range admits no entity).

Parameters:
Return type:

tuple[str, float] | None

class ConstrainedDecode(facts, rejected, below_floor, n_samples)[source]

Bases: object

The result of ontology-constrained LLM decoding: what survived, what the schema rejected, and why.

Parameters:
facts: list[tuple[Any, float]]
rejected: list[dict[str, Any]]
below_floor: list[tuple[Any, float]]
n_samples: int
asserted()[source]
Return type:

list[Any]

as_dict()[source]
Return type:

dict[str, Any]

constrained_decode(llm, prompt, ontology, types, *, n=None, floor=0.5, calibrator=None)[source]

Ontology-constrained decoding (D2): an LLM may only assert schema-consistent, confident facts.

Samples llm (a GraphLLM) n times, masks every sampled graph through Ontology.filter_triples() (violating triples are REJECTED with named reasons – the typed-grammar mask applied post-parse), then marginalizes the constrained graphs into a GraphDistribution and keeps only facts whose edge marginal clears floor – the calibrated confidence floor (pass a fitted calibrator from fit_fact_calibrator() to apply the floor on CALIBRATED truth probability rather than the raw marginal). Consistent-but-underconfident facts are reported as withheld, never silently dropped: the decode says what it refused to assert and why.

Parameters:
Return type:

ConstrainedDecode