0

私のプログラムのコンテキストは次のとおりです。このプロローグコードでは、次のように、特定の研究と特定の研究がありstudentsますcountryyears

student('Steve Morris').
student('Joe Jez').
student('Carlos Sethi').
student('Natasha Carter').

country('Steve Morris', usa).
country('Joe Jez', usa).
country('Carlos Sethi', usa).
country('Natasha Carter', france).

years('Steve Morris', 3).
years('Joe Jez', 1). 
years('Carlos Sethi', 4).
years('Natasha Carter', 4). 

scholarship(A) :- country(A,B), B = france.
scholarship(A) :- years(A,C), C > 2.

生徒の 1 人に 1 つだけの奨学金を贈りたいです。これを行うために、「奨学金係数」を上げるいくつかのルールを使用し、より大きな奨学金係数を取得した学生が奨学金を取得します。

最初の規則では、学生はフランス出身である必要があり、2 番目の規則では、学生は 2 年以上勉強している必要があります。

したがって、 を実行するscholarship(X)と、次のようになります。

?- scholarship(X).
X = 'Natasha Carter' ;    % Only student who matches the first rule
X = 'Steve Morris' ;      % All students from now on, match the second rule
X = 'Carlos Sethi' ;
X = 'Natasha Carter'.

そうは言っても、最終的に奨学金を獲得する学生の名前を取得しようとするプログラムを実行しようとしています。まず、述語を実行して、findallこれらのルールに一致するすべての学生を 1 つずつフィルタリングし、リストに追加しようとしました。

?- findall(X, scholarship(X), L).
L = ['Natasha Carter', 'Steve Morris', 'Carlos Sethi', 'Natasha Carter'].

を使用しているため、これは予想される結果ですscholarship(X)

さて、結果をフィルタリングして探しているものを満たすために、生成されたリストが必要になるようです。上記の例で、私が到達することを期待している結果は、少なくとも、学生とその奨学金要因を示すリストであることに注意してください。これは次のようなものです (必ずしも正確ではありません)。

[['Natasha Carter', 2], ['Steve Morris', 1], ['Carlos Sethi', 1]].

findall?で生成されたリストを操作する方法です? または、これを解決する別の方法が必要ですか?

編集:問題のモデル化について重要なことがあります:すべてのルールには同じ奨学金係数の値があるため、学生がルールを満たすと、どのルールであっても奨学金係数は 1 まで上昇する必要があります。

問題の更新: Mog のおかげでmsort/2、二次リストを使用して適用する問題のアプローチができました。これが私が得たものです。

?- findall(X, scholarship(X), L), msort(L, L1).
L = ['Natasha Carter', 'Steve Morris', 'Carlos Sethi', 'Natasha Carter'],
L1 = ['Carlos Sethi', 'Natasha Carter', 'Natasha Carter', 'Steve Morris'].
4

2 に答える 2

0

次のレジストリ構造を使用することで、別の解決策を見つけました。

reg(C, N)

ここでCはその人の名前で、 は でN生成されたリストにその人の名前が表示される回数ですfindall(このソリューションの効果のための の使用はmsort/2、単に順序付けのためです)。

listsort(L1) :- findall(X, scholarship(X), L), msort(L, L1).

compress([],[]).
compress([X|Xs],Ys):-comp(Xs,X,1,Ys).

comp([],C,N,[reg(C,N)]).
comp([X|Xs],X,N,Ys):-N1 is N+1, comp(Xs,X,N1,Ys).
comp([X|Xs],Y,N,[reg(Y,N)|Ys]):-  X\=Y, comp(Xs,X,1,Ys).

predic(S2) :- listsort(S1), compress(S1, S2).

したがって、元の問題の出力は提案されたものと似ています (唯一の違いは、元の問題ではレジストリが次の順序で並べられていることNです:

?- predic(K).
K = [reg('Carlos Sethi', 1), reg('Natasha Carter', 2), reg('Steve Morris', 1)] 
于 2013-07-15T03:16:41.317 に答える