Bagaimana mengubah tabel kebenaran menjadi sekecil mungkin jika / selain itu memblokir

20

Bagaimana saya bisa mengambil tabel kebenaran dan mengubahnya menjadi blok jika dipadatkan?

Sebagai contoh, katakanlah saya memiliki tabel kebenaran ini di mana A dan B adalah kondisi dan x, y dan z adalah tindakan yang mungkin:

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

Ini bisa berubah menjadi di bawah jika memblokir:

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

Ini adalah contoh yang mudah, tetapi saya sering memiliki beberapa kondisi yang digabungkan dengan cara yang berbeda harus menghasilkan output yang berbeda dan sulit untuk menemukan cara yang paling padat dan elegan untuk mewakili logika mereka dalam blok if.

Juan
sumber
10
Anda maksud mengubah peta Karnaugh menjadi kaskade ifelse?
ratchet freak
@ scratchet: Sepertinya saya lakukan bukan? Saya tidak tahu tentang mereka sebelumnya. Harus melakukan beberapa bacaan tetapi masih dan aplikasi yang akan melakukannya untuk saya akan menyenangkan, jika tidak ada yang lain, untuk memverifikasi hasil tangan saya.
Juan
1
@jalayn sebagian besar alat karnaugh adalah untuk sirkuit digital; mereka memiliki heuristik yang berbeda dari apa pertanyaannya
ratchet freak
1
@ jsoldi: Jawaban yang Anda terima akan bergantung pada situs yang Anda tanyakan. Jika Anda mencari komentar pada fragmen kode tertentu yang berisi beberapa blok if-then-else, tentu saja itu milik review Kode (beta) . Stackoverflow akan mengajarkan Anda alat dan teknik. Pada programmer.SE, orang akan memberi tahu Anda apakah Anda harus / tidak seharusnya khawatir tentang menulis ulang pernyataan logika untuk pemahaman manusia, atau untuk eksekusi yang lebih cepat.
rwong
2
Rekomendasi alat adalah di luar topik, tetapi jika Anda mengubah pertanyaan menjadi "Bagaimana saya bisa melakukan ini?" itu akan sesuai topik. Jika Anda menginginkan rekomendasi perangkat lunak, Anda harus mengunjungi softwarerecs.stackexchange.com.
Kilian Foth

Jawaban:

14

Jika Anda mendesain dari peta Karnaugh, maka kodenya juga mungkin terlihat seperti itu:

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

actionMap[a][b]()
kevin cline
sumber
Bahasa apa ini? Javascript? Python?
TheLQ
TheLQ, ini bukan python, mungkin javascript. Tetapi akan sangat mirip jika ditulis dengan python
grizwako
@TheLQ: ini Groovy, karena itulah yang saya lakukan hari ini, dan mungkin Ruby juga. Kode untuk Javascript atau Python atau LUA atau Perl akan sangat mirip.
kevin cline
2
Ini, tentu saja, memiliki efek mengevaluasi b bahkan ketika evaluasi itu tidak diperlukan. Mungkin itu masalah, mungkin tidak.
Nama samaran
@kevincline tolong, tolong, "Lua", bukan "LUA". :)
Machado
4

Di C # .NET, Anda dapat menggunakan Kelas Kamus untuk mendapatkan hasilnya tanpa JIKA LAINNYA sebagai berikut - Yang menyenangkan tentang ini adalah:

  1. Itu bisa dibaca
  2. Kunci baru akan unik (jika tidak, Anda mendapatkan kesalahan)
  3. Urutan tidak masalah
  4. Mudah untuk menambah atau menghapus entri

Jika Anda tidak memiliki yang setara dengan Kelas Kamus, Anda dapat melakukan hal yang sama dalam fungsi pencarian / pencarian biner.

//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
// Create a Dictionary object and populate it
Dictionary<string, string> _decisionTable = new Dictionary<string, string>() { 
    { "0,0", "0,0,1" }, 
    { "0,1", "0,0,1" }, 
    { "1,0", "0,1,0" }, 
    { "1,1", "1,0,0"} 
};

//usage example: Find the values of X,Y,Z for A=1,B=0
Console.WriteLine(_decisionTable["1,0"]);
Console.Read();
Tidak ada kesempatan
sumber
1
Saya suka solusi ini, satu-satunya perubahan yang saya lakukan adalah menggunakan Kamus <Tuple <bool, bool>, Tuple <bool, bool, bool> alih-alih Kamus <string, string>. Maka Anda tidak perlu membuat string untuk mencari dan mendekonstruksi hasilnya setelah itu karena Tuples akan melakukan ini untuk Anda.
Lyise
@Lyise, Terima kasih atas komentar Anda. Anda benar sekali. Saya harus memasukkan poin bagus Anda ketika saya mendapat kesempatan.
NoChance
2

Yang Anda inginkan adalah algoritma Rete . Ini secara otomatis menyisir seperangkat aturan dan memprioritaskannya ke pohon seperti yang Anda gambarkan.

Ada sejumlah sistem "mesin aturan" komersial yang melakukan ini pada skala yang sangat besar (jutaan aturan) di mana kecepatan eksekusi sangat penting.

Alex Feinman
sumber
2

Berikut ini adalah perpustakaan Anda :) Dan Anda tidak perlu melewati K-table penuh, hanya bidang yang Anda minati :) Ini mengasumsikan bahwa operator DAN-nya di tabel kebenaran. Jika Anda ingin menggunakan lebih banyak operator, Anda harus dapat menulis ulang. Anda dapat memiliki sejumlah argumen. Ditulis python, dan diuji.

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()
grizwako
sumber
1

Petakan input menjadi nilai tunggal dan kemudian aktifkan:

#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
Deduplicator
sumber
1

Tabel pencarian yang berisi fungsi pointer dapat berfungsi dengan baik dalam beberapa situasi. Di C, misalnya, Anda dapat melakukan sesuatu seperti ini:

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();
}

Ini adalah solusi yang baik ketika jumlah input relatif kecil, karena jumlah entri dalam tabel harus 2 ^^ n di mana n adalah jumlah input. 7 atau 8 input mungkin dapat dikelola, 10 atau 12 mulai menjadi jelek. Jika Anda memiliki banyak input, cobalah menyederhanakan dengan cara lain (seperti peta Karnaugh) terlebih dahulu.

Caleb
sumber
0

Lihatlah perangkat lunak "Gorgeous Karnaugh" - ia dapat menerima tabel kebenaran yang cukup tepat sebagai sampel Anda, menerima definisi rumus boolean analitik, menerima skrip Lua untuk membuat tabel kebenaran. Selanjutnya, perangkat lunak "Gorgeous Karnaugh" menggambar K-Maps untuk input yang diambil, yang Anda dapat meminimalkan secara manual atau menggunakan "Espresso" logika minimizer, dan menghasilkan output untuk C / C ++ dan beberapa bahasa perangkat keras. Lihat halaman fitur ringkasan untuk "Gorgeous Karnaugh" - http://purefractalsolutions.com/show.php?a=xgk/gkm

Petruchio
sumber
Ini sangat mirip dengan apa yang saya butuhkan, tetapi tidak bisa mendapatkan kode C / C ++ untuk menunjukkan apa pun selain kosong ifsetelah memasukkan tabel kebenaran.
Juan
Ya, alat yang dirancang untuk meminimalkan fungsi logika - setelah memasukkan tabel kebenaran Anda harus meminimalkan fungsi logika (PoS / SoP - oleh 0 / oleh 1). Kode C ++ dapat ditemukan di jendela "Hasil minimalisasi" setelah minimalisasi.
Petruchio