table_verite.py

Note de lecture générée automatiquement

Le vrai fichier est scripts/maths/table_verite.py (Obsidian n’affiche pas les scripts eux-mêmes). Ne modifie pas cette note : modifie le script, puis relance python3 generer_vues_obsidian.py dans le dossier scripts.

Code

#!/usr/bin/env python3
"""
table_verite.py — Table de vérité d'une expression booléenne, et vérification
que deux expressions sont équivalentes (pour contrôler un Karnaugh ou De Morgan).
 
Notation acceptée (écris-la entre guillemets) :
    .  ou  *   : ET          +   : OU          !a  ou  ~a  : NON a
    exemples : "a.b + !a.b.c"     "!(a + b)"     "a*b + c"
 
Utilisation :
    python3 table_verite.py "a.b + !a.b.c"
    python3 table_verite.py "a.b + !a.b.c" "b.c + a.b"      # équivalentes ?
    python3 table_verite.py --mintermes "a.b + !b.c + !c.a"  # liste Σm( … ) pour Karnaugh
"""
import itertools
import re
import sys
 
 
def variables_de(expression: str) -> list:
    return sorted(set(re.findall(r"[a-z]", expression)))
 
 
def vers_python(expression: str) -> str:
    # Traduction de la notation BTS vers une expression Python sur des booléens
    traduite = expression.replace("!", " not ").replace("~", " not ")
    traduite = traduite.replace(".", " and ").replace("*", " and ").replace("+", " or ")
    return traduite
 
 
def evaluer(expression: str, valeurs: dict) -> int:
    return int(bool(eval(vers_python(expression), {"__builtins__": {}}, valeurs)))
 
 
def table(expressions: list) -> list:
    noms = sorted(set(v for e in expressions for v in variables_de(e)))
    print(" ".join(noms) + " | " + " | ".join(expressions))
    lignes = []
    for combinaison in itertools.product([0, 1], repeat=len(noms)):
        valeurs = {nom: bool(bit) for nom, bit in zip(noms, combinaison)}
        resultats = [evaluer(e, valeurs) for e in expressions]
        lignes.append((combinaison, resultats))
        print(" ".join(map(str, combinaison)) + " | " + " | ".join(
            str(r).center(len(e)) for r, e in zip(resultats, expressions)))
    return lignes
 
 
if __name__ == "__main__":
    arguments = sys.argv[1:]
    if not arguments:
        sys.exit(__doc__)
    if arguments[0] == "--mintermes":
        lignes = table([arguments[1]])
        mintermes = [int("".join(map(str, c)), 2) for c, r in lignes if r[0] == 1]
        print(f"\nF = Σm({', '.join(map(str, mintermes))})")
    else:
        lignes = table(arguments)
        if len(arguments) == 2:
            equivalentes = all(r[0] == r[1] for _, r in lignes)
            print("\n✅ Expressions ÉQUIVALENTES" if equivalentes else "\n❌ Expressions DIFFÉRENTES")