Prolog述語定義の入力パラメータと出力パラメータに違いはありますか? これは、Scheme や C などの他の言語と比べてどうですか?
2 に答える
あなたの質問を理解していただければ幸いです。Prolog で統合がどのように実装されているかを調べる必要があります。ともかく:
簡単に言えば、Prolog述語への引数を入力、出力、または入力/出力として宣言する組み込みの方法はありません。
C では、次のように言えます。
void foo(int const *a, int *b)
{
*b += *a;
}
のコンテキストではfoo
、a
は入力引数であり、b
は出力引数であると主張できます。Prolog では、述語を記述するときにこの表記法を使用できますが、述語定義の先頭で、述語が呼び出されるときに引数がバインドまたは自由変数でなければならないことを宣言する方法がありません。とにかく、純粋な Prolog のほとんどの述語には、述語の使用方法に応じて、input、output、またはinput/outputの引数があります。多くの例については、SWI-Prolog のリスト ライブラリを参照してください。
もちろん、引数がインスタンス化されること、または自由変数であることを要求できますが、これは述語定義の本体で行われます。
add_2(A, B) :- integer(A), var(B), B is A+2.
これを次と比較してください。
plus_2(A, B) :- integer(A), integer(B), B =:= A+2.
integer/1
これは、A に 2 を加算して結果を Bで統一する代わりに、B=A+2 が真であるかどうかをチェックvar/1
します。
Prolog を使った非常に限られた経験の中で、十分な引数が次のいずれかにインスタンス化されている限り機能する述語を定義しようとする人がいることに気付きました。
- 述語のロジックに従って他の変数をインスタンス化する
- 述語によって記述された引数間の関係が成り立つかどうかを推測します。
たとえばlength(List, Integer)
、リストの長さを教えたり、指定された長さのインスタンス化されていない変数のリストを作成したり、リストが長いかどうかを確認したりできます。
ただし、できることは、述語定義の先頭に基本用語を含めることです。たとえば、foo(1)
. この種の述語はファクトと呼ばれます。先頭に基底項がある節は、再帰述語の再帰の終わりを定義する通常の方法です。
Prolog 定義の入出力パラメーターに違いはありますか?
いいえ、実際には、パラメーターは使用方法に応じていずれかになります。ボリスの長さの例は、長さを計算できるため、良い例です。
?- length([1,2,3], X).
X = 3.
または、回答をテストします。
?- length([1,2,3], 3).
true.
または、指定された長さのリストを生成します。
?- length(X, 3).
X = [_G273, _G276, _G279].
または、リストと長さを生成することもできます:
?- length(X, Y).
X = [],
Y = 0 ;
X = [_G15],
Y = 1 ;
X = [_G15, _G18],
Y = 2 ;
...
したがって、どちらの引数length/2
もインスタンス化できるかどうかがわかりますが、それでも意味のある答えが得られます。Prolog のすべての述語がこのように柔軟であるとは限りませんが、多くは柔軟です。
これは、scheme や C などの他の言語と比べてどうですか?
これがProlog と他の言語の主な違いです。あなたがそれを理解するのを助けるために類似した振る舞いをする、よりよく知られている言語は他にありません。これは、とりわけ、暗黙的な「戻り値」がないことを意味します。結果を返すためのパラメーターが必要ですが、1 つの結果パラメーターに限定されるわけではありません。への両方の引数length/2
がインスタンス化されていない場合、それらは両方とも戻り値として機能していました。
慣例により、一般的なケースでは入力パラメーターが出力パラメーターの前に来るように述語を作成する必要があります (または、少なくとも、選択した名前の賢明な方法で)。