gpt4 book ai didi

list - 有没有办法在 PROLOG 中只选择列表的第一个和最后一个元素?

转载 作者:行者123 更新时间:2023-12-04 02:29:48 25 4
gpt4 key购买 nike

我正在尝试编写一个谓词,如果 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].

或者,再次使用适当的变量名,以便我们可以看到绑定(bind):

?- 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].

关于list - 有没有办法在 PROLOG 中只选择列表的第一个和最后一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64971645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com