我最近开始在Prolog中编程,并且我正在尝试创建在列表中的给定元素之后找到元素的规则.例如,我想find(2,X,[1,2,3,4]).结果3.
我到目前为止的尝试:
find(X,Y,[X,Y|Tail]):-
!.
find(X,Y,[_|Tail]):-
find(X,Y,Tail).
Run Code Online (Sandbox Code Playgroud)
让我们使用if_/3和(=)/3(又名equal_truth/3),在这个答案中由@false定义!
所以这里出现了新的,逻辑上纯粹的 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)).
Run Code Online (Sandbox Code Playgroud)
让我们运行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.
怎么样的最一般的查询?由于代码是纯粹的,我们得到逻辑上合理的答案:
?- 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) ...
Run Code Online (Sandbox Code Playgroud)
这是一个更简洁的变体,缺乏想象力的称为findB/3:
findB(E0,E1,[X0,X1|Xs]) :- if_(X0=E0, X1=E1, findB(E0,E1,[X1|Xs])).
就像find/3,findB/3在不留下无用的选择点的意义上是有效的,但它具有更高的内存使用.
findC/3尝试通过提升公共表达式来减少内存使用[X1|Xs]:
findC(E0,E1,[X0|XXs]) :- XXs = [X1|_], if_(X0=E0, X1=E1, findC(E0,E1,XXs)).
这是一个没有剪辑的版本:
find(X,Y,[X,Y|_]).
find(X,Y,[Z|Tail]) :-
X\=Z, find(X,Y,Tail).
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2632 次 |
| 最近记录: |