簡體   English   中英

減少布爾表達式

[英]Reducing a boolean expression

我有一個表達,假設,

a = 1 && (b = 1 || b != 0 ) && (c >= 35 || d != 5) && (c >= 38 || d = 6)

我希望它減少到,

a = 1 && b != 0 && (c >= 38 || d = 6)

有沒有人有什么建議? 指向任何算法的指針?

Nota Bene:我相信Karnaugh Map或Quine-McCluskey不是一個選擇。 由於這些方法不處理灰色案例。 我的意思是,表達只能減少,就像A或A'或任何東西,或說黑色或白色或缺乏顏色。 但是在這里,我有灰色陰影,正如大家們所看到的那樣。

解決方案:我已經在Clojure中為此編寫了程序。 我使用了包含函數值的地圖。 這非常方便,只是幾個組合的一些規則,你很好。 謝謝你的有用答案。

我認為你應該能夠通過使用約束處理規則來實現你想要的。 您需要編寫簡化OR和AND表達式的規則。

主要的困難是約束蘊涵檢查,告訴你哪些部分可以丟棄。 例如,(c> = 35 || d!= 5)&&(c> = 38 || d = 6)簡化為(c> = 38 || d = 6),因為前者是后者所必需的,即,后者更具體。 但是對於OR表達式,您需要選擇更通用的部分。

谷歌發現了一篇關於CHR擴展的文章,其中包含用戶定義約束的蘊涵檢查 我不知道CHR能夠告訴你是否需要這樣的擴展。

我相信這些事情是在約束邏輯編程中定期完成的。 不幸的是,我沒有足夠的經驗來提供更准確的細節,但這應該是一個很好的起點。

一般原則很簡單:未綁定的變量可以具有任何值; 當你針對不等式進行測試時,它的一組可能值受到一個或多個間隔的限制。 當/如果這些間隔收斂到單個點時,該變量將綁定到該值。 如果,OTOH,任何這些不等式被認為對於間隔中的每個值都是不可解的,則發生[編程]邏輯故障。

另請參閱示例,了解如何使用swi-prolog在實踐中完成此操作。 希望您能找到基礎算法的鏈接或參考,因此您可以在您選擇的平台中重現它們(甚至可以找到現成的庫)。

更新:我嘗試使用swi-prolog和clpfd重現您的示例,但沒有得到我預期的結果,只有接近的結果。 這是我的代碼:

?- [library(clpfd)].
simplify(A,B,C,D) :-
    A #= 1 ,
    (B #= 1 ; B #\= 0 ) ,
    (C #>= 35 ; D #\= 5) ,
    (C #>= 38 ; D #= 6).

我的結果,回溯(插入換行符以便於閱讀):

10 ?- simplify(A,B,C,D).

A = 1,
B = 1,
C in 38..sup ;

A = 1,
B = 1,
D = 6,
C in 35..sup ;

A = 1,
B = 1,
C in 38..sup,
D in inf..4\/6..sup ;

A = 1,
B = 1,
D = 6 ;

A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;

A = 1,
D = 6,
B in inf.. -1\/1..sup,
C in 35..sup ;

A = 1,
B in inf.. -1\/1..sup,
C in 38..sup,
D in inf..4\/6..sup ;

A = 1,
D = 6,
B in inf.. -1\/1..sup.

11 ?- 

因此,該計划產生了8個結果,其中包括您感興趣的2個(第5和第8個):

A = 1,
B in inf.. -1\/1..sup,
C in 38..sup ;

A = 1,
D = 6,
B in inf.. -1\/1..sup.

另一個是冗余的,也許可以使用簡單的,可自動化的邏輯規則來消除:

1st or 5th ==> 5th          [B == 1  or B != 0 --> B != 0]
2nd or 4th ==> 4th          [C >= 35 or True   --> True  ]
3rd or 1st ==> 1st ==> 5th  [D != 5  or True   --> True  ]
4th or 8th ==> 8th          [B == 1  or B != 0 --> B != 0]
6th or 8th ==> 8th          [C >= 35 or True   --> True  ]
7th or 3rd ==> 3rd ==> 5th  [B == 1  or B != 0 --> B != 0]

我知道成為一般解決方案還有很長的路要走,但正如我所說,希望這是一個開始......

PS我使用“常規”AND和OR( ,; )因為clpfd的那些( #/\\#\\/ )給出了一個非常奇怪的結果,我無法理解自己...也許更有經驗的人可以投射一些它...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM