2017-04-23 6 views
1

私はプロローグについて学び始めました。私は完全に混乱しています。Beginner Prolog:Predicate Logicと(多分)構文の問題

以下のシナリオを考えてみましょう。私は、人に関する事実を含む知識ベースを、フォーマット担当者(名前、年齢)と一緒に持っています。

例:

person(brad,20). 
person(lindsey,15). 
person(sophie,18). 
person(charles,24). 

私は年齢の合計がさらに40を超えた場合にtrueに評価されますルールを作成するには、照会あれば、それは出力/年齢の人々の名前が表示されますすべてのソリューションを取得するには、

addsto40(X,Y,Sum) :- person(X,A), person(Y,B), Sum is A + B, Sum > 9. 

私はそれが年齢40より大きい数まで追加二人の名前を返し、次の(私はクエリヒット:だから40まで追加し、私はこれを試してみました)。クエリの例:

X = brad, 
Y = charles, 
Sum = 44 ; 
X = sophie, 
Y = charles, 
Sum = 42 ; 
X = charles, 
Y = brad, 
Sum = 44 ; 
X = charles, 
Y = sophie, 
Sum = 42 ; 
X = Y, Y = charles, 
Sum = 48. 

しかし、これは、二つの対に出力を制限:

?- addsto40(X,Y,Sum). 

このクエリはfollwingを返します。私はそれに制限がないようにしたい、答えは例えば:brad、lindsey、sophieを含むことができる。

私はいくつかの失敗した解決策を試しました。私はaddsto40/3を実装し、合計が40に達するまで1人増やすことを考えました。しかし、それがうまく動作するようには機能しません。

addsto40(X,Y,Sum) :- person(X,A), person(Y,B), Sum is A + B, Sum < 40, addper(P,Sum,Newsum). 
addsto40(X,Y,Sum) :- person(X,A), person(Y,B), Sum is A + B, Sum > 40. 

addper(Y,Sum,Newsum) :- person(Y,X), Newsum is Sum + X, Newsum < 40, addper(P,Newsum,someSum). 
addper(Y,Sum,Newsum) :- person(Y,X), Newsum is Sum + X, Newsum > 40. 

私は正しい方向に誘導することができますか?なぜこれは機能しないのですか?解決策は何とかリストを実装することにありますか?プロローグの初心者のためのヒントやトリックはありますか?私はどんな種類の助けにも感謝します。ありがとうございました?

あなたが40より大きい

以下

1はあなたのアプローチに似てそれを行うかもしれない方法であるが、代わりにリストを使用して、年齢の合計の人々のリストを取得しようとしているので、あなたはおそらく、リストを使用する必要があります

+0

私を助けてください! –

答えて

1

addsto40([H|_],Sum,NewSum) :- person(H,A), NewSum is A + Sum, NewSum > 40. 
addsto40([H|T],Sum,EndSum) :- person(H,A), NewSum is A + Sum, addsto40(T,NewSum,EndSum). 

そしてあなたのクエリは次のようになります。

addsto40(X,0,Sum). 

ただし、上記の複数回とあなたのリストは、その中に人々の無限の数を持つことができます同じ人が含まれていることがわかります。この問題を解決するために、リストに特定のメンバーが含まれているかどうかをチェックする述語を追加し、それを使用して同じ人を2回追加しないようにします。また、ヘルパー述語を使用して開始合計(0)と開始リスト(空)を除外します。最終的なコードは以下のようになります。

addsto40(X,Sum) :- addsto40help(X,0,[],Sum). 

addsto40help([H|_],Sum,Used,NewSum) :- person(H,A), not(contains(H,Used)), NewSum is A + Sum, NewSum > 40. 
addsto40help([H|T],Sum,Used,EndSum) :- person(H,A), not(contains(H,Used)), NewSum is A + Sum, addsto40help(T,NewSum,[H|Used],EndSum). 

contains(X,[X|_]). 
contains(X,[_|T]) :- contains(X,T). 

そして、あなたのクエリは次のようになります。

addsto40(X,Sum). 
+0

どうもありがとうございました。 –