关于SWI Prolog中列表的规则匹配
最近我开始学习Prolog,作为练习,我尝试实现一个谓词关于SWI Prolog中列表的规则匹配,prolog,Prolog,最近我开始学习Prolog,作为练习,我尝试实现一个谓词倒数第二个/2,给出列表中不会回溯的倒数第二个元素 当一个人使用cuts时,这个问题很小,但我尝试以与不使用cuts的last/2谓词的SWI Prolog实现类似的方式实现谓词: penultimate([X1, X2 | Rest], Elem) :- penultimate_([X1, X2 | Rest], X1, X2, Elem). penultimate_([], X1, _, X1). penultimate_([_]
倒数第二个/2
,给出列表中不会回溯的倒数第二个元素
当一个人使用cuts时,这个问题很小,但我尝试以与不使用cuts的last/2
谓词的SWI Prolog实现类似的方式实现谓词:
penultimate([X1, X2 | Rest], Elem) :-
penultimate_([X1, X2 | Rest], X1, X2, Elem).
penultimate_([], X1, _, X1).
penultimate_([_], _, X2, X2).
penultimate_([X1, X2 | Rest], _, _, Penultimate) :-
penultimate_(Rest, X1, X2, Penultimate).
当列表的长度为偶数时,此代码按预期工作,但当使用奇数长度的列表馈送时,我得到以下结果:
?- penultimate([1,2,3], X).
X = 2 ;
false.
我能想到的唯一原因是,SWI Prolog匹配系统将我程序中的规则视为与一个元素列表进行匹配的可能性,即使规则头中的列表至少需要2个元素。这是正确的吗?试试:
penultimate([X1, X2 | Rest], Penultimate) :-
penultimate(Rest, X1, X2, Penultimate).
penultimate([], Penultimate, _, Penultimate).
penultimate([X3| Rest], _, X2, Penultimate) :-
penultimate([X2, X3| Rest], Penultimate).
电话样本:
| ?- penultimate([1,2,3,4,5], P).
P = 4
yes
| ?- penultimate([1,2,3,4], P).
P = 3
yes
| ?- penultimate([1,2,3], P).
P = 2
yes
| ?- penultimate([1,2], P).
P = 1
yes
| ?- penultimate([1], P).
no
大多数Prolog系统上的索引可以区分空列表(原子)或非空列表(复合术语),但通常不会在列表中执行深度索引。尝试:
penultimate([X1, X2 | Rest], Penultimate) :-
penultimate(Rest, X1, X2, Penultimate).
penultimate([], Penultimate, _, Penultimate).
penultimate([X3| Rest], _, X2, Penultimate) :-
penultimate([X2, X3| Rest], Penultimate).
电话样本:
| ?- penultimate([1,2,3,4,5], P).
P = 4
yes
| ?- penultimate([1,2,3,4], P).
P = 3
yes
| ?- penultimate([1,2,3], P).
P = 2
yes
| ?- penultimate([1,2], P).
P = 1
yes
| ?- penultimate([1], P).
no
大多数Prolog系统上的索引可以区分空列表(原子)或非空列表(复合术语),但通常不会在列表中执行深度索引