library(clpb)を使用できます :
まず、式を変数 Expr に代入します。
Expr = ((A + ~C)*(B + ~C)+(~(A + ~B))
.
ご了承ください:
クエリを実行すると、次のようになります。
?- use_module(library(clpb)).
true.
?- Expr=((A + ~C)*(B + ~C))+(~(A + ~B)),taut(Expr,T).
false.
述語taut /2は入力として clpb 式を取り、トートロジーの場合は T=1 を返し、式が満たされない場合は T=0 を返し、それ以外の場合は失敗します。したがって、上記のクエリが失敗したという事実は、Expr もトートロジーでもなく、満たすことができなかったことを意味します。つまり、満たすことができたということです。
また、クエリを実行することによって:
?- Expr=((A + ~C)*(B + ~C))+(~(A + ~B)),sat(Expr).
Expr = (A+ ~C)* (B+ ~C)+ ~ (A+ ~B),
sat(1#C#C*B),
sat(A=:=A).
Predicatesat/1
は、ブール式が充足可能である場合に True を返し、次の場合に上記の Expression が充足可能であるという答えを返します。
sat(1#C#C*B),
sat(A=:=A).
where'#'
はexclusive OR
が満たされるときに式 (taut/2 から充足可能であることがわかります) が満たされることを意味します1#C#C*B
。
ライブラリを使用しない別の解決策は次のとおりです。
truth(X):-member(X,[true,false]).
test_truth(A,B,C):-
truth(A),
truth(B),
truth(C),
((A->C),(B->C)->(A->C)).
例:
?- test_truth(A,B,C).
A = B, B = C, C = true ;
false.
また、あなたのコメントから正しく理解できた場合、考えられるすべての解決策を収集するために、次のように書くことができます。
?- findall([A,B,C],test_truth(A,B,C),L).
L = [[true, true, true]].
これにより、リストのリストが得られます。ここで、内側のリストは[true,true,true]
上記の例の形式を持ちます。これは、ソリューションがA=true,B=true,C=true
存在し、上記の場合、ソリューションが 1 つしかないことを意味します。
すべての矛盾を見つけるには、次のように記述できます。
truth(X):-member(X,[true,false]).
test_truth(A,B,C):-
truth(A),
truth(B),
truth(C),
not( (\+ ((\+A; C),(\+B ; C)) ; (\+A ; B)) ).
最後の行は次のように書くこともできます:
not( ( (A->C;true),(B->C;true) ) -> (A->B;true) ;true ).
例:
?- findall([A,B,C],test_truth(A,B,C),L).
L = [[true, false, true]].