すでに優れた2つの回答を補足するだけです...
Prolog では、パラメーターの入力と出力を持つ "関数" としてではなく (実際にはそのように動作しますが)、ルールを定義し、変数パラメーター (インスタンス化されていない変数) をインスタンス化しようとする "述語" として考えます。ルールを真にするような方法。このプロセスでは、解決策がまったく得られない場合もあれば、1 つの解決策が得られる場合もあれば、多くの解決策が得られる場合もあります。すべての解決策が得られます。インスタンス化されていない変数のすべての組み合わせに対して、すべての述語がこの「完全な機能」を提供するわけではありません。または、インスタンス化されていない変数が多すぎると、ソリューションを提供することが論理的に非現実的になります。これらの状況のいずれかでパラメーターの動作を決定するもの、および述語に解決策があるかどうかは、述語のロジックであり、入力または出力の正式な宣言ではありません。
与えられた例を見てみましょうconcatenate
(注: これらには GNU Prolog を使用しています)。述語concatenate(L1, L2, L3)
が意味するのは、「L1 と L2 を (その順序で) 連結すると L3 が得られる」ということです。これは、「L1 と L2 が与えられた場合、L3 でそれらの連結を提供する」と言うよりも一般的であり、特定の入力と出力を意味します。
だから私が入力した場合:
concatenate( [1,2], [3,4], L3 ).
私は得る:
L3 = [1,2,3,4]
(1 ms) yes
| ?-
これは、プロローグが、示されている のインスタンス化を使用して、述語に対する 1 つの解を見つけたことを意味しますL3
。これを入力することもできます:
concatenate( L1, [3,4], [1,2,3,4] ).
そして、私は得るでしょう:
L1 = [1,2]
(1 ms) yes
| ?-
これは、プロローグが、示されている のインスタンス化を使用して、述語に対する 1 つの解を見つけたことを意味しますL1
。同様に、入力した場合、concatenate( [1,2], L2, [1,2,3,4] )
1 つの解決策が得られますL2 = [3,4]
。
もっと面白いことを試してみましょう:
concatenate( L1, L2, [1,2,3,4] ).
Prolog はこれに対する解決策を見つけますが、インスタンス化されていない変数を 2 つ用意しました。したがって、解決策には次の可能性が含まれます。
L1 = [1,2,3,4]
L2 = [] ? ;
L1 = [1,2,3]
L2 = [4] ? ;
L1 = [1,2]
L2 = [3,4] ? ;
L1 = [1]
L2 = [2,3,4] ? ;
L1 = []
L1 = [1,2,3,4] ? ;
(1 ms) yes
| ?-
これを試してみましょう:
concatenate( [1,2], L2, L3 ).
私は得る:
L3 = [1,2|L2]
| ?-
この場合、L2
andの可能性L3
は無限であるため、プロローグは一般的な解決策を示しています。
あなたの例でconcatenate( X, [2,Y], [1,1,1,2,3] )
は、同じ考え方が当てはまります。Prolog は、「X を [2,Y] と連結すると [1,1,1,2,3] が得られる」という条件を満たすX
andのインスタンス化を見つけようとします。[2,Y] は最初の要素と 2 番目の要素を持つリストです。要素。この場合、あなたが示すように、解決策は1つしかありません。Y
2
Y
このテーマのバリエーションとして、@DrH が説明するリストの概念を使用すると、次のようになります。
concatenate( X, [2|Y], [1,1,1,2,3] ).
と が得られX = [1,1,1]
ますY = [3]
。これを行った場合は次のことに注意してください。
concatenate( X, [2,Y], [1,1,1,2,3,4] ).
Y
ここでは がリストではなくアトムとして示されているため (カンマ構文のため)、「いいえ」(解決策なし)が返されます。言い換えれば、[2,Y]
あらゆる可能性で連結されたときに、X
will yieldのように見える 2 つの要素リストはありません[1,1,1,2,3,4]
。しかし、これを行った場合:
concatenate( X, [2|Y], [1,1,1,2,3,4] ).
インスタンス化されていないものをリストの末尾として示しているため、それ自体がリストであり、単なるアトムではありません (X = [1,1,1]
構文を使用)。Y = [3,4]
Y
|
@WillNess が指摘しているように、特定の述語のドキュメントでは、特定の変数をインスタンス化しないままにしておくと、述語の動作を期待する必要があることがわかります。適切に作成されたプロローグ述語は、適切に作成されていないものやより制限的なものよりも、「期待または要求することを実行する」可能性が高くなります。それは非常に有用な目的を果たす可能性があるため、より制限された述語を「悪い」ものにするわけではありません。それはそれほど役に立ちません。独自のプロローグ述語を作成するときは、これらのことを考慮してください。
プロローグは囲碁のようなものです。いくつかの単純なルールですが、多くの興味深い可能性があります。