Prolog 哪个列表项是最常见的

Prolog 哪个列表项是最常见的,prolog,logical-purity,Prolog,Logical Purity,我试图找到最常见的列表项common([b,a,a,a,c,d,b,f,s,f,s,f,s,f,f],R),因此结果应该是R=f, 我在想,如果我们拿这个列表,到列表的末尾,拿el=b,num1=1,然后回到开头,比较一下,如果b=b,num1=num1+1,还有a=b然后如果num2=num2+1,num1>num2递归,或者el=a或者类似的东西,但是我很难将它转换成Prolog insert\u sort对列表进行排序,但出于一些有趣的原因,如果我使用last(X,Y)(我覆盖了原始的la

我试图找到最常见的列表项common([b,a,a,a,c,d,b,f,s,f,s,f,s,f,f],R),因此结果应该是R=f, 我在想,如果我们拿这个列表,到列表的末尾,拿el=b,num1=1,然后回到开头,比较一下,如果b=b,num1=num1+1,还有a=b然后如果num2=num2+1,num1>num2递归,或者el=a或者类似的东西,但是我很难将它转换成Prolog

insert\u sort对列表进行排序,但出于一些有趣的原因,如果我使用
last(X,Y)
(我覆盖了原始的
last/2
),如果我使用
last(X,Y)
我只得到一个

most_common([X|Y],J):-
    insert_sort([X|Y],[R|Rs]),             
    count_runs([R|Rs],G),
    las(G,J).

las([N-Y],Y).
las([_|T],Y):- las(T,Y).
las([_|Tail], Y) :- las(Tail, Y).

insert_sort(List,Sorted):-
   i_sort(List,[],Sorted).

i_sort([],Acc,Acc).
i_sort([H|T],Acc,Sorted):- 
    insert(H,Acc,NAcc),
    i_sort(T,NAcc,Sorted).

insert(X,[],[X]).     
insert(X,[Y|T],[Y|NT]):- X @> Y, insert(X,T,NT).
insert(X,[Y|T],[X,Y|T]):- X @=< Y.
最常见([X | Y],J):-
插入排序([X | Y],[R | Rs]),
计算运行次数([R | Rs],G),
las(G,J)。
las([N-Y],Y)。
las(T,Y):-las(T,Y)。
las(Tail,Y):-las(Tail,Y)。
插入排序(列表,已排序):-
i_排序(列表,[],已排序)。
i_排序([],Acc,Acc)。
i|u排序([H|T],Acc,排序):-
插入(H、Acc、NAcc),
i_排序(T,NAcc,Sorted)。
插入(X,[],[X])。
插入(X[Y | T],[Y | NT]):-X@>Y,插入(X,T,NT)。
插入(X[Y|T],[X,Y|T]):-X@=
我可以给你一个高层次的答案:你可以对列表进行排序,然后相对容易地一个接一个地计算项目,并更新到目前为止最常见的项目。

这看起来像是家庭作业,所以我不会给你一个完整的答案,但会建议你如何以一种特定的方式解决它,哪种方式不一定是最好的:

  • 将列表按排序顺序排序(如果这足够好,则按术语的标准顺序):查看例程。e、 例如,
    [b,a,a,c,d,b]
    变成
    [a,a,b,b,c,d]

  • 取已排序的列表并计算“运行”的大小,或许可以将
    [a,a,b,b,c,d]
    转换为
    [3-a,2-b,1-c,1-d]
    (其中
    -
    /2只是另一个术语)。例如,考虑下面的代码:



  • 执行类似的操作,按照关键字的值对术语进行排序(即,作为计数的数字,将
    [3-a,2-b,1-c,1-d]
    转换为
    [1-c,1-d,2-b,3-a]
    )。然后,列表中出现最多的元素是列表末尾具有相同键值的值(即,这里是最后一项
    3-a
    中的
    a
    )。通常,它们可能是出现最多的一个以上元素(与另一个相同)
祝你好运

基于,我们使用元谓词和,以及具体化的术语相等谓词:

示例查询:

?- mostcommon_in(X,[a,b,c,d,a,b,c,a,b]). X = a ; X = b ; false. ?-在(X,[a,b,c,d,a,b,c,a,b])中最常见。 X=a; X=b; 错。 请注意,这是单调的(与早期的quick hack版本不同)。看

?-在(X,[A,B,C,D,A,B,C,C,A,B]),A=A,B=B,C=C,D=D中最常见的。 X=a,a=a,B=B,C=C,D=D; X=b,A=A,b=b,C=C,D=D; 错。 保存 用于定义/2中最常见的项目,如下所示:

mostcommonitem_in(E,Xs) :-
   list_counts(Xs,Cs),                      % tag items with multiplicity
   maplist(\ (X-N)^(M-X)^(M is -N),Cs,Ps),  % prepare keysorting
   keysort(Ps,[Max-_|_]),                   % sort ascending by negated count
   member(Max-E,Ps).                        % pick most common ones
让我们运行一个查询

?- mostcommonitem_in(X,[a,b,c,d,a,b,c,a,b]).
X = a ;
X = b ;
false.                                % OK
但是,它还是单调的吗

?- mostcommonitem_in(X,[A,B,C,D,A,B,C,A,B]), A=a,B=b,C=c,D=d.
X = A, A = a, B = b, C = c, D = d ;
X = B, B = b, A = a, C = c, D = d ;
false.                                % OK: monotone
有速度吗?(与我在中给出的纯答案相比)

%旧的 ?长度(Xs,5),时间(findall(t,mostcommon_in(E,Xs),Ts)),长度(Ts,N_sols)。 %854636个推论,0.115秒0.115 CPU(100%CPU,7447635个嘴唇) N_sols=71,Xs=[u,u,,,,,,,]Ts=[t,t,t |……]。 ?长度(Xs,6),时间(findall(t,mostcommon_in(E,Xs),Ts)),长度(Ts,N_sols)。 %4407975推断,0.449秒内0.449 CPU(100%CPU,9813808) N_sols=293,Xs=[u,u,,,,,,[t,t |……]。 ?长度(Xs,7),时间(findall(t,mostcommon_in(E,Xs),Ts)),长度(Ts,N_sols)。 %24240240个推断,2.384秒2.385 CPU(100%CPU,10162591个嘴唇) N_sols=1268,Xs=[u,u,u,,,,,,[t,t |……]。 %新的 ?长度(Xs,5),时间(findall(t,mostcommonitem_in(E,Xs),Ts)),长度(Ts,N_sols)。 %4031个推断,0.002秒0.001 CPU(93%CPU,2785423个嘴唇) N_sols=71,Xs=[u,u,,,,,,,]Ts=[t,t,t |……]。 ?长度(Xs,6),时间(findall(t,mostcommonitem_in(E,Xs),Ts)),长度(Ts,N_sols)。 %17632个推断,0.002秒内0.002 CPU(100%CPU,9194323) N_sols=293,Xs=[u,u,,,,,,[t,t |……]。 ?长度(Xs,7),时间(findall(t,mostcommonitem_in(E,Xs),Ts)),长度(Ts,N_sols)。 %82263个推断,0.023秒0.023 CPU(100%CPU,3540609个嘴唇) N_sols=1268,Xs=[u,u,u,,,,,,[t,t |……]。
最常见([a,a,b,f,f,d,f,s,d,d,s,d,s,d,s,d,s,d,s],E)。E=f。这是完整代码的一部分:最常见([X | Y],C):-count|u运行([X | Y],K),last(K,C)。%我们对列表K进行了排序,并使用Last()找到字母Last([N-Y],Y)。last([[u124; Tail],Y):-last(Tail,Y)。但假设我们有这样一个列表:最常见的([a,a,b,f,f,d,f,s,d,s,s,d,s,d,d,d,s,d,s,d,d,s],E)。->最后([1-b,1-f,1-s,1-f,1-s,1-f,1-s,…-…,a),最常见的项目是a,但不是f,因此我们有一个小问题:对整个问题的一个小优化是定义
count_runs/2
,这样它以相反的顺序累积项目计数,将它们排序为从大到小的计数,结果是在结果列表的头部出现最多的元素
E
,即
[-E |]
计数翻转/2
:哦,这些手动
映射列表
和λ-编译器。
mostcommonitem_in(E,Xs) :-
   list_counts(Xs,Cs),                      % tag items with multiplicity
   maplist(\ (X-N)^(M-X)^(M is -N),Cs,Ps),  % prepare keysorting
   keysort(Ps,[Max-_|_]),                   % sort ascending by negated count
   member(Max-E,Ps).                        % pick most common ones
?- mostcommonitem_in(X,[a,b,c,d,a,b,c,a,b]).
X = a ;
X = b ;
false.                                % OK
?- mostcommonitem_in(X,[A,B,C,D,A,B,C,A,B]), A=a,B=b,C=c,D=d.
X = A, A = a, B = b, C = c, D = d ;
X = B, B = b, A = a, C = c, D = d ;
false.                                % OK: monotone
% OLD ?- length(Xs,5), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols). % 854,636 inferences, 0.115 CPU in 0.115 seconds (100% CPU, 7447635 Lips) N_sols = 71, Xs = [_,_,_,_,_], Ts = [t,t,t|...]. ?- length(Xs,6), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols). % 4,407,975 inferences, 0.449 CPU in 0.449 seconds (100% CPU, 9813808 Lips) N_sols = 293, Xs = [_,_,_,_,_,_], Ts = [t,t,t|...]. ?- length(Xs,7), time(findall(t,mostcommon_in(E,Xs),Ts)), length(Ts,N_sols). % 24,240,240 inferences, 2.385 CPU in 2.384 seconds (100% CPU, 10162591 Lips) N_sols = 1268, Xs = [_,_,_,_,_,_,_], Ts = [t,t,t|...]. % NEW ?- length(Xs,5), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols). % 4,031 inferences, 0.001 CPU in 0.002 seconds (93% CPU, 2785423 Lips) N_sols = 71, Xs = [_,_,_,_,_], Ts = [t,t,t|...]. ?- length(Xs,6), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols). % 17,632 inferences, 0.002 CPU in 0.002 seconds (100% CPU, 9194323 Lips) N_sols = 293, Xs = [_,_,_,_,_,_], Ts = [t,t,t|...]. ?- length(Xs,7), time(findall(t,mostcommonitem_in(E,Xs),Ts)), length(Ts,N_sols). % 82,263 inferences, 0.023 CPU in 0.023 seconds (100% CPU, 3540609 Lips) N_sols = 1268, Xs = [_,_,_,_,_,_,_], Ts = [t,t,t|...].