カットフェイルは、誤解を招くアンチパターンです。次のように原文で何かを言う方がはるかに良いでしょう:
bird(eagle).
bird(penguin).
flightless(penguin).
can_fly(X) :- bird(X), \+ flightless(X).
この問題の優れたより詳細な議論については、@ boris の回答を参照してください。
これで、このデータベースができました。少し分かりやすいように名前を入れてみます。
married(bill, hillary).
married(barack, michelle).
lovers(bill, michelle).
ここであなたが言いたいのは、浮気をしていない限り、既婚者はお互いが好きだということです。Prolog でこれらの用語を定義して、推論できるようにした方がよいでしょう。ドメインを定義するために使用する必要がある言語を作成します。これは次のようになります。
cheating(Cheater, SpitedSpouse, Lover) :-
married(Cheater, SpitedSpouse),
lovers(Cheater, Lover),
SpitedSpouse \= Lover.
定義がはるかに簡単になりましたlikes/2
。
likes(Husband, Wife) :- married(Husband, Wife), \+ cheating(Husband, Wife, _).
likes(Husband, Lover) :- cheating(Husband, _, Lover).
嫌いなものを適切に定義することもできます。
dislikes(SpitedSpouse, Lover) :- cheating(_, SpitedSpouse, Lover).
dislikes(Cheater, Spouse) :- cheating(Cheater, Spouse, _).
私たちが学んだことを見てください: あなたが実際に持っているのは、2 人の間の結婚関係、または 3 人の浮気関係であり、他の述語は、これら 2 つの基本的な関係の投影にすぎません。それはかなりきれいですよね?:)cheating/3
基本的に古典的な「三角関係」です。これは、プログラムをより強力なものに進化させる方法を示唆しています。もちろん、愛の四角形を処理することです! などなど。
興味深いことに気づきましたか?このコードは「キャッチ」できませmichelle
んbill
。これは、述語の性別/向きの制限という、より大きな問題を浮き彫りにします。このような具体的な名詞があると、論理的な関係を理解するのに役立つと思いますが、解決すべき危険な近道です。ロジックを処理する簡単な方法は、次のような述語を作成することです。
spouse(X, Y) :- married(X, Y)
spouse(X, Y) :- married(Y, X).
もちろん、同じ人が繰り返されていないことを確認するために、さらにチェックを行う必要がありますが、難しくはありません。次に、変数を変更して、性別固有のものを少なくします。