質問

したがって、大学オペレーター。私はそれを正確に理解していません。

たとえば、これ:

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

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

大学オペレーターなしでこれをどのように書き直しますか?

役に立ちましたか?

解決

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

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

bar 各述語を呼び出すようです PredList の上 Item, 、 と foo バックトラッキング Items。 (変数を述語として使用することはポータブルではありません; call 述語を好むべきです。)

編集: :Kaarelは正しいです、大学はに置き換えることができます functor/3arg/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

他のヒント

私の意見で最も適切な書き換えは次のとおりです。

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

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

理由が1つあります call/n シンプルよりも優先する必要があります (=..)/2functor/3 + arg/3 ソリューション。 call/n ソリューションは閉鎖を処理できます(**)。

シンプルで (=..)/2functor/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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top