Prolog中的排列谓词

时间:2017-03-29 15:30:30

标签: recursion prolog logic

我在Prolog中编写了以下内容(我正在使用版本7.4.0-rc1),试图定义一个谓词insertPermutation/2,当且仅当两个参数都是列表时才是真的,一个是另一个的排列

delete(X,[X|T],T). % Base case, element equals head.
delete(X,[A|B],[A|C]) :- delete(X,B,C). % And/or repeat for the tail.

insert(X,Y,Z) :- delete(X,Z,Y). % Inserting is deletion in reverse.

insertPermutation([],[]). % Base case.
insertPermutation([H|T],P) :- insertPermutation(Q,T), insert(H,Q,P). % P permutation of T, H inserted.

我已经意识到删除对于上面的帮助器谓词来说不是一个好名字。我们需要编写这些谓词,并且我们不能使用内置谓词。这就是为什么我用这种方式编写上面的代码,我选择了我做的名字(因为我先写了它来删除一个元素)。当且仅当第三个参数是一个列表时,它才是真的,等于第二个参数中的列表,第一个参数的第一个参数被删除。

insertPermutation谓词递归地测试P是否等于第一个列表尾部的排列,并将头部添加到置换中的任何位置。这种方式适用于两个都是空列表的基本情况。

但是,置换谓词的行为并不像我想要的那样。例如,查询

?- insertPermutation([1,2,2],[1,2,3]).

Prolog不会返回false,而是冻结。查询

?- insertPermutation(X,[a,b,c]).

Prolog回应

X = [a, b, c] ;
X = [b, a, c] ;
X = [c, a, b] ;
X = [a, c, b] ;
X = [b, c, a] ;
X = [c, b, a] ;
之后它又冻结了。我看到这些问题是相关的,但不是如何。有人可以指出我遗失的案例吗?

编辑:两件事,这是家庭作业,我需要使用插入谓词来解决这个问题。我写了这个。

1 个答案:

答案 0 :(得分:0)

答案是改变最后一行

% P permutation of T, H inserted.
insertPermutation([H|T],P) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P).

% P permutation of T, H inserted.
insertPermutation(P,[H|T]) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P). 

用例仅需要检查第一个元素是否是后者的排列,而不是反过来(反之亦然)。反气候,但我的问题的答案。