Moteur D'Inférence
Pendant mes études, j’ai du codé un moteur d’inférence en java… j’en ai fait une version Python beaucoup plus épuré que ce que j’avais pu faire à l’époque. C’est un chaînage avant. Avec cet outil, on peut construire un système expert capable de déduction depuis une base de fait en se basant sur des règles définis par l’utilisateur.
#!/usr/bin/env python3
# coding: utf8
import logging
# construction du logger
LOGGER = logging.getLogger()
#LOGGER.setLevel(logging.WARNING)
LOGGER.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(module)s :: %(levelname)s :: %(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
LOGGER.addHandler(stream_handler)
class regle () :
"""
Les règles sont constitué d'un ensemble de faits appelé prémisse dont la conséquence est appelé la conclusion.
"""
def __init__ (self,Premisse,Conclusion):
self.Premisse=Premisse
self.Conclusion=Conclusion
def aff (self) :
return str(self.Premisse) + ' donne ' + self.Conclusion
def __str__(self):
return str(self.Premisse) + ' donne ' + self.Conclusion
class Brain () :
"""
Le moteur d'inférence.
"""
def __init__ (self):
self.BaseDeFait=[]
self.BaseDeRegle=[]
def present(self, Premisse):
"""
Dit si une prémisse est présente dans l'ensemble.
"""
# utilise les fonctions ensembliste pour faire le test
# A dans B
S1 = set(self.BaseDeFait)
S2 = set(Premisse)
if S1.intersection(S2) == S2 :
return True
else :
return False
def AjoutDeFait (self,Fait):
"""
Ajout un fait à la base de fait.
"""
self.BaseDeFait.append(Fait)
def AjoutDeRegle (self,Regle):
"""
Ajout une règle à la base de règle
"""
self.BaseDeRegle.append(Regle)
def Analyse (self) :
"""
Analyse la base de fait et déduit de nouveau fait en fonction de la base de règle.
"""
ConclusionAjouter = 1
LOGGER.debug("Début de la boucle d'analyse.")
while (len(self.BaseDeRegle) > 0 and ConclusionAjouter > 0 ):
LOGGER.debug("La base de règle contient %d règles.", len(self.BaseDeRegle))
RegleMarquee = []
ConclusionAjouter = 0
LOGGER.debug("Recherche des règles valide.")
for Regle in self.BaseDeRegle :
if (self.present(Regle.Premisse)):
self.AjoutDeFait(Regle.Conclusion)
RegleMarquee.append(Regle)
ConclusionAjouter += 1
LOGGER.debug("Règle valide : %s.",Regle)
if ConclusionAjouter > 0:
LOGGER.debug("Suppression des règles utilisées de la base de règle.")
for Regle in RegleMarquee :
self.BaseDeRegle.remove(Regle)
LOGGER.debug("Règle supprimée : %s.",Regle)
if ConclusionAjouter == 0:
LOGGER.debug("Aucune règle n'a été ajouté. L'analyse des règles est terminées.")
else:
LOGGER.debug("%d nouveaux fait ont été ajouté à la base de fait. L'analyse doit reprendre.", ConclusionAjouter)
LOGGER.debug("Fin de la boucle d'analyse.")
def aff(self) :
return (self.BaseDeFait)
if __name__ == '__main__' :
db=Brain()
db.AjoutDeFait('a')
db.AjoutDeFait('c')
db.AjoutDeFait('f')
db.AjoutDeRegle(regle([],'Z')) # une regle sans premisse est toujours vrai
db.AjoutDeRegle(regle(['a','c'],'e'))
db.AjoutDeRegle(regle(['e','g','f'],'h'))
db.AjoutDeRegle(regle(['c','f'],'d'))
db.AjoutDeRegle(regle(['d','e'],'g'))
db.AjoutDeRegle(regle(['j','k'],'m')) # regle non réalisable dans le cas présent
db.AjoutDeRegle(regle(['a','h','e'],'l'))
print("Base de fait", db.aff())
db.Analyse()
print("Base de fait après Analyse : ", db.aff())
Ce moteur pourrait être intégré à une carte électronique (NodeMCU) prenant en charge le python (micropython) afin d’utiliser les capteurs relié à la dite carte comme base de fait.
Si fumé + élévation de la température (calcul de la dérivé seconde [accélération] de la température) alors il y a probablement un incendie.