首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >替代findall

替代findall
EN

Stack Overflow用户
提问于 2015-03-23 18:39:08
回答 1查看 808关注 0票数 2

我正试图在Prolog中创建一个替代findall的方法。

我拥有的是:

代码语言:javascript
复制
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).

然而,这给了我不一致的结果。怎么啦?提前谢谢你。

EN

回答 1

Stack Overflow用户

发布于 2020-11-08 20:45:40

试试这个,我们切(!)在撤回/1和显式断言/1之后:

代码语言:javascript
复制
solutions(A,T,_) :- 
   T,
   assertz(temp(A)),
   fail.
solutions(_,_,S) :-
   obtain(S).

obtain([A|S]) :-
   retract(temp(A)), !,
   obtain(S).
obtain([]).

工作正常,但不是可重入的,第二个查询结果是错误的:

代码语言:javascript
复制
?- 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的重入解决方案:

代码语言:javascript
复制
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(_,[]).

现在,这两个查询都可以正常工作:

代码语言:javascript
复制
?- 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期间可能无效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29217910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档