2011-10-20 5 views
0

私はStrawberry Prolog(コンピュータラボが私の学校に持っているもの)を使用してファミリーツリーを実装しており、重複した回答を取り除きたいと思っています。 findall関数はすべての答えをリストに入れたStrawberry Prologで動作しますが、このコンパイラではsetofは存在しません。私はコンパイラを切り替えたり、setof関数をこの関数に追加することができました。後者はより良い学習体験になると思いますが、どこから始めたらいいか分かりません。Strawberry Prolog setof

誰かが他のコンパイラのsetof関数の背後にあるコードを知っていますが、これをStrawberry Prologに変換する方法はありますか?あるいは、既にStrawberry Prologにsetofと似た機能がありますか?

ありがとうございました。

答えて

0

findallの出力を単純に並べ替えることができます。もちろん、setofを実装する方がはるかに有益な方法ですが、単純ではありません。 SWI-Prologのからここでソース:

%%  setof(+Var, +Goal, -Set) is semidet. 
% 
% Equivalent to bagof/3, but sorts the resulting bag and removes 
% duplicate answers. We sort immediately after the findall/3, 
% removing duplicate Templ-Answer pairs early. 

setof(Templ, Goal0, List) :- 
    '$free_variable_set'(Templ^Goal0, Goal, Vars), 
    ( Vars == v 
    -> findall(Templ, Goal, Answers), 
     Answers \== [], 
     sort(Answers, List) 
    ; findall(Vars-Templ, Goal, Answers), 
     ( ground(Answers) 
     -> sort(Answers,Sorted), 
     pick(Sorted,Vars,List) 
     ; bind_bagof_keys(Answers,_VDict), 
     sort(Answers, Sorted), 
     pick(Sorted, Vars, Listu), 
     sort(Listu,List) % Listu ordering may be nixed by Vars 
     ) 
    ). 

あなたが見ることができるように、基本的なことだいつものfindAll ...

+0

感謝。私は成功することなくそれを実装しようとしました。私はSWI-Prologに切り替わりました。私のプログラムは動作していますが、今は別の問題があります。私が画面に印刷しているリストが長すぎて、その一部が| ...]で切り取られてしまいます。最大リストサイズを拡張したり、印刷する長さを変更するために使用できるコマンドはありますか? – Tijgerlili

+0

Nevermind。私はそれを考え出した。 :D – Tijgerlili