2016-10-17 9 views
2

で私は1つのタイプのすべての事実を取り、それのリストを作る簡単な関数、持っているしたいと思います:/3 FORALL手

% 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すでにこの罰金をしていることを知っていると

all_facts(L) :- findall(
         (LETTER, NUMBER), 
         fact(LETTER, NUMBER), 
         L 
         ). 

しかし、私はここでその機能を実現するつもりはありません。私はPrologに比較的新しいので、その背後にある論理を理解することが欲しい。これまでのところ、私はここにいます:

all_facts([(LETTER, NUMBER)|Rest]) :- fact(LETTER, NUMBER), fail. 

これはすべての事実をすべて失敗し続けます。私の問題は実際にそれらをリストに保存することです。

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). 

例:

?- all_facts((X,Y),fact(X,Y),L). 
L = [ (a, '1'), (b, '2'), (c, '3')]. 

この背後にある基本的な考え方は、(静的ファイルからロードされた用語を主張することである@matは本からあなたが書くことができるプロローグのクラフトを示唆したように

+0

リチャードO'Keefeの本**すべてのソリューションの述語、よくある落とし穴、およびそれらを正しく実装する方法についての素晴らしい紹介については** Prolog **のCraftを参照してください。 – mat

+0

お薦めいただきありがとうございます!確認してみるよ。今のところ、この特定の問題に関するヒントはありますか? – Selbi

+0

'listing(findall)'はあまり役に立ちません。 – Fatalize

答えて

3

事実/ 2)を使用するが、動的に(assertを使用して)それらを使用するときにそれらを引っ込めることができる。

関連する問題