14

だから大学のオペレーター。よくわかりません。

たとえば、次のようになります。

foo(PredList,[H|_]) :- bar(PredList,H).
foo(PredList,[_|T]) :- foo(PredList,T),!.

bar([H|_],Item) :- G =.. [H,Item],G.
bar([_|T],Item) :- bar(T,Item).

これは何をしているのですか?これは、別の述語が真かどうかを確認します。「..」の意味がわかりません。

univ 演算子なしでこれをどのように書き換えますか?

4

2 に答える 2

17

Univ ( =..) は、用語を構成要素のリストに分割するか、そのようなリストから用語を構築します。試す:

?- f(x,y) =.. L.
L = [f, x, y].

?- f(x,y,z) =.. [f|Args].
Args = [x, y, z].

?- Term =.. [g,x,y].
Term = g(x, y).

barsをバックトラックして、 PredListonで各述語を呼び出すようです。(変数を述語として使用することは移植性がありません。述語を使用することをお勧めします。)ItemfooItemcall

編集: Kaarel は正しいです。次のように、 univ をfunctor/3andに置き換えることができます。arg/3

bar([H|_],Item) :-
    functor(Goal,H,1),   % unifies Goal with H(_)
    arg(1,Goal,Item),    % unifies first argument of Goal with Item
    call(Goal).          % use this for portability
于 2010-11-09T08:18:32.173 に答える
3

私の意見では、最も適切な書き直しは次のようになります。

 bar( [H|_], Item ) :- call(H, Item).

call/nまだISOコア規格の一部ではありませんが、近い将来になる可能性があります(*)。多くのPrologシステムはすでにそれらをサポートしています。

+単純なソリューションcall/nよりも優先されるべき理由が1つあります。このソリューションは、クロージャー(**)を処理できます。(=..)/2functor/3arg/3call/n

単純な(=..)/2+functor/3ソリューションでは、最初のリスト引数のアトムでのみarg/3呼び出すことができます。bar/2例えば:

 p1(1).
 p2(2).
 ?- bar( [p1, p2], 1 ).
 Yes
 ?- bar( [p1, p2], 2 ).
 Yes
 ?- bar( [p1, p2], 3 ).
 No

クロージャーを使用すると、アトムに制限されず、コーディングの労力を節約できる可能性があります。たとえば、次のことを直接行うことができます。

 ?- bar( [=(1), =(2)], 1 ).
 Yes
 ?- bar( [=(1), =(2)], 2 ).
 Yes
 ?- bar( [=(1), =(2)], 3 ).
 No

よろしくお願いします

(*)
ドラフト技術正誤表2
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#call

(**)
誰がそれを発明したのか?:call/n述語
http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/naish.html

于 2011-12-14T11:43:41.450 に答える