让我们使用if_/3
and (=)/3
(又名equal_truth/3
),如 @false 中所定义这个答案 https://stackoverflow.com/a/27358600/4609915!
所以新的来了,逻辑纯粹 find/3
:
find(E0,E1,[X|Xs]) :-
member_next_prev_list(E0,E1,X,Xs).
member_next_prev_list(E0,E1,X0,[X1|Xs]) :-
if_(X0=E0, X1=E1, member_next_prev_list(E0,E1,X1,Xs)).
让我们运行 OP/其他答案/一些评论提到的查询:
?- find(a,X,[a,a,b]).
X = a. % succeeds deterministically
?- find(a,X,[a,Y,b]).
X = Y. % succeeds deterministically
?- find(a,b,[a,a,b]).
false. % fails
?- find(a,X,[a,a,b,c]).
X = a. % succeeds deterministically
?- find(b,X,[a,a,b,c]).
X = c. % succeeds deterministically
现在来说一些更一般的事情:
?- find(X,Y,[a,a,b,c]).
X = a, Y = a ;
X = b, Y = c ;
false.
关于最一般的查询?由于代码是pure,我们得到逻辑上合理答案:
?- find(X,Y,List).
List = [ X,Y|_Z] ;
List = [_A, X,Y|_Z], dif(_A,X) ;
List = [_A,_B, X,Y|_Z], dif(_A,X), dif(_B,X) ;
List = [_A,_B,_C, X,Y|_Z], dif(_A,X), dif(_B,X), dif(_C,X) ;
List = [_A,_B,_C,_D,X,Y|_Z], dif(_A,X), dif(_B,X), dif(_C,X), dif(_D,X) ...
编辑2015-05-06
这是一个更简洁的变体,毫无想象力地称为findB/3
:
findB(E0,E1,[X0,X1|Xs]) :-
if_(X0=E0, X1=E1, findB(E0,E1,[X1|Xs])).
Like find/3
, findB/3
从不留下无用选择点的意义上来说是高效的,但它具有更高的内存使用率。
findC/3
尝试通过提升通用表达式来减少内存使用[X1|Xs]
:
findC(E0,E1,[X0|XXs]) :-
XXs = [X1|_],
if_(X0=E0, X1=E1, findC(E0,E1,XXs)).