【发布时间】:2017-03-29 13:24:40
【问题描述】:
我正在尝试编写一个谓词permutation/2,这样当且仅当两个参数都是列表时,它才是真的,一个是另一个的排列。为此,我编写了两个辅助谓词delete/3 和insert/3。当且仅当第三个参数是第二个参数时,第一个为真,两个列表都删除了第一个参数中元素的第一个实例。当且仅当第三个参数等于插入了第一个参数(元素)的第二个参数时,第二个才是真的。
delete(X,[X|T],T). % Base case, element equals head.
delete(X,[A|B],[A|C]) :- delete(X,B,C). % Else, repeat for the tail.
insert(X,[],[X]). % Base case.
insert(X,[H|T],B) :- delete(H,B,U), insert(X,T,U). % Delete all elements from B.
permutation([],[]). % Base case.
permutation([H|T],P) :- permutation(Q,T), insert(H,Q,P). % P a permutation of T, H inserted.
我的想法是查询
?- insert(A,B,X).
对于给定的 A,B 应该返回所有实例化 X 的方式,使其等于列表 B,其中添加了元素 A。但是,它不会这样做:
?- insert(3,[1,2],X).
X = [1, 2, 3] ;
X = [1, 3, 2] ;
ERROR: Out of global stack
我认为这是因为我定义谓词的方式,检查第三个参数中的列表减去第二个参数中列表的每个元素是否等于仅包含第一个参数的列表,而不是建设性地定义它,但是我很难以另一种方式解决这个问题。然后,排列谓词应检查其第二个参数中的列表是否是递归排列,方法是检查 P 是否是第一个列表的尾部的排列,其中头部随机插入。感谢您的帮助!
【问题讨论】:
-
也许你可以问:“为什么我对
insert/3的定义被破坏了?”? -
您可以在github.com/SWI-Prolog/swipl/blob/master/library/lists.pl 中查看lists.pl,您可以在其中找到许多“教科书”谓词。我首先在 Sterling 和 Shapiro 的教科书“The Art of Prolog”中发现了这样的谓词。也许您可以阅读教科书?