あなたが示すコードにはいくつかの問題があります。
不正なメタ引数
まず、組み込みの述語setof/3
には次のプロパティがあります。
| ?- predicate_property(setof(A,B,C),P).
P = (meta_predicate setof(?,0,?)) ? ;
P = built_in ? ;
P = jittable ? ;
no
これは、ISO/IEC 13211-1 の ISO 宣言に密接に対応しています。
8.10.3.2 テンプレートとモード
setof(?term, +callable_term, ?list)
2 番目の引数は、 によって実行されるゴールcall/1
です。追加の引数は必要ありません。これが0
私たちに伝えていることです。
一方、表示するコードには、別のメタ述語宣言が含まれています。
:- meta_predicate set_of(+,:,+) .
ここで、2 番目の引数は a:
です。SICStus、YAP、および SWI では、次の:
ことを意味します。この引数は、モジュール情報をさらに渡すことができるように、現在のモジュールで自動的に修飾されます。考えてみてくださいasserta(:)
。ここで、引数はゴールではなく節です。
したがって、これを修正する必要があるのは、に置き換える:
こと0
です。そして、使用する変数名でこの事実を示すことができます。つまり、Goal_0
for call(Goal_0)
、Goal_1
for call(Goal_1, Arg1)
、Goal_2
forcall(Goal_2, Arg1, Arg2)
などです。
悪いモード
1+
番目と 3 番目の引数の は不適切です。3 番目の引数は通常、結果のリストと統合されるインスタンス化されていない変数です。
プロローグのsetof/3
バロック?
% Prologs set_of はバロックです
setof/3
余計な装飾が含まれていると言いたいのでしょう。実際、setof/3
言及されているよりもはるかに用途が広いset_of/3
です。この最近の質問またはそれを取ってください。多くの場合、非常に具体的な状況について最初に考えます。たとえば、特定の映画の俳優のリストが必要だとします。次に、後でどんな映画があるか尋ねたいとします。この一般化は非常にスムーズに機能しsetof/3
ますが、それがなければ非常に複雑です。
もう 1 つの非常に便利な使用方法setof/3
は、冗長な回答を削除する場合です。
| ?- (X = 2;X=1;X=2).
X = 2 ? ;
X = 1 ? ;
X = 2 ? ;
no
| ?- setof(t, (X=2;X=1;X=2), _).
X = 1 ? ;
X = 2 ? ;
no
それを効率的にエミュレートしてみてください。
実行時のオーバーヘッド
それらはほとんど無視できます。オーバーヘッドがあると本当に信じている場合は、単にsetof/3
単一の目標で使用してください。このように、前処理はほぼ無意味です。