1

私たちのプロローグコースにはこの課題があります。週に 1 時間の Prolog を 2 か月続けた後でも、それはまだ謎に包まれています。私の思考は手続き型言語から適応できないようです。

同じ名前でアリティ 1、2、3 の述語/ファンクターを含むナレッジ ベースがあります。呼び出し形式は次​​のようになります。

search(ファンクター名、引数、S)。

答えは、アリティに関係なく、このファンクター名と引数を持つすべての出現を見つける必要があります。回答は次の形式にする必要があります。

S = functor_name(argument);
S = functor_name(argument,_);
S = functor_name(_,argument);
S = functor_name(argument,_,_);
S = functor_name(_,argument,_);
S = functor_name(_,_,argument);
false.

call を使用して、ナレッジ ベースのエントリが存在するかどうかをテストできることがわかりました。

しかし、呼び出しはファンクター名の変数では機能しないようです。ファンクター名に変数を使用する方法がわかりません。

アップデート:

私の質問は部分的に答えられました。私の新しいコードは、アリティ 1、2、および 3 について true と false を返します (以下を参照)。

search(Person,Predicate) :-
   ID = Person, Key = Predicate, current_functor(Key,1),
   call(Key,ID)
 ; ID = Person, Key = Predicate, current_functor(Key,2),
   (call(Key,ID,_);call(Key,_,ID))
 ; ID = Person, Key = Predicate, current_functor(Key,3),
   (call(Key,ID,_,_);call(Key,_,ID,_);call(Key,_,_,ID)).

更新 2:

別の部分的な回答が来ました。それは用語のリストとして S を与えますが、「その他の」引数はプレースホルダーです:

search2(Predicate, Arg, S) :-
   ( Arity = 2 ; Arity = 3 ; Arity = 4 ),
   functor(S, Predicate, Arity),
   S =.. [_,Predicate|Args],
   member(Arg, Args).

結果はかなりいいです。まだ欠落しています: 述語は括弧内にあってはならず、他の引数は、プレースホルダーとしてではなく、ナレッジ ベースから文字どおりに取得する必要があります。現在の結果は次のようになります。

 ?- search2(parent,lars,S).
S = parent(parent, lars) ;
S = parent(parent, lars, _G1575) ;
S = parent(parent, _G1574, lars) ;
S = parent(parent, lars, _G1575, _G1576) ;
S = parent(parent, _G1574, lars, _G1576) ;
S = parent(parent, _G1574, _G1575, lars).

最初から質問の仕方が間違っていたので、この質問は諦めます。私はもっ​​と具体的に尋ねるべきでした - 私はまだPrologが得意ではないので、できませんでした。

@false が最も役に立ちました。私は彼の答えを受け入れています。

4

2 に答える 2

4

ここには 2 つのアプローチがあります。1 つは「伝統的な」(1970 年代) もので、文字通り必要なものを実装します。

search(F, Arg, S) :-
   ( N = 1 ; N = 2 ; N = 3 ), % more compactly: between(1,3, N)
   functor(S, F, N),
   S =.. [_|Args],            % more compactly: between(1,N, I), arg(I,S,Arg)
   member(Arg, Args).

もう 1 つは、目標の明示的な構成を再考します。実際、 functorFと argumentsA1があればA2、orを使わずA3にすぐにゴールを書くことができます。call(F, A1, A2, A3)functor/3(=..)/2

call(F, A1, A2, A3)の代わりに使用することには多くの利点がありますGoal =.. [F, A1, A2, A3], call(Goal)。さらに、モジュール システムを使用すると、潜在的なモジュール資格の処理がFシームレスに機能します。(=..)/2すべての醜い詳細を明示的に処理する必要があるのに対し、それはより多くのコード、より多くのエラーです。

search(F,A,call(F,A)).
search(F,A,call(F,A,_)).
search(F,A,call(F,_,A)).
search(F,A,call(F,A,_,_)).
search(F,A,call(F,_,A,_)).
search(F,A,call(F,_,_,A)).

これを短縮したい場合は、むしろcall/N動的に構築します。

search(F, Arg, S) :-
   ( N = 2 ; N = 3 ; N = 4 ),
   functor(S, call, N),
   S =.. [_,F|Args],
   member(Arg, Args).

call には functor の追加の引数が必要であることに注意してくださいF

于 2014-06-10T09:45:00.153 に答える
3

「univ」演算子 を使用して=..、ゴールを動的に構築できます。

?- F=member, X=1, L=[1,2,3], Goal =.. [F, X, L], call(Goal).
F = member,
X = 1,
L = [1, 2, 3],
Goal = member(1, [1, 2, 3]) .
于 2014-06-10T09:04:01.353 に答える