Skip to main content

qualia_core_db/solvers/ontology_align/
correspondence.rs

1//! Ontology-alignment result types + the human-ratification guardrail.
2//!
3//! **Hard invariant (identity / out-of-band remainder):** this engine *proposes*
4//! correspondences with a degree; it can emit `CloseMatch` routed to
5//! `RequiresHumanReview`, and is **structurally forbidden** from asserting
6//! `ExactMatch`. `exactMatch` requires signed human ratification — the machine
7//! proposes, the human disposes. The type system enforces it: there is no
8//! constructor here that yields an asserted exact match.
9
10/// The status a *machine-proposed* correspondence may carry. Note the deliberate
11/// absence of an "asserted ExactMatch" — that state is reachable only through the
12/// human-ratification layer, never from an alignment solver.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ProposedStatus {
15    /// A graded `skos:closeMatch` proposal awaiting human ratification.
16    CloseMatch,
17}
18
19/// One proposed correspondence between a source entity and a target entity.
20#[derive(Debug, Clone, Copy, PartialEq)]
21pub struct Correspondence {
22    pub source: usize,
23    pub target: usize,
24    /// Match degree in `[0,1]` (the fuzzy `closeMatch` strength).
25    pub degree: f64,
26    pub status: ProposedStatus,
27    /// Always `true`: a proposed correspondence MUST be human-reviewed before it can
28    /// become an `exactMatch`. There is no path here that sets this `false`.
29    pub requires_human_review: bool,
30}
31
32impl Correspondence {
33    /// The only constructor — a close-match *proposal*. By construction it is never
34    /// an asserted exact match and always requires human review.
35    pub fn propose(source: usize, target: usize, degree: f64) -> Self {
36        Self {
37            source,
38            target,
39            degree: degree.clamp(0.0, 1.0),
40            status: ProposedStatus::CloseMatch,
41            requires_human_review: true,
42        }
43    }
44}
45
46/// A full alignment: the proposed correspondences plus the total quality earned.
47#[derive(Debug, Clone, PartialEq)]
48pub struct Alignment {
49    pub correspondences: Vec<Correspondence>,
50    pub quality: f64,
51}
52
53impl Alignment {
54    /// Every correspondence is a review-required close-match proposal (the invariant).
55    pub fn all_require_review(&self) -> bool {
56        self.correspondences
57            .iter()
58            .all(|c| c.requires_human_review && c.status == ProposedStatus::CloseMatch)
59    }
60}