次のルールで構成されるデータベースがあります。
speaks(fred [german, english, dutch]).
speaks(mary [spanish, arabic, dutch]).
speaks(jim [norwegian, italian, english]).
speaks(sam [polish, swedish, danish]).
等
より大規模なプログラムの一部として、同じ言語を話す 3 人をどのように見つけますか?
ジェン
そのままでは、Franz のソリューションは機能しません。同じ言語を話す prople のトリプルを返しますが、これらのトリプルには重複が含まれる可能性があります。したがって、例に頼ってsort/2
元length/2
の質問に対する答えを見つける必要があります。
?- findspeakers(Language, X1, X2, X3), sort([X1, X2, X3], Y), length(Y, 3).
false.
(つまり、答えはノーです。同じ言語を話す人は 3 人もいません。)とにかく、もっと洗練された解決策が存在すると思います。
spoken(L, S) :-
speaks(S, LL), member(L, LL).
same_language(N, L, SS) :-
bagof(S, spoken(L, S), SS), length(SS, N).
言語が person によって話されている場合、述語spoken/2
は使用されmember/2
、成功します。リストに明確な人が含まれていて、その全員が language を話す場合、成功します。この述語は;を使用します。述語の定義に重複データが含まれている場合は、代わりに使用する必要があります。L
S
same_language/3
SS
N
L
bagof/3
speak/2
setof/3
これが問題をうまく一般化していることに注意してください: 3 だけでなく、任意の nについて質問に答えることができます。
?- same_language(3, L, SS).
false.
?- same_language(2, L, SS).
L = dutch,
SS = [fred, mary] ;
L = english,
SS = [fred, jim] ;
false.
久しぶりなので構文の不具合があるかもしれませんが、ご理解いただければ幸いです...
% Find out whether an element is contained in a list
in_list(X,[X|_]).
in_list(X,[First|Rest]) :- in_list(X,Rest).
% Find out 3 people who speak the same language
findspeakers(Language, X1, X2, X3) :- speaks(X1, L1), speaks(X2, L2), speaks(X3, L3), in_list(Language, L1), in_list(Language, L2), in_list(Language, L3).
リスト演算子を使用した非常に単純なソリューション (変数がリストに含まれているかどうかを調べる組み込みのルールがあるかどうか覚えていなかったので、書き直しました)。
次のコマンドを使用して、英語を話している 3 人のグループを見つけることができます。
findspeakers('English', X1, X2, X3).
次のコマンドを使用して、共通の言語を話している 3 人のすべてのグループを見つけることができます。
findspeakers(Language, X1, X2, X3).
注: これらのコマンドは、3 人のグループのすべての可能な組み合わせを提供するため、英語を話す 4 人がいる場合、最初のコマンドは 4 つの結果セットを提供します。