私は7週間で7つの言語に取り組んでいますが、プロローグについて理解できないことがあります。私は次のプログラムを持っています(彼らのウォレスとグルミットプログラムに基づいています):
/* teams.pl */
onTeam(a, aTeam).
onTeam(b, aTeam).
onTeam(b, superTeam).
onTeam(c, superTeam).
teamMate(X, Y) :- \+(X = Y), onTeam(X, Z), onTeam(Y, Z).
このようにロードします
?- ['teams.pl'].
true.
しかし、それは私に次の解決策を与えません
?- teamMate(a, X).
false.
それはより単純なものを解決することができます(それは本に示されています):
?- onTeam(b, X).
X = aTeam ;
X = superTeam.
そして解決策があります:
?- teamMate(a, b).
true ;
false.
何が足りないのですか?私はgnuprologとswiplの両方で試しました。
...そしてもっとあります...
「自分のチームメイトになることはできません」という制限を移動して終了すると、次のようになります。
/* teams.pl */
onTeam(a, aTeam).
onTeam(b, aTeam).
onTeam(b, superTeam).
onTeam(c, superTeam).
teamMate(X, Y) :- onTeam(X, Z), onTeam(Y, Z), \+(X = Y).
それは私が期待する解決策を私に与えます:
?- ['teams.pl'].
true.
?- teamMate(a, X).
X = b.
?- teamMate(b, X).
X = a ;
X = c.
何が得られますか?
マットによって答えはあなたにいくつかの高レベルの考慮事項とソリューションを提供します。私の答えは、あなたにとって興味深いかもしれないし、そうでないかもしれない根本的な理由についての詳細です。
(ちなみに、Prologを学んでいる間、私はほとんど同じ質問をし、同じユーザーから非常によく似た答えを得ました。素晴らしいです。)
質問があります:
2人のプレーヤーはチームメイトですか?
Prologから回答を得るには、クエリを作成します。
?- team_mate(X, Y).
ここで、XとYはどちらも自由変数または束縛です。
述語(事実と規則)のデータベースに基づいて、Prologは証拠を見つけようとし、あなたに解決策を提供します。Prologは、プルーフツリーの深さ優先走査を実行してプルーフを検索します。
最初の実装で\+ (X = Y)
は、が何よりも優先されるため、ツリーのルートノードにあり、次の目標の前に評価されます。そして、X
またはY
が自由変数である場合、X = Y
成功する\+ (X = Y)
必要があります。つまり、失敗する必要があります。したがって、クエリは失敗する必要があります。
一方、X
またはY
が自由変数である場合は成功しますが、後でそれらを互いに統合しようとすると失敗する必要があります。その時点で、Prologは、プルーフツリーの別のブランチにプルーフが残っている場合はそれを探す必要があります。dif(X, Y)
(プルーフツリーを念頭に置いて、実装方法dif/2
を考えてみてください:dif/2
a)の引数に何らかの状態を追加するか、b)解決戦略を変更しなくても可能だと思いますか?)
そして最後に、最後に置い\+ (X = Y)
て、両方X
とY
が評価されるまでに粉砕されるように注意すると、統合は単純な比較のようになり、失敗する可能性があるため、否定は成功します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加