如果我有以下两个处所:
得出的结论:
然后结论可能会显示无效,因为:
a - >当a为真且c为真时,c对语句#1有效,并且 b - >当b为假且c为真时,c对语句#2有效。这导致 - > b当a为真且b为假时,与陈述#3直接矛盾。
或者,每个证据都有一个真值表,其中包含一个前提是真的但是结论是假的:
Truth Table with true premises and false conclusion
我的问题是:“有没有办法使用prolog来表明语句#1和#2的断言与语句#3的结论相矛盾?如果是这样,那么这样做的简洁方法是什么?”
答案 0 :(得分:2)
@coder已经使用clpb约束给出了一个非常好的答案。
我想用一种略微不同的方式来表明结论不来自场所,也使用CLP(B)。
主要区别在于我为每个前提发布了个别 sat/1
约束,然后使用taut/2
来查看结论是否来自前提。
第一个前提是:
a→c
在CLP(B)中,您可以将其表达为:
sat(A =< C)
第二个前提,即b→c,变为:
sat(B =< C)
如果a→b来自这些前提,那么taut/2
将成功与T = 1
:
?- sat(A =< C), sat(B =< C), taut(A =< B, T). false.
既然没有,我们知道结论不是来自前提。
我们可以要求CLP(B)显示反例,即将真值分配给变量,其中a→c和b→c都保持,而a→b不成立:
?- sat(A =< C), sat(B =< C), sat(~(A =< B)). A = C, C = 1, B = 0.
只需发布约束即可,以显示此案例中存在的唯一反例。如果反例不是唯一的,我们可以使用labeling/1
来生成地面实例,例如:labeling([A,B,C])
。
为了进行比较,请考虑例如:
?- sat(A =< B), sat(B =< C), taut(A =< C, T). T = 1, sat(A=:=A*B), sat(B=:=B*C).
这表明a→c跟随a→b∧b→c。
答案 1 :(得分:1)
您可以使用库(clpb):
首先为表达式赋予变量Expr:
Expr = ((A + ~C)*(B + ~C)+(~(A + ~B))
。
请注意:
'+'代表逻辑OR
'*'表示逻辑AND
'〜'
A->B
也与A+(~B)
等效。因此,上述表达式与((A->C),(B->C))-> (A->C)
相同,我们使用'->'
和+,~
','
撰写了*
。
现在,如果我们查询:
?- use_module(library(clpb)).
true.
?- Expr=((A + ~C)*(B + ~C))+(~(A + ~B)),taut(Expr,T).
false.
谓词拉紧/ 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).
谓词sat/1
如果布尔表达式是可满足的,则返回True,并给出以下表达式在以下情况下可满足的答案:
sat(1#C#C*B),
sat(A=:=A).
其中'#'
是exclusive OR
,这意味着当满足1#C#C*B
时,您的表达式(我们从绷紧/ 2中得知,这是可以满足的)。
不使用库的另一种解决方案可能是:
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
,在上述情况下,它只有一个解决方案。
找到你可以写的所有矛盾:
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]].