web-dev-qa-db-fra.com

Comment transformer la table de vérité en bloc le plus petit possible si / sinon

Comment puis-je prendre une table de vérité et la transformer en un bloc compacté si?

Par exemple, disons que j'ai cette table de vérité où A et B sont des conditions et X, Y et Z sont des actions possibles:

A B | x y z
-------------
0 0 | 0 0 1
0 1 | 0 0 1
1 0 | 0 1 0
1 1 | 1 0 0

Cela pourrait se transformer en ci-dessous si le bloc:

if(A)
{
    if(B)
    {
        do(x)
    }
    else
    {
        do(y)
    }
}
else
{
    do(z)
}

C'est un échantillon facile, mais j'ai souvent plusieurs conditions combinées de différentes manières de produire différentes sorties et devient difficile de comprendre le moyen le plus compacté et élégant de représenter leur logique dans un bloc IF.

20
Juan

Si vous concevez une carte de Karnaugh, le code peut aussi bien regarder aussi bien:

//                   a      b
def actionMap = [ false: [false: { z() },
                          true:  { z() }],
                  true:  [false: { x() },
                          true:  { y() }]]

actionMap[a][b]()
14
kevin cline

Ce que vous voulez, c'est un algorithme à nouvea . Cela combunise automatiquement un ensemble de règles et les privilégie dans un arbre comme vous décrivez.

Il existe un certain nombre de systèmes de "moteur de règles" commerciaux qui le font à très grande échelle (des millions de règles) où la vitesse d'exécution est essentielle.

2
Alex Feinman

Voici votre bibliothèque :) Et vous n'avez pas besoin de passer une table K complète, seuls les champs qui vous intéressent :) Cela suppose que son opérateur dans la table de vérité. Si vous souhaitez utiliser plus d'opérateurs, vous devriez être capable de le réécrire. Vous pouvez avoir un nombre quelconque d'arguments. Écrit en python et testé.

def x():
    print "xxxx"

def y():
    print "yyyyy"

def z(): #this is default function
    print "zzzzz"

def A():
    return 3 == 1

def B():
    return 2 == 2


def insert(statements,function):
    rows.append({ "statements":statements, "function":function })

def execute():
    for row in rows:
        print "==============="
        flag = 1

        for index, val in enumerate(row["statements"]):
            #for first pass of lopp, index is 0, for second its 1....
            #if any function returns result different than one in our row, 
            # we wont execute funtion of that row (mark row as not executable)
            if funcs[index]() != val:
                flag = 0

        if flag == 1:
            #we execute function 
            row["function"]()
        else: z() #we call default function


funcs = [A,B]  #so we can access functions by index key
rows = []

insert( (0,0), y)
insert( (0,1), y)
insert( (1,0), x)
insert( (1,1), x)
insert( (0,1), x)

execute()
2
grizwako

Mappez les entrées en une seule valeur, puis allumez-la:

#define X(a, b) (!!(a) * 2 + !!(b))
switch(X(A, B)) {
case X(0, 0):
    ...
    break;
case X(0, 1):
    ...
    break;
case X(1, 0):
    ...
    break;
case X(1, 1):
    ...
    break;
}
#undef X
1
Deduplicator

Une table de recherche contenant des fonctions Les pointeurs peuvent bien fonctionner dans certaines situations. En C, par exemple, vous pouvez faire quelque chose comme ceci:

typedef void(*VoidFunc)(void);

void do(int a, int b)
{
    static VoidFunc myFunctions[4] = {z, z, y, x}; // the lookup table

    VoidFunc theFunction = myFunctions[ a * 2 + b ];
    theFunction();
}

C'est une bonne solution lorsque le nombre d'entrées est relativement faible, car le nombre d'entrées dans la table doit être 2 ^^ N dans lequel n est le nombre d'entrées. 7 ou 8 entrées peuvent être gérables, 10 ou 12 commencent à devenir laids. Si vous avez de nombreux intrants, essayez de simplifier par d'autres moyens (tels que Karnaugh Maps).

1
Caleb

Regardez le logiciel "Gorgeous Karnaugh" - il peut accepter des tables de vérité assez exactes comme ton d'échantillon, accepter la définition de formules booléennes analytiques, accepter les scripts Lua pour construire des tables de vérité. Suivant, le logiciel "Gorgeous Karnaugh" dessine les k-Maps pour une entrée prise, que vous pouvez minimiser manuellement ou utiliser un minimum de logique "Espresso" et produit une sortie pour C/C++ et certaines langages matériels. Recherchez la page Résumé des fonctions de "Gorgeous Karnaugh" - http://purefractalsolutions.com/show.php?a=xgk/gkm

0
Petruchio