我在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] ;
之后它又冻结了。我看到这些问题是相关的,但不是如何。有人可以指出我遗失的案例吗?
编辑:两件事,这是家庭作业,我需要使用插入谓词来解决这个问题。我写了这个。
答案 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).
用例仅需要检查第一个元素是否是后者的排列,而不是反过来(反之亦然)。反气候,但我的问题的答案。