2017-10-17 2 views
1

私は私の知識ベースを定義した:私は、次を使用し、上記の知識ベースを使用して、今すぐPrologのカットオペレータ

edge(mammal,isa,animal). 
edge(human,isa,mammal). 
edge(simba,isa,human). 

edge(animal,swim,bybirth). 
edge(human,swim,mustlearn). 

path(X,Y) :- edge(X,isa,Y). 
path(X,Y) :- edge(X,isa,Z), path(Z,Y). 

swim(X,Y) :- edge(X,swim,Y). 
swim(X,Y) :- path(X,Z), swim(Z,Y). 

?- swim(simba,bybirth). 
?- swim(simba,mustlearn). 

とクエリの両方のために、プロローグがtrueを返します。私はPrologがプロパティーをローカルで調べるようにしてから、直接的な親を見て行き、階層的なやり方でそうするようにします。そして、私たちがSimbaが泳ぐための "mustlearn"があることを知ったらすぐに検索を止めて、それ以上見るべきではありません。したがって、最初のクエリではfalseを返し、2番目のクエリではtrueを返します。

私はそれがバックトラックを制限することによって行われなければならないことを知っています。私はカットを使用して、演算子を使用しようとしましたが、成功することはできませんでした。これを達成する方法はありますか?

答えて

1

私も試してみましたが問題にも遭遇しました。それは動作しません

swim(X,Y) :- once((edge(X,swim,Y); path(X,Z), swim(Z,Y))). 

、Yはすでに途中でインスタンス化された場合、最初のステップは、統一に失敗し、それが中間humanを通過する第2の経路を尽くしますので、私は、これはうまくいくかもしれないと思いました。したがって、クエリでは1つの結果しか生成されませんが、swim(simba, bybirth)を生成することになります。ソリューションはプロローグが別の変数に結合することを約束して、約束した後結合することを確認するために強制することです:これはプロローグに伝え

swim(X,Y) :- 
    once((edge(X,swim,Method); path(X,Z), swim(Z,Method))), 
    Method = Y. 

、この方法を取得する唯一の方法があり、そのための方法を見つけ、あなたは間違った方法を見つけた場合、それは検索に行くことはありません、それはちょうど失敗します。それを試してみてください!