Diagnostic d’un réseau par abduction explicite

Solutions du code

Module .../reseau/abduction.py

from .disjonction import Disjonction
from .conjonction import Conjonction

class Abduction:

    def __init__(self, conflits, no_goods):
        self.conflits = conflits
        self.no_goods = no_goods

    def combiner_conflits_observations(self, disjonctions):
        """ Combine plusieurs disjonctions en une seule.

            :param disjonctions: une collection de disjonctions.
        """
        combinaison = Disjonction()
        for disjonction in disjonctions:
            combinaison = combinaison.combiner(disjonction)
        return combinaison

    def retire_subsumes(self, conjonctions):
        """ Retire d'une liste de conjonctions les candidats
            subsumés.

            :param conjonctions: une liste de conjonctions.
        """
        sans_subsumes = Disjonction()

        for conjonction in sorted(conjonctions, key=lambda expl: len(expl)):
            conserver = True
            for conj in sans_subsumes:
                if conj.issubset(conjonction):
                    conserver = False
                    break
            if conserver:
                sans_subsumes.add(conjonction)

        return sans_subsumes

    def retire_no_goods(self, conjonctions, no_goods):
        """
            Retire d'une liste de conjonctions les candidats
            contenant un no-good.

            Les conjonctions résultantes sont retournées sous
            forme de disjonction.

            :param conjonctions: une collection de conjonctions.
            :param no_goods: une liste de no-goods.
        """
        sans_no_goods = Disjonction()

        for conjonction in conjonctions:
            conserver = True
            for no_good in no_goods:
                if no_good.issubset(conjonction):
                    conserver = False
                    break
            if conserver:
                sans_no_goods.add(conjonction)

        return sans_no_goods

    def calcule_conflit_minimal(self, afficher_etapes=False):
        """
            Calcule par abduction le conflit minimal entre les candidats.
        """

        # 1. Combine les conflits.
        conflit_minimal = self.combiner_conflits_observations(self.conflits)
        if afficher_etapes: print('Conflit combiné :', conflit_minimal)

        # 3. Supprime les candidats subsumés.
        conflit_minimal = self.retire_subsumes(conflit_minimal)
        if afficher_etapes: print('Non subsumés :', conflit_minimal)

        # 4. Supprime les candidats contenant les no-goods.
        conflit_minimal = self.retire_no_goods(conflit_minimal, self.no_goods)
        if afficher_etapes: print('Sans no-goods :', conflit_minimal)

        return conflit_minimal

Documentation du code

class reseau.bloc.Bloc(nom, entree_1, entree_2, sortie)

Un bloc dans un circuit.

__init__(nom, entree_1, entree_2, sortie)

Construit un nouveau bloc.

Paramètres:
  • nom – le nom servant à identifier le bloc.
  • entree_1 – la première entrée du bloc.
  • entree_2 – la seconde entrée du bloc.
  • sortie – la sortie du bloc.
__lt__(autre)

Permet la comparaison avec un autre bloc. Surtout utile pour trier une liste de blocs.

class reseau.circuit.Circuit

Modélise un circuit électrique composé de blocs et de connexions.

__init__()
ajouter_bloc(nom, entree_1, entree_2, sortie)

Ajoute un bloc au circuit.

Paramètres:
  • nom – un nom identifiant le bloc.
  • entree_1 – le nom de l’une des entrées du bloc.
  • entree_2 – le nom de l’autre entrée.
  • sortie – le nom de la connexion de sortie.
observe_correct(signal)

Notifie l’observation d’un signal correct.

Paramètres:signal – le nom de la connection observée.
observe_incorrect(signal)

Notifie l’observation d’un signal incorrect.

Paramètres:signal – le nom de la connection observée.
traduire_chemin_en_disjonction(chemin)

Transforme un chemin en une disjonction de conjonctions, c’est-à-dire un conflit.

trouver_un_chemin(signal)

Collecte la liste des candidats possibles pour expliquer l’observation d’un signal défectueux.

Paramètres:signal – le nom de la connection observée.
class reseau.conjonction.Conjonction

Une conjonction logique.

__or__(autre)

Retourne une conjonction couvrant l’union des éléments de la conjonction courante et de ceux de autre.

Paramètres:autre – une autre conjonction.
class reseau.disjonction.Disjonction

Une disjonction logique.

combiner(disjonction)

Combine la disjonction courante avec une autre afin d’obtenir une disjonction regroupant, sous formes de conjonctions, toutes les combinaisons d’éléments appartenant à l’une et à l’autre.

Si self est (p & q) | (u & v) et disjonction est (a & b) | (c & d), le résultat sera

(p & q & a & b) | (p & q & c & d) | (u & v & a & b) | (u & v & c & d)

Paramètres:disjonction – une autre disjonction.