可以使用prolog来确定无效推断吗?

时间:2016-10-15 00:59:59

标签: prolog logic boolean-logic clpb

如果我有以下两个处所:

  1. a - > c(a暗示c)
  2. b - > c(b暗示c)
  3. 得出的结论:

    1. a - > b(因此暗示b),
    2. 然后结论可能会显示无效,因为:

      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的结论相矛盾?如果是这样,那么这样做的简洁方法是什么?”

2 个答案:

答案 0 :(得分:2)

@coder已经使用约束给出了一个非常好的答案。

我想用一种略微不同的方式来表明结论来自场所,也使用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

  • 逻辑NOT
  • '〜' 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]].