Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta
class BaseDeConhecimento:
    """
    Armazena a base de conhecimento do sistema especialista:
      - fatos: informacoes conhecidas no momento (sintomas relatados
        pelo paciente e diagnosticos ja deduzidos).
      - regras: relacoes do tipo SE (condicoes) ENTAO (conclusao).
    """

    def __init__(self):
        self.fatos = set()
        self.regras = []  # cada regra e uma tupla (condicoes: set, conclusao: str)

    def adicionar_fato(self, fato):
        self.fatos.add(fato)

    def adicionar_regra(self, condicoes, conclusao):
        """
        condicoes: conjunto de fatos que precisam ser verdadeiros
                   simultaneamente (conjuncao logica / "E").
        conclusao: fato que passa a ser considerado verdadeiro caso
                   todas as condicoes sejam satisfeitas.
        """
        self.regras.append((set(condicoes), conclusao))

    def __repr__(self):
        linhas = ["Fatos conhecidos: " + ", ".join(sorted(self.fatos))]
        linhas.append("Regras:")
        for condicoes, conclusao in self.regras:
            condicoes_str = " E ".join(sorted(condicoes))
            linhas.append(f"  SE {condicoes_str} ENTAO {conclusao}")
        return "\n".join(linhas)


class SistemaEspecialista:
    """
    Motor de inferencia com encadeamento progressivo (forward chaining):
    a cada rodada, verifica quais regras tem todas as condicoes
    satisfeitas pelos fatos conhecidos e, se sim, adiciona a conclusao
    aos fatos. Repete ate nenhuma regra nova poder ser aplicada.
    """

    def __init__(self, base_conhecimento):
        self.base = base_conhecimento
        self.raciocinio = []  # guarda o "porque" de cada conclusao, na ordem

    def inferir(self):
        self.raciocinio = []
        houve_mudanca = True

        while houve_mudanca:
            houve_mudanca = False
            for condicoes, conclusao in self.base.regras:
                if conclusao in self.base.fatos:
                    continue  # essa conclusao ja foi deduzida antes

                if condicoes.issubset(self.base.fatos):
                    self.base.adicionar_fato(conclusao)
                    condicoes_str = " E ".join(sorted(condicoes))
                    self.raciocinio.append(
                        f"Como {condicoes_str} -> concluo: {conclusao}"
                    )
                    houve_mudanca = True

        return self.base.fatos

    def explicar_raciocinio(self):
        if not self.raciocinio:
            return "Nenhuma nova conclusao foi deduzida a partir dos fatos fornecidos."
        return "\n".join(self.raciocinio)


# ---------------------------------------------------------
# Testando o sistema
# ---------------------------------------------------------
if __name__ == "__main__":

    print("### Caso 1: paciente com febre alta, tosse e dificuldade para respirar ###\n")

    base1 = BaseDeConhecimento()
    base1.adicionar_fato("febre_alta")
    base1.adicionar_fato("tosse")
    base1.adicionar_fato("dificuldade_para_respirar")

    base1.adicionar_regra({"febre_alta", "tosse"}, "infeccao_respiratoria")
    base1.adicionar_regra({"infeccao_respiratoria", "dificuldade_para_respirar"}, "pneumonia")

    print(base1)

    sistema1 = SistemaEspecialista(base1)
    fatos_finais = sistema1.inferir()

    print("\nRaciocinio do sistema:")
    print(sistema1.explicar_raciocinio())
    print("\nFatos finais:", sorted(fatos_finais))

    print("\n" + "=" * 70 + "\n")

    print("### Caso 2: paciente apenas com tosse (sem febre e sem falta de ar) ###\n")

    base2 = BaseDeConhecimento()
    base2.adicionar_fato("tosse")

    base2.adicionar_regra({"febre_alta", "tosse"}, "infeccao_respiratoria")
    base2.adicionar_regra({"infeccao_respiratoria", "dificuldade_para_respirar"}, "pneumonia")

    print(base2)

    sistema2 = SistemaEspecialista(base2)
    fatos_finais_2 = sistema2.inferir()

    print("\nRaciocinio do sistema:")
    print(sistema2.explicar_raciocinio())
    print("\nFatos finais:", sorted(fatos_finais_2))
1 resposta

Olá, Bruna! Como vai?

Parabéns pela resolução da atividade!

Vi que você explorou o encadeamento progressivo (forward chaining) para dedução de fatos com Python, utilizou muito bem a estrutura de regras e condições para modelar diagnósticos e ainda compreendeu a importância da explicação do raciocínio para tornar o sistema especialista transparente e confiável.

Continue postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Se quiser aprofundar ainda mais, algumas boas práticas são:

  • Escalabilidade: adicionar suporte a encadeamento reverso (backward chaining) para responder perguntas específicas.
  • Generalização: permitir que as regras sejam carregadas de arquivos externos (JSON ou YAML), facilitando manutenção.
  • Explicabilidade: enriquecer o raciocínio com justificativas mais detalhadas, aproximando o sistema de aplicações reais em diagnósticos médicos ou consultivos.

Alguns materiais podem estar em inglês, mas é possível compreendê-los usando o recurso de tradução de páginas do próprio navegador.

Ah, uma pergunta: você prefere continuar praticando com sistemas especialistas para consolidar fundamentos ou acha mais interessante avançar para aplicações mais complexas que integrem aprendizado de máquina junto às regras lógicas?

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!