【发布时间】:2017-08-14 15:31:27
【问题描述】:
我正在尝试在 Prolog 中定义一个谓词 sublist(X,Y),当列表 X 的元素都出现在列表 Y 中时,该谓词为真,其顺序与它们在 X 中的顺序相同。
我的方法是取X 的头部,在Y 中找到头部的第一个实例,并在第一个实例之前剪切列表,然后用X 的尾部重复此操作,直到尾部等于空列表。
我已经编写了辅助谓词cut(X,Y,Z),如果Z 是在Y 列表中的第一个X 实例之前切割所有内容的结果列表,则为true。
我的代码如下:
cut(_,[],[_|_]) :- false.
cut(X,[H|T],[H|T]) :- X = H, !.
cut(X,[_|T],Y) :- cut(X,T,Y).
sublist([],[]).
sublist([],[_|_]).
sublist([A|B],C) :- cut(A,C,Z), sublist(B,Z).
当我查询时
?- sublist(L,[1,2,3]).
Prolog 没有给出[1,2,3] 的所有子列表,而是给出了以下输出:
L = [] ;
L = [1] ;
L = [1, 1] ;
L = [1, 1, 1] ;
L = [1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1, 1, 1, 1, 1] ;
L = [1, 1, 1, 1, 1, 1, 1, 1, 1|...] ;
L = [1, 1, 1, 1, 1, 1, 1, 1, 1|...] ;
L = [1, 1, 1, 1, 1, 1, 1, 1, 1|...]
我看不到我的错误。谁能给我指点一下?
【问题讨论】:
-
你不需要规则
cut(_,[],[_|_]) :- false.只是它的缺失会导致看起来像cut(_,[],[_|_]).的查询失败,因为它与后续规则不匹配。你试过trace吗?或者您是否尝试仅测试cut/3本身?您创建cut/3而不仅仅是使用select/3是否有原因?