| """Modèles Pydantic du moteur d'inférence JDM (Phase 11).""" |
| from __future__ import annotations |
|
|
| from enum import Enum |
| from typing import List |
|
|
| from pydantic import BaseModel, ConfigDict, Field |
|
|
|
|
| class FiredSchema(str, Enum): |
| """Schéma d'inférence ayant produit le résultat. |
| |
| L'énumération est complète dès le départ (sérialisation stable) même si |
| certains schémas ne sont activés qu'à l'effort 2. |
| """ |
| NONE = "none" |
| TAUTOLOGY = "tautology" |
| CONTRADICTION = "contradiction" |
| INVERSE = "inverse" |
| IMPLICATION = "implication" |
| SYNONYM_EQUIV = "synonym_equiv" |
| ISA_INCOMPATIBLE = "isa_incompatible" |
| CLASS_ELIM = "class_elimination" |
| DEDUCTION_ISA = "deduction_isa" |
| TRANSITIVITY = "transitivity" |
| TARGET_GENERIC = "target_generic" |
| DOUBLE_ISA = "double_isa" |
| COMPOSITION = "composition" |
| PREFIX = "prefix" |
| HYPONYM_PROP = "hyponym_propagation" |
| ANTONYM_CONTRAST = "antonym_contrast" |
| COHYPONYM = "cohyponym" |
| GEO_PROPAGATION = "geo_propagation" |
|
|
|
|
| class ProofStep(BaseModel): |
| """Un triplet JDM élémentaire dans la chaîne de preuve d'une inférence.""" |
| source: str |
| relation: str |
| target: str |
| w: float |
| note: str = "" |
|
|
|
|
| class InferenceResult(BaseModel): |
| """Résultat d'une inférence sur le triplet (subject, relation, object). |
| |
| `signed_weight` porte le verdict : |
| * > 0 → le triplet est jugé VRAI par inférence |
| * < 0 → le triplet est jugé FAUX / réfuté |
| * = 0 → silence (aucun schéma n'a conclu) |
| """ |
| model_config = ConfigDict(extra="ignore") |
|
|
| subject: str |
| relation: str |
| object: str |
| signed_weight: float = 0.0 |
| fired_schema: FiredSchema = FiredSchema.NONE |
| proof: List[ProofStep] = Field(default_factory=list) |
| confidence: float = Field(0.0, ge=0.0, le=1.0) |
| lookups_used: int = 0 |
| explanation: str = "" |
|
|
| @property |
| def is_true(self) -> bool: |
| return self.signed_weight > 0 |
|
|
| @property |
| def is_false(self) -> bool: |
| return self.signed_weight < 0 |
|
|
| @property |
| def is_silent(self) -> bool: |
| return self.signed_weight == 0 |
|
|