我正在尝试编写一个谓词,如果X是Y的子列表,则该判断是正确的,而不考虑Y的第一项和最后一项。例如,查询listWithinList([b,c,d],[a, b,c,d,e])将返回True,但是查询listWithinList([b,c,d,e],[a,b,c,d,e])将产生False,因为e是Y的最后一个元素,不应该是X的一部分。
目前,我有,listWithinList(X,Y):-append(_,Y2,Y), append(X,_,Y2).
但是我不确定如何更改代码,以使它起到相同的作用,但是没有考虑Y的第一项和最后一项。
当您向写入_
参数时append
,它指向任意列表。如此随意以至于其长度也是任意的。
例如:
?- append(_, Suffix, [a, b, c]).
Suffix = [a, b, c] ;
Suffix = [b, c] ;
Suffix = [c] ;
Suffix = [] ;
false.
在这里_
可以代表任何名单中的[]
,[a]
,[a, b]
,[a, b, c]
。但是我不需要告诉你这个。如果您给匿名变量改_
一个专有名称,那么Prolog可以告诉您:
?- append(Prefix, Suffix, [a, b, c]).
Prefix = [],
Suffix = [a, b, c] ;
Prefix = [a],
Suffix = [b, c] ;
Prefix = [a, b],
Suffix = [c] ;
Prefix = [a, b, c],
Suffix = [] ;
false.
相反,该术语[_]
并不代表任意列表。它代表肯定有一个元素的列表。该元素(表示为_
)是任意的。
例如:
?- append([_], Suffix, [a, b, c]).
Suffix = [b, c].
或者,再次使用适当的变量名,以便我们可以看到绑定:
?- append([X], Suffix, [a, b, c]).
X = a,
Suffix = [b, c].
这一切都是从问题的定义说的:
listWithinList(X,Y):-append(_,Y2,Y), append(X,_,Y2).
接近正确。但是,两种用法_
不会“删除”每个元素。他们每个“删除”任意数量的元素。因此,您不只是排在中间:
?- listWithinList(Middle, [a, b, c, d, e]).
Middle = [] ;
Middle = [a] ;
Middle = [a, b] ;
Middle = [a, b, c] ;
Middle = [a, b, c, d] ;
Middle = [a, b, c, d, e] ;
Middle = [] ;
Middle = [b] ;
Middle = [b, c] ;
Middle = [b, c, d] ;
Middle = [b, c, d, e] ;
Middle = [] ;
Middle = [c] ;
Middle = [c, d] ;
Middle = [c, d, e] ;
Middle = [] ;
Middle = [d] ;
Middle = [d, e] ;
Middle = [] ;
Middle = [e] ;
Middle = [] ;
false.
如果要从正面和背面“删除”仅一个元素的列表,则必须编写[_]
:
listWithinList(X, Y) :-
append([_], Y2, Y),
append(X, [_], Y2).
现在的行为如下:
?- listWithinList(Middle, [a, b, c, d, e]).
Middle = [b, c, d] ;
false.
此外,需要注意的区别[_]
和[_|_]
。前者代表仅一个元素的列表。后者代表一个或多个元素的列表。在这种情况下,您不想“删除”多个元素,因此[_|_]
像其他答案之一所示,使用绝对是胡说八道。
最后,Prolog可以建议我们进一步简化:
?- append([X], Xs, Ys).
Ys = [X|Xs].
追加一个元素列表[X]
和任意列表Xs
会给出一个列表,我们也可以[X | Xs]
不使用编写该列表append
。因此,append
不需要打个电话。我可以这样写这个谓词:
list_middle(List, Middle) :-
append([_First | Middle], [_Last], List).
并像这样使用它:
?- list_middle([a, b, c, d, e], Middle).
Middle = [b, c, d] ;
false.
或像这样:
?- list_middle(List, [1, 2, 3]).
List = [_2658, 1, 2, 3, _2664].
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句