说我要删除列表的最后一个元素。我可以通过添加来做到这一点:
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])
时,先前谓词处理的查询就很好了,它将留下一个选择点,然后一旦您接受它便无法终止...
我想念什么?