有没有办法在不离开选择点的情况下删除列表的最后一个元素?

时间:2018-07-11 16:03:08

标签: prolog

说我要删除列表的最后一个元素。我可以通过添加来做到这一点:

append(WithoutLastElement, [_], List)

但是,这留下了一个选择点!例如,尝试使用append(X, [_], [1, 2])

我可以尝试编写自己的谓词:

list_withoutlast([_Last], []). % forget the last element
list_withoutlast([Head|List], [Head|WithoutLast]) :-
    list_withoutlast(List, WithoutLast).

运行list_withoutlast([1, 2, 3], Y)之类的查询时,这显然留下了一个障碍,因为list_withoutlast([X], Y)匹配了两个头。

因此,我尝试变得更聪明:

list_withoutlast2([_Last], []). % forget the last element
list_withoutlast2([First, Second|List], [First|WithoutLast]) :-
  list_withoutlast2([Second|List], WithoutLast).

在运行list_withoutlast2([1, 2, 3], Y)之类的查询(在SWI Prolog中)时,这也会留下一个选择点,这对我来说并不明显。 list_withoutlast2([X], Var)很显然只会匹配第一个头,但是SWI序言尝试将其匹配到两个头。

我可以尝试花哨:

list_withoutlast4([Head|List], WithoutLast) :-
  list_withoutlast4(List, Head, End-End, WithoutLast).

list_withoutlast4([], _Last, WithoutLast-[], WithoutLast).
list_withoutlast4([Head|List], PrevHead, Accum-[PrevHead|End], WithoutLast) :-
  list_withoutlast4(List, Head, Accum-End, WithoutLast).

这最终正确地处理了list_withoutlast4([1, 2, 3], Y)。但是,当给定的查询如list_withoutlast4(X, [1, 2, 3])时,先前谓词处理的查询就很好了,它将留下一个选择点,然后一旦您接受它便无法终止...

我想念什么?

0 个答案:

没有答案