2012-04-21 8 views
5

をPrologの初心者として、私はPrologで可換的な表現が直感的ではないことを発見しました。Prologで "Commutativity"を表現する代わりに?

family(X,Y) :- 
     married(X,Y); 
     relative(X,Y); 
     father_son(X,Y). 

は、私もそれを「可換」にするために、定義に以下を追加する必要があります:私はXとYを表現したい場合など

は次のように、一つの家族である

 married(Y,X); 
     relative(Y,X); 
     father_son(Y,X). 

しかし、我々は、エレガントなコードを書きたいので、我々は、プロローグを使用して...ので、私は、元に(代わりに、上記の3つの)一つだけの行を追加したいと考えていたい:

 family(Y,X). 

ここはPOINTです。それは終わりにつながる!なぜプロローグは「論理的」ではないのですか?終わりに至らないこの素敵な1行の表現に代わる方法がありますか?

素敵な週末! ワット

答えて

7

ルールのfamily(X,Y) :- family(Y,X).一部の問題は、それが各レベルで無条件に自分自身との統一維持し、ダウン再帰続けるということです。この再帰からの終了条件はありません。

あなたはレベル上記で引数スワップを行う必要があります:あなたは今

is_married(X,Y) :- 
    married(X,Y); 
    married(Y,X). 

is_relative(X,Y) :- 
    relative(X,Y); 
    relative(Y,X). 

できます

また
family(X,Y) :- 
    is_family(X,Y); 
    is_family(Y,X). 

is_family(X,Y) :- 
    married(X,Y); 
    relative(X,Y); 
    father_son(X,Y). 

、あなたはルールにそれが理にかなって以下対称の基礎となる作ることができますfamilyルールを次のように書き換えます。

family(X,Y) :- 
    is_married(X,Y); 
    is_relative(X,Y); 
    father_son(X,Y); 
    father_son(Y,X). 
+0

私はこれを見て、それがなぜ終わりを出すのかも明らかです。ありがとう! – Matt

+0

私はまた、別の事実を使用することをお勧めします。 –

+0

@AlexanderSerebrenik絶対に - 私はオリジナルのスタイルに近づきたいと思っていました。しかし、私のPrologの時代には、読みやすさとデバッグのしやすさのために ';'よりも複数のルールが好まれていました。 – dasblinkenlight

1

方法について:

relatives(X,Y) :- 
    married(X,Y); 
    relative(X,Y); 
    father_son(X,Y). 

family(X,Y) :- 
    relatives(X,Y); 
    relatives(Y,X). 
関連する問題