您实际上与 非常接近count_elt/3
,但您需要更多的非确定性。简而言之,你需要找到一种count_elt/3
减少剪辑的方式来表达,因为现在你得到了这个:
?- count_elt([a,b,a,a,c,b,d,e,a,f], Y, X).
Y = a,
X = 4.
而你想要得到的是:
?- count_elt([a,b,a,a,c,b,d,e,a,f], Y, X).
Y = a,
X = 4 ;
Y = b,
X = 2 ;
Y = c,
X = 1 ;
...
Y = f,
X = 1 ;
false.
从那里您只是试图找到具有最大值的解决方案,您可以使用setof/3
逻辑表达式或使用aggregate
库来完成。所以首先修复count_elt/3
并从那里开始。
编辑:一些一般性评论:
- 你可以写成
[H1|[H2|T]]
,[H1,H2|T]
这样更清楚一点。
listMode/2
可能应该将项目返回第二个位置而不是计数。由于您需要计数来执行此过程,因此您可能需要创建一个listMode/3
或listMode/5
帮助程序来在递归期间管理您的状态。
编辑:解决方案
由于@MaDu_LK 决定展示解决方案,即使这很可能是家庭作业,我想我会分享我的,使用@false 的具体化相等谓词:
count_of([], _, 0).
count_of([H|Rest], E, N1) :-
equality_reified(H, E, Bool),
count_of(Rest, E, N0),
(Bool == true -> N1 is N0 + 1 ; N1 = N0).
frequency(L, I, N) :-
sort(L, LSorted),
member(I, LSorted),
count_of(L, I, N).
mode(L, X) :-
frequency(L, X, NMax),
\+ (frequency(L, _, NBigger),
NMax < NBigger).
这具有更令人愉悦的性能特性:
% MaDu_LK
?- time(get_mode([a,b,c,a,b,c,a,a,b,c,a,d,b], X)).
% 2,811 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 7117429 Lips)
X = a.
% mine
?- time(mode([a,b,c,a,b,c,a,a,b,c,a,d,b], X)).
% 217 inferences, 0.000 CPU in 0.000 seconds (98% CPU, 3144928 Lips)
X = a ;
% 195 inferences, 0.000 CPU in 0.000 seconds (97% CPU, 3305085 Lips)
false.
即使列表是多模式的,另一种解决方案也只产生一种模式:
% MaDu_LK
?- get_mode([a,a,b,b,c], X).
X = a.
% mine
?- mode([a,a,b,b,c], X).
X = a ;
X = b ;
false.
深思熟虑。