私には次の事実とルールがあります。
% frequents(D,P) % D=drinker, P=pub
% serves(P,B) % B=beer
% likes(D,B)
frequents(janus, godthaab).
frequents(janus, goldenekrone).
frequents(yanai, goldenekrone).
frequents(dimi, schlosskeller).
serves(godthaab, tuborg).
serves(godthaab, carlsberg).
serves(goldenekrone, pfungstaedter).
serves(schlosskeller, fix).
likes(janus, tuborg).
likes(janus, carlsberg).
count_good_beers_for_at(D,P,F) :- group_by((frequents(D,P), serves(P,B), likes(D,B)),[D,P],(F = count)).
possible_beers_served_for_at(D,P,B) :- lj(serves(P,B), frequents(D,R), P=R).
ここで、「飲酒者」「頻繁」が0より大きい各パブで利用可能な「いいね」ビールの数が「真」を返す述語のように機能するルールを作成したいと思います。
ルールがタプルを返さない場合、述語はtrueと見なされます。述語が偽の場合、「いいね」したビールが1つもないバーを返すように計画していました。
ご覧のとおり、私はすでに、特定のパブで特定の酒飲みに適したビールを数えるルールを持っています。また、提供できるビールの数を指定するルールもあります。
DES> count_good_beers_for_at(A,B,C)
{
count_good_beers_for_at(janus,godthaab,2)
}
Info: 1 tuple computed.
ご覧のとおり、カウンターには頻繁に訪れたパブは返されませんが、好きなビールは0本あります。左外側の結合を使用してこれを回避することを計画していました。
DES> is_happy_at(D,P,Z) :- lj(serves(P,B), count_good_beers_for_at(D,Y,Z), (Y=P))
Info: Processing:
is_happy_at(D,P,Z) :-
lj(serves(P,B),count_good_beers_for_at(D,Y,Z),Y = P).
{
is_happy_at(janus,godthaab,2),
is_happy_at(null,goldenekrone,null),
is_happy_at(null,schlosskeller,null)
}
Info: 3 tuples computed.
これはほとんど正しいですが、それは私に頻繁ではないパブも与えていることを除いて。条件を追加してみます:
DES> is_happy_at(D,P,Z) :- lj(serves(P,B), count_good_beers_for_at(D,Y,Z), (Y=P)), frequents(D,P)
Info: Processing:
is_happy_at(D,P,Z) :-
lj(serves(P,B),count_good_beers_for_at(D,Y,Z),Y = P),
frequents(D,P).
{
is_happy_at(janus,godthaab,2)
}
Info: 1 tuple computed.
今、私はどういうわけかnullを含むすべてをフィルターで除去しました!これはDESのnull値ロジックが原因だと思います。
私はこの問題全体に間違った方法で取り組んでいる可能性があることを認識しています。どんな助けでも大歓迎です。
編集:割り当ては「very_happy(D)ist wahr、genau dann wenn jede Bar、die Trinker D besucht、wenigstens ein Bier ausschenkt、dasermag」です。これは、「very_happy(D)が真であり、各バーを飲む人Dが訪れた場合、彼が好きなビールを少なくとも1杯提供する」という意味になります。この課題はDatalogに関するものなので、Prologを使わなくても間違いなく解決できると思います。