1

私は、誰かが他の誰かの兄弟であるかどうかを決定するルールを私のプロローグプログラムに書き込もうとしています。

たとえば、brother_of(chris、X)と入力すると、chrisはchristyの兄弟であるため、christyが返されます。ただし、これを入力すると、存在例外が発生します。すべてをカバーするためにファクトを含めましたが、ルール定義に問題があるのではないでしょうか。コードは以下のとおりです。

/* Facts */
female(ella).
female(jodi). 
female(sonya).
female(jane). 
female(christy). 
female(mary).
male(arnold).
male(chris).
male(louis).
male(mark).  
father(arnold).
father(louis).
father(mark).
mother(ella).
mother(jodi).
mother(jane).
mother(mary).
father_of(arnold, chris). /* arnold is the father of chris */
father_of(arnold, christy).
father_of(louis, mark).
father_of(mark, arnold). 
mother_of(mary, chris).
mother_of(mary, christy).          
mother_of(jane, arnold).    
mother_of(ella, sonya).
mother_of(jodi, ella).
mother_of(jodi, mark).

/* Rules */

brother_of(X, Y) :-
    male(X),
    ((father_of(Z, X), father_of(Z, Y));
    (mother_of(W, X), mother_of(W, Y))),
    X =\= Y.
4

1 に答える 1

1

演算子=\=は算術のみ(AFAIK)で使用され、2つの用語が異なる(統合できない)かどうかを確認するには、演算子を使用します\=

X \= Y.

更新:カット( )の目標の簡単な紹介!:カットが述語で使用される場合、すでに見つかったもの以外に検索する必要がないことを意味します(つまり、検索ツリーで「残りのブランチをカットする」)。例:

first_child(X,Y) :-
    father_of(X,Y), !.

?- first_child(arnold,Y).

Y = chris ;

no

カットに到達すると、カットのすべての選択ポイントが破棄されます(ただし、カット後に新しい選択ポイントを作成できます)。あなたの例では、XとYの父親が同じである場合、母親も同じであるかどうかは関係ありません。したがって、「共通の父」の部分が成功した直後にカットを配置できます。

brother_of(X, Y) :-
    male(X),
    ((father_of(Z, X), father_of(Z, Y), X \= Y, !); # If cut is reached, will not run the next line
    (mother_of(W, X), mother_of(W, Y), X \= Y)).

ただし、カットの使用には多くの落とし穴があります(リンクされたウィキペディアの記事の「グリーンカット」と「レッドカット」を参照)が、ここで説明するには多すぎます。(私が繰り返した方法に注意してくださいX \= Y-私がそれをしなかった場合、プログラムは時々失敗するでしょう)

最後に、Prologコードを書くときに使用することはしばしば推奨されないことも指摘したいと思い;ます(ただし、必要なときに使用できます)。代わりに、次の2つの句で記述します。

brother_of(X, Y) :-
    male(X),
    father_of(Z, X),
    father_of(Z, Y), 
    X \= Y,
    !.
brother_of(X, Y) :-
    male(X),
    mother_of(W, X),
    mother_of(W, Y), 
    X \= Y.

;ただし、これと2つの句は少し主観的なものなので、あまり議論しません...両方の方法が可能であり、同じ結果が得られることを知っておいてください)

于 2012-04-20T03:07:22.837 に答える