我正试图在Prolog中创建一个替代findall的方法。
我拥有的是:
solutions(A,T,S) :-
T,
assert(temp(A)),
fail.
solutions(A,T,S) :-
obtain([],S).
obtain(X,S) :-
retract(temp(A)),
obtain([A|X],S).
obtain(S,S).然而,这给了我不一致的结果。怎么啦?提前谢谢你。
发布于 2020-11-08 20:45:40
试试这个,我们切(!)在撤回/1和显式断言/1之后:
solutions(A,T,_) :-
T,
assertz(temp(A)),
fail.
solutions(_,_,S) :-
obtain(S).
obtain([A|S]) :-
retract(temp(A)), !,
obtain(S).
obtain([]).工作正常,但不是可重入的,第二个查询结果是错误的:
?- solutions(X,between(1,3,X),L).
L = [1, 2, 3].
?- solutions(X-R,(between(1,3,X),solutions(Y,between(1,X,Y),R)),L).
L = [3-[2-[1-[1], 1, 2], 1, 2, 3]].编辑08.11.2020:
下面是使用gensym/2的重入解决方案:
solutions(A,T,L) :-
setup_call_cleanup(
gensym('bag',B),
solutions(B,A,T,L),
retractall(temp(B,_))).
solutions(B,A,T,_) :-
T,
assertz(temp(B,A)),
fail.
solutions(B,_,_,S) :-
obtain(B,S).
obtain(B,[A|S]) :-
retract(temp(B,A)), !,
obtain(B,S).
obtain(_,[]).现在,这两个查询都可以正常工作:
?- solutions(X,between(1,3,X),L).
L = [1, 2, 3].
?- solutions(X-R,(between(1,3,X),solutions(Y,between(1,X,Y),R)),L).
L = [1-[1], 2-[1, 2], 3-[1, 2, 3]].警告:一个具有逻辑更新语义的Prolog系统
在重复撤回/1期间可能无效。
https://stackoverflow.com/questions/29217910
复制相似问题