ontologos_core/trace.rs
1//! Engine-agnostic inference trace types for explanation generation.
2
3use serde::{Deserialize, Serialize};
4
5use crate::axiom::AxiomId;
6use crate::entity::EntityId;
7
8/// What an inference step concludes.
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case", tag = "kind")]
11pub enum TraceConclusion {
12 /// A new or existing ontology axiom.
13 Axiom {
14 /// Concluded axiom id.
15 id: AxiomId,
16 },
17 /// EL completion: `sub ⊑ sup`.
18 SubClassOf {
19 /// Subclass entity.
20 sub: EntityId,
21 /// Superclass entity.
22 sup: EntityId,
23 },
24 /// EL completion: `class ⊑ ∃property.filler`.
25 Existential {
26 /// Subject class.
27 class: EntityId,
28 /// Object property.
29 property: EntityId,
30 /// Filler class.
31 filler: EntityId,
32 },
33 /// EL completion: `subProperty ⊑ superProperty`.
34 SubObjectPropertyOf {
35 /// Sub property.
36 sub: EntityId,
37 /// Super property.
38 sup: EntityId,
39 },
40}
41
42/// A premise referenced by an inference step.
43#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
44#[serde(rename_all = "snake_case", tag = "kind")]
45pub enum TracePremise {
46 /// An ontology axiom used as a premise.
47 Axiom {
48 /// Premise axiom id.
49 id: AxiomId,
50 },
51 /// EL graph edge `sub ⊑ sup` used as a premise.
52 SubClassOf {
53 /// Subclass entity.
54 sub: EntityId,
55 /// Superclass entity.
56 sup: EntityId,
57 },
58 /// EL graph edge `sub ⊑ ∃property.filler` used as a premise.
59 Existential {
60 /// Subject class.
61 class: EntityId,
62 /// Object property.
63 property: EntityId,
64 /// Filler class.
65 filler: EntityId,
66 },
67 /// EL graph edge `subProperty ⊑ superProperty` used as a premise.
68 SubObjectPropertyOf {
69 /// Sub property.
70 sub: EntityId,
71 /// Super property.
72 sup: EntityId,
73 },
74}
75
76/// A single recorded inference step.
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
78pub struct TraceStep {
79 /// Rule name (engine-specific snake_case identifier).
80 pub rule: String,
81 /// Premises for this step.
82 pub premises: Vec<TracePremise>,
83 /// What this step concludes.
84 pub conclusion: TraceConclusion,
85}
86
87/// Ordered list of inference steps from a reasoning run.
88#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
89pub struct InferenceTrace {
90 /// Steps in derivation order.
91 pub steps: Vec<TraceStep>,
92}
93
94impl InferenceTrace {
95 /// Create an empty trace.
96 #[must_use]
97 pub fn new() -> Self {
98 Self::default()
99 }
100
101 /// Append a step.
102 pub fn push(&mut self, step: TraceStep) {
103 self.steps.push(step);
104 }
105}