prolog可以用来确定无效的推理吗?

prolog可以用来确定无效的推理吗?,prolog,logic,boolean-logic,clpb,Prolog,Logic,Boolean Logic,Clpb,如果我有以下两个场所: a->c(a意味着c) b->c(b意味着c) 以及由此得出的结论: a->b(因此a意味着b) 那么结论就可以被证明是无效的,因为: 当a为true且c为true时,a->c对语句#1有效,并且 当b为false而c为true时,b->c对语句#2有效。当a为真,b为假时,这导致a->b,这与语句#3直接矛盾 或者,根据包含一行前提为真但结论为假的真值表的证明: 我的问题是:“有没有一种方法可以使用prolog来表明语句1和语句2的断言与语句3的结论相矛盾?如果有,那

如果我有以下两个场所:

  • a->c(a意味着c)
  • b->c(b意味着c)
  • 以及由此得出的结论:

  • a->b(因此a意味着b)
  • 那么结论就可以被证明是无效的,因为:

    当a为true且c为true时,a->c对语句#1有效,并且 当b为false而c为true时,b->c对语句#2有效。当a为真,b为假时,这导致a->b,这与语句#3直接矛盾

    或者,根据包含一行前提为真但结论为假的真值表的证明:


    我的问题是:“有没有一种方法可以使用prolog来表明语句1和语句2的断言与语句3的结论相矛盾?如果有,那么什么是一种清晰简洁的方法呢?”

    您可以使用库(clpb)

    首先将表达式指定给变量Expr:

    Expr=((A+~C)*(B+~C)+(~(A+~B))

    请注意:

    • “+”表示逻辑或

    • “*”表示逻辑和

    • “~”表示逻辑非 同样
      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.
    
    谓词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).
    
    谓词
    sat/1
    在布尔表达式可满足时返回True,并在以下情况下给出上述表达式可满足的答案:

    sat(1#C#C*B),
    sat(A=:=A).
    
    其中,
    “#”
    的排他或
    ,这意味着当满足
    1#C#C*B
    时,您的表达式(我们从taut/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, false, true]].
    
    此外,如果我从您的评论中正确理解,请收集您可以编写的所有可能的解决方案:

    ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, true, 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)) ).
    
    它给出了一个列表列表,在上面的示例中,内部列表的形式为
    [true,true,true]
    ,这意味着一个解决方案是
    a=true,B=true,C=true
    ,在上面的示例中,它只有一个解决方案

    要找出所有矛盾,你可以写:

    ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, true, 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 ).
    
    例如:

    ?- test_truth(A,B,C).
    A = B, B = C, C = true ;
    false.
    
      ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, false, true]].
    

    您可以使用库(clpb)

    首先将表达式指定给变量Expr:

    Expr=((A+~C)*(B+~C)+(~(A+~B))

    请注意:

    • “+”表示逻辑或

    • “*”表示逻辑和

    • “~”表示逻辑非 同样
      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.
    
    谓词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).
    
    谓词
    sat/1
    在布尔表达式可满足时返回True,并在以下情况下给出上述表达式可满足的答案:

    sat(1#C#C*B),
    sat(A=:=A).
    
    其中,
    “#”
    的排他或
    ,这意味着当满足
    1#C#C*B
    时,您的表达式(我们从taut/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, false, true]].
    
    此外,如果我从您的评论中正确理解,请收集您可以编写的所有可能的解决方案:

    ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, true, 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)) ).
    
    它给出了一个列表列表,在上面的示例中,内部列表的形式为
    [true,true,true]
    ,这意味着一个解决方案是
    a=true,B=true,C=true
    ,在上面的示例中,它只有一个解决方案

    要找出所有矛盾,你可以写:

    ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, true, 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 ).
    
    例如:

    ?- test_truth(A,B,C).
    A = B, B = C, C = true ;
    false.
    
      ?- findall([A,B,C],test_truth(A,B,C),L).
    L = [[true, false, true]].
    

    @编码器已经给出了一个非常好的答案,使用约束

    我想用一种稍有不同的方式来证明结论并非基于前提,也使用CLP(B)

    主要区别在于,我为每个前提发布了单独的
    sat/1
    约束,然后使用
    taut/2
    查看结论是否遵循前提

    第一个前提是:

    a→c

    在CLP(B)中,您可以表示为:

    sat(A =< C)
    
    既然没有,我们知道结论不是从前提出发的

    我们可以要求CLP(B)显示一个反例,即,将真值分配给变量,其中a&rightarrow;c和B&rightarrow;c均成立,而a&rightarrow;B不成立:

    ?- sat(A =< C), sat(B =< C), sat(~(A =< B)). A = C, C = 1, B = 0.
    这表明a&rightarrow;c跟在a&rightarrow;b后面∧ b&rightarrow;c.

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

    我想用一种稍有不同的方式来证明结论并非基于前提,也使用CLP(B)

    主要区别在于,我为每个前提发布了单独的
    sat/1
    约束,然后使用
    taut/2
    查看结论是否遵循前提

    第一个前提是:

    a&rightarrow;c

    在CLP(B)中,您可以表示为:

    sat(A =< C)
    
    既然没有,我们知道结论不是从前提出发的

    我们可以要求中电(B)展示一个反例,即:。,