""" MODULE INFERENCE ENGINE - GOLDEN RECORD ======================================= Responsabilité : Créer une vérité unique (montant_net) à partir des données brutes. """ from rdflib import Namespace VORTEX = Namespace("http://vortex.ai/ontology#") class InferenceEngine: def __init__(self, rdf_store): self.rdf_store = rdf_store def run_inference(self): print("🧠 [R-BOX] Inférence (Golden Records)...") # 1. GOLDEN RECORD : Déduplication des Montants # On prend le MAX des montants déclarés pour un même ID de prêt rule_dedup = """ CONSTRUCT { ?pret vortex:montant_net ?max_val . } WHERE { SELECT ?pret (MAX(xsd:decimal(?val)) AS ?max_val) WHERE { ?pret a ?type . ?pret ?p ?val_raw . FILTER(CONTAINS(LCASE(STR(?p)), "montant") || CONTAINS(LCASE(STR(?p)), "capital")) FILTER(isNumeric(xsd:decimal(?val_raw))) BIND(xsd:decimal(?val_raw) AS ?val) } GROUP BY ?pret } """ self._apply_rule(rule_dedup, "Création Golden Record (montant_net)") # 2. HIGH VALUE : Marquage automatique (> 100k) rule_high_value = """ CONSTRUCT { ?pret vortex:statut_risque "HighValue" . } WHERE { ?pret vortex:montant_net ?m . FILTER(?m > 100000) } """ self._apply_rule(rule_high_value, "Détection HighValue (>100k)") # 3. RELATIONS INVERSES (Pour lier Prêt <-> Client) rule_inverse = """ CONSTRUCT { ?pret vortex:a_emprunteur ?client_label . } WHERE { ?client vortex:possede_pret ?pret . ?client rdfs:label ?client_label . } """ self._apply_rule(rule_inverse, "Inverse Emprunteur") def _apply_rule(self, sparql, name): try: full_query = f""" PREFIX vortex: PREFIX xsd: PREFIX rdfs: {sparql} """ res = self.rdf_store.g.query(full_query) for t in res: self.rdf_store.g.add(t) print(f"✅ Règle '{name}' appliquée.") except Exception as e: print(f"❌ Erreur Règle '{name}' : {e}")