Prolog で古典的なarg述語を実装するように求める演習で問題が発生しました。
arg(?Arg, +Term, ?Value)
Arg は、Term の引数リスト内の引数のインデックスです。値 この引数の値です。
例えば:
arg(1, t(f(X),Y,a), Value)
Value = f(X).
f(x) は t メイン ファンクターの引数リストの最初の引数であるためです。
だから私はこの方法で univ =.. 述語を使用して演習を解決しようとしています:
argom(ArgIndex,Term,ValueArg):- Term =.. [_|ArgsList],
element_n(ArgIndex,ArgsList,ValueArg).
element_n(1,[ValueArg,_],ValueArg).
element_n(N,[_,Tail],ValueArg):- N1 is N-1,
element_n(N1,Tail,ValueArg).
argom関係は、述語に組み込まれたargの私の個人的な実装です...
問題は、解決策が機能しないことです...アイデアは、次のようなargom述語があるということです:
- ArgIndex : 取得する引数のインデックス。
- f(a,b,c) のような式である用語
- ValueArg : ArgIndexをインデックスとして持つ引数の値を rappresent する
したがって、用語としてf(a,b,c)があり、ArgIndexが 1 の場合、ArgValueはaでなければなりません。
unive組み込みの述語を使用して、 Termから始めて、ヘッドにTermのメイン ファンクターがあり、テール ( ArgsListという名前) にメイン ファンクターの引数リストがあるリストを作成します。
n 番目の引数を取得するため、ArgsList の n 番目の要素を取得し、それを取得するために、ArgIndex、ArgsList、ValueArg を取るelement_nリレーションを定義します。
リストの最初の要素の場合、 ArgIndex値は 1 であり、基本ケースが一致します。
element_n(1,[ValueArg,_],ValueArg).
したがって、ValueArg は ArgsList 引数リストの先頭にあり、それを統合します。
それ以外の場合は、ルールを呼び出して、ArgsList の n 番目の要素を取得します
問題は、私が相談してもうまくいかず、答えは常に次のとおりです。最初の要素を取得しようとしても失敗します(これは、基本ケースルールを使用する最も単純なケースです)
トレースを見ると、同じ状況があります。
[trace] 9 ?- argom(1,f(a,b,c),a).
Call: (6) argom(1, f(a, b, c), a) ? creep
Call: (7) f(a, b, c)=..[_G3148|_G3149] ? creep
Exit: (7) f(a, b, c)=..[f, a, b, c] ? creep
Call: (7) element_n(1, [a, b, c], a) ? creep
Fail: (7) element_n(1, [a, b, c], a) ? creep
Fail: (6) argom(1, f(a, b, c), a) ? creep
false.
したがって、それは「メイン ファンクタの最初の引数が a であることは TRUE ですか?」と言って Argom ルールを呼び出します。
それは正しい方法でuniv =..組み込みの述語を使用して、リスト[f, a, b, c]を my Term f(a, b, c)から生成します。
ここでelement_n述語を呼び出しますが、これが基本ケースであるため、ValueArgをリストの先頭と統合する必要がありますが、失敗します
私も質問しようとしました: ArgIndex 値が 1 で、Term が f(a,b,c) の場合、ValueArg の値は何ですか?
[trace] 10 ?- argom(1,f(a,b,c),ValueArg).
Call: (6) argom(1, f(a, b, c), _G3483) ? creep
Call: (7) f(a, b, c)=..[_G3553|_G3554] ? creep
Exit: (7) f(a, b, c)=..[f, a, b, c] ? creep
Call: (7) element_n(1, [a, b, c], _G3483) ? creep
Fail: (7) element_n(1, [a, b, c], _G3483) ? creep
Fail: (6) argom(1, f(a, b, c), _G3483) ? creep
false.
したがって、問題は、このルールでリストの先頭を ValueArg と統合するのに何らかの問題があるように見えることです。
element_n(1,[ValueArg,_],ValueArg).
なんで?