Prolog中的逻辑等价

时间:2013-05-23 00:34:42

标签: prolog logic-programming

我有两个表达式,用Prolog列出所有位列表:

bit(0).
bit(1).

bitlist1([]).
bitlist1([B|Bs]) :-
    bit(B),
    bitlist1(Bs).

bitlist2([]).
bitlist2([B|Bs]) :-
    bitlist2(Bs),
    bit(B).

我无法确定它们在逻辑上是否相同,即使它们都列出了所有位列表。

当我使用SWI-Prolog时,我得到了以下输出:

?- bitlist1(Bs).
Bs = [] ;
Bs = [0] ;
Bs = [0, 0] ;
Bs = [0, 0, 0] ;
Bs = [0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0, 0, 0, 0, 0] ;
Bs = [0, 0, 0, 0, 0, 0, 0, 0, 0|...] ;
...

?- bitlist2(Bs).
Bs = [] ;
Bs = [0] ;
Bs = [1] ;
Bs = [0, 0] ;
Bs = [1, 0] ;
Bs = [0, 1] ;
Bs = [1, 1] ;
Bs = [0, 0, 0] ;
Bs = [1, 0, 0] ;
Bs = [0, 1, 0] ;
Bs = [1, 1, 0] ;
Bs = [0, 0, 1] ;
Bs = [1, 0, 1] ;
Bs = [0, 1, 1] ;
Bs = [1, 1, 1] ;
Bs = [0, 0, 0, 0] ;
...

bitlist1开始列出仅包含零的所有位列表,然后开始列出所有其他位列表,但这实际上不能被视为Prolog列出的无穷无尽的包含零的位列表。

bitlist2列出了每个长度的01的所有组合,然后继续使用长度更长的位列表。

因此它们在逻辑上等效于imo,只有位列表的输出顺序不同。

也许任何人都可以确认我的猜测或解释为什么这两个表达式在逻辑上不相同?会很棒。

4 个答案:

答案 0 :(得分:1)

引用Vannoord

  

两个表达式在逻辑上是否等价的问题对于任何“有趣”逻辑都是不可判定的。

然后,由于Prolog搜索的不完整性,您应该在某种程度上限制您的证明标准。我会说明等同于

这一事实

对于任何给定的N,不可能找到失败的长度(L,N),bitlist1(L),bitlist2(L)。 确实

2 ?- length(L,N), bitlist1(L), bitlist2(L).
L = [],
N = 0 ;
L = [0],
N = 1 ;
L = [1],
N = 1 ;
L = [0, 0],
N = 2 ;
L = [0, 1],
N = 2 ;
L = [1, 0],
N = 2 ;
L = [1, 1],
...

答案 1 :(得分:1)

在逻辑层面上,两个谓词都是等价的,因为规则中的“,”被解释为可交换的逻辑连接(检查这一点的最简单方法是查看A& B的真值表 - > C和B& A - > C,但也有后续的微积分或其他一些证明微积分。)

对于纯prolog程序,逻辑等效谓词的答案集是相同的。由于prolog使用深度优先搜索作为搜索策略,因此一个预测可能不会终止,以防其他人执行:

?- bitlist1([a|Xs]).
false.

?- bitlist2([a|Xs]).
^CAction (h for help) ? abort
% Execution Aborted

原因是prolog试图一个接一个地证明目标。在bitlist1的情况下,第一个目标是位(B),其中prolog可以立即决定位(a)不成立。在bitlist2的情况下,prolog首先尝试证明bitlist2(Bs)并递归地为Bs列表的尾部执行此操作,这导致无限递归。因此,即使两个谓词在逻辑上等价,它们的行为也不同。

对于查看解决方案的问题,您可以尝试按增加的长度枚举列表:

?- length(X,_), bitlist1(X).
X = [] ;
X = [0] ;
X = [1] ;
X = [0, 0] ;
X = [0, 1] ;
X = [1, 0] ;
X = [1, 1] ;
X = [0, 0, 0] ;
X = [0, 0, 1] ;
X = [0, 1, 0] .

?- length(X,_), bitlist2(X).
X = [] ;
X = [0] ;
X = [1] ;
X = [0, 0] ;
X = [1, 0] ;
X = [0, 1] ;
X = [1, 1] ;
X = [0, 0, 0] ;
X = [1, 0, 0] ;
X = [0, 1, 0] .

长度谓词给出列表与其长度之间的关系。我们现在依赖于length(X,_)生成长度增加的自由变量列表这一事实。然后在固定大小的列表上调用目标位列表(1/2),prolog将在回溯并尝试下一个更大的列表之前找到该大小的所有解决方案。

请注意,此技巧仅重新排序解决方案,但一般不会更改终止:

?- X=[a|Xs], length(X,_), bitlist2(X).
^CAction (h for help) ? abort
% Execution Aborted

这仍然失败,因为prolog需要检查所有列表X不要以a开头,但检查只在递归目标之后进行。

答案 2 :(得分:0)

在纯逻辑中,操作顺序无关紧要,因为一切都是幂等函数。因此,只要您没有任何割伤或副作用,A, BB, A都是等效的。

答案 3 :(得分:0)

我不确定你应该讨论谓词的纯逻辑含义,然后用实际的Prolog程序来证明它。

例如,

你的第一个谓词实际上永远不会用完0.没有“后记”,或者“搜索树中的后缀肯定永远不会被访问。这是当然,如果您使用它来生成答案;使用它进行验证不会表现出这种行为。