将数字添加到列表中并找到最大的数字

时间:2014-05-09 13:06:03

标签: prolog

这个问题是基于我之前的一个问题。Here is the previous question. 因此,你可以看到我现在能够获得我在问题中输入的每个键的分数,但现在我需要找到最高分并将其与所有其他分数的总和相加。例如,如果我进行查询,我希望将分数添加到列表中。例如 它可能看起来像scores[1,2,3,2,1]然后我想从这个列表中提取最大值3,并将其添加到列表的总和中,即1 + 2 + 3 + 2 + 1 = 9。

我不能让它发挥作用。据我所知,追加仅适用于列表。我可以从

添加Acc吗?
score([Tag|Tags], Acc, Count, document(Title,_)) :-
    (   sub_string(case_insensitive, Tag, Title)  % Check for Tag in Title
    ->  Acc1 is Acc + 1                           % Increment acc if found
    ;   Acc1 = Acc                                % Otherwise, no increment
    ),
    score(Tags, Acc1, Count, document(Title,_)).  % Score remaining tags

使用会员列表?我尝试了但是我无法使它工作......

这是一个例子: 这是我的查询

?- document(T,_),score([rule],Acc,document(T,_)).

因此我会得到

T = 'Rules; Semantic Technology; and Cross-Industry Standards',Acc = 1;
T = 'Rule Transformation and Extraction',Acc = 1;
T = 'Rules and Uncertainty',Acc = 1;
T = 'Rules and Rules',Acc = 2;

依此类推......我希望将每个Acc添加到列表中,然后我想提取此列表的max Acc

2 个答案:

答案 0 :(得分:1)

库(聚合)可能是一个很好的起点,但为了充分利用它,我认为你需要解耦任务,并使用sub_atom / 5实际上可以搜索'多次出现:

tags_count(Tags, Title, Count) :-
    downcase_atom(Title, Downcase),
    aggregate_all(count, (member(T,Tags), sub_atom(Downcase, _,_,_, T)), Count).

counters(Tags, L) :-
    findall(C, (document(T,_), tags_count(Tags,T,C)), L).

试验:

document('Rules; Semantic Technology; and Cross-Industry Standards',_).
document('Rule Transformation and Extraction',_).
document('Rules and Uncertainty',_).
document('Rules and Rules',_).

?- counters([rule], L), max_list(L, Max), sum_list(L, Sum), Tot is Sum + Max.
L = [1, 1, 1, 2],
Max = 2,
Sum = 5,
Tot = 7.

编辑真的,所有的工作都在'内部完成。 aggregate_all / 3

tags_tot_max_title(Tags, Tot, Max, Title) :-
    aggregate_all(info(sum(C), max(C, T)), (
        document(T, _), tags_count(Tags, T, C)
    ), info(Sum, max(Max, Title))),
    Tot is Sum + Max.

产量

?- tags_tot_max_title([rule], Tot, Max, Title).
Tot = 7,
Max = 2,
Title = 'Rules and Rules'.

答案 1 :(得分:0)

如果您有以下查询:

document(T,_),score([rule],Acc,document(T,_))

并且您希望通过多个此类查询收集结果并对其进行排序(并假设使用唯一元素),您可以使用setof

setof(doc(Acc, T), ((document(T, _), score([rule], Acc, document(T, _)), Accs)

列表Accs将是以doc(Acc, T)的升序排序的Acc对的集合。 [ N.B。,方便的是,即使元素是复合词,setof也很清楚排序列表。因此doc(X, Y)之类的术语将使用X比较符排序Y然后@排序。]如果您反转列表并抓住头部,您将获得最大Acc以及相应的T

reverse(Accs, [doc(MaxAcc, MaxT)|_])

您可以将它们组合成一个谓词:

max_doc_acc(Tags, MaxAcc, Doc) :-
    setof(doc(Acc, T), ((document(T,_), score(Tags, Acc, document(T,_)), Accs),
    reverse(Accs, [doc(MaxAcc, Doc)|_]).

然后查询类似的内容:

max_doc_acc([rule], MaxAcc, Doc).