具有更多确定性的 Prolog append/3 实现? [英] Prolog append/3 realization with more determinism?
问题描述
append(X,[Y],Z)
找到最后一个元素是民间常识列表Z
和剩余列表X
的Y
.
It is folk knowledge that append(X,[Y],Z)
finds the last element
Y
of the list Z
and the remaining list X
.
但是拥有自定义谓词last/3
有一些优势,即它可以在不离开选择点的情况下做出反应:
But there is some advantage of having a customized predicate last/3
,
namely it can react without leaving a choice point:
?- last([1,2,3],X,Y).
X = 3,
Y = [1,2]
?- append(Y,[X],[1,2,3]).
Y = [1,2],
X = 3 ;
No
有没有办法实现不同的实现append/3
这也不会在上面的例子?
Is there a way to realize a different implementation of
append/3
which would also not leave a choice point in the
above example?
P.S.:我在比较:
/**
* append(L1, L2, L3):
* The predicate succeeds whenever L3 unifies with the concatenation of L1 and L2.
*/
% append(+List, +List, -List)
:- public append/3.
append([], X, X).
append([X|Y], Z, [X|T]) :- append(Y, Z, T).
和(如格特扬·范·诺德):
And (à la Gertjan van Noord):
/**
* last(L, E, R):
* The predicate succeeds with E being the last element of the list L
* and R being the remainder of the list.
*/
% last(+List, -Elem, -List)
:- public last/3.
last([X|Y], Z, T) :- last2(Y, X, Z, T).
% last2(+List, +Elem, -Elem, -List)
:- private last2/4.
last2([], X, X, []).
last2([X|Y], U, Z, [U|T]) :- last2(Y, X, Z, T).
推荐答案
一种方法是使用 foldl/4
和适当的帮助谓词:
One way to do it is to use foldl/4
with the appropriate help predicate:
swap(A, B, B, A).
list_front_last([X|Xs], F, L) :-
is_list(Xs),
foldl(swap, Xs, F, X, L).
应该是这样:
?- list_front_last([a,b,c,d], F, L).
F = [a, b, c],
L = d.
?- list_front_last([], F, L).
false.
?- list_front_last([c], F, L).
F = [],
L = c.
?- Ys = [y|Ys], list_front_last(Ys, F, L).
false.
尝试看看是否可以从定义中省略 is_list/1
.
Try to see if you can leave out the is_list/1
from the definition.
这篇关于具有更多确定性的 Prolog append/3 实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!