首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Forall/3手写

Forall/3手写
EN

Stack Overflow用户
提问于 2016-10-17 17:16:49
回答 1查看 301关注 0票数 2

我希望有一个简单的函数,它接受一种类型的所有事实并列出它:

代码语言:javascript
复制
% Facts
fact('a','1').
fact('b','2').
fact('c','3').

% Call
all_facts(L) :- ......

% Expected
27 ?- all_facts(L).
L = [ ('a', '1'), ('b', '2'), ('c', '3')].

我知道forall/3已经很好地做到了这一点,并且可能是任何实际场景中的首选用法:

代码语言:javascript
复制
all_facts(L) :- findall(
                        (LETTER, NUMBER),
                        fact(LETTER, NUMBER),
                        L
                       ).

但我并不是为了这里的功能而尝试实现这一点。我想了解它背后的逻辑,因为我是Prolog的新手。到目前为止,我在这里:

代码语言:javascript
复制
all_facts([(LETTER, NUMBER)|Rest]) :- fact(LETTER, NUMBER), fail.

这按顺序检查所有事实,因为它总是失败。我的问题是将它们保存在一个列表中。

EN

回答 1

Stack Overflow用户

发布于 2016-10-17 23:40:10

正如@mat从《Prolog的手艺》一书中建议的那样,你可以这样写:

代码语言:javascript
复制
all_facts( Template, Enumerator, List ) :-
        asserta( 'find all'( [] ) ),
        call( Enumerator ),
        asserta( 'find all'( {Template} ) ),
        fail
    ;
        'all found'( [], List ).

'all found'( SoFar, List ) :-
    retract( 'find all'( Item ) ),!,
    'all found'( Item, SoFar, List ). 

'all found'( [], List, List ).

'all found'( {Template}, SoFar, List ) :-
    'all found'( [Template|SoFar], List ).

示例:

代码语言:javascript
复制
?- all_facts((X,Y),fact(X,Y),L).
L = [ (a, '1'), (b, '2'), (c, '3')].

这背后的基本思想是断言静态(事实/2)但动态(使用断言)从您的文件加载的术语,以便能够在使用它们时收回它们。

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

https://stackoverflow.com/questions/40082552

复制
相关文章

相似问题

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