[您好,我正在上学,但我正在尝试获取递归返回的最大数字。让我用示例更好地解释:
我有这个谓词:
li(_, []).
li(NAME, [H|T]) :-
find(NAME, H, Occur),
li(NAME, T).
li(NAME) :-
findall(T, pri(name(T), _, _, _), Info),
li(NAME, Info).
第2行中的谓词(查找),它的作用是,通过提供一个名称和一些其他信息,它将为我返回一个数字(出现)。我想做的是知道整个递归中的最高数字(发生)。
下面我尝试做一些比较,但是没有用,它说最高的没有定义,我知道是因为它没有任何价值,但是我不知道该怎么做。
li(_, [], 0).
li(NAME, [H|T], Highest) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Temp is Occur,
Highest < Temp,
Highest is Temp.
li(NAME) :-
findall(T, pri(name(T), _, _, _), Info),
li(NAME, Info, Return),
write(Return).
目标是在第3行的末尾写入数字。有谁知道我该怎么做才能解决此问题?谢谢。
编辑
我再次尝试并执行此操作:
li(_, [], 0).
li(NAME, [H|T], Highest) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Temp < Occur,
Temp is Occur,
Highest is Temp.
li(NAME) :-
findall(T, pri(name(T), _, _, _), Info),
li(NAME, Info, Return),
write(Return).
它不会触发任何错误,但是什么也不会发生,不会返回任何错误,也不会打印任何内容。
EDIT2
感谢@David Tonhofer,我现在可以获得最高的数字。但是我真正想要的是与那个高号相关联的名字。
li(NAME, [H|T], Highest, X) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Highest is max(Temp,Occur), X = ??.
我正在逐步进行,首先尝试获得最高的号码,然后获得名称,但是现在有了MAX,我想我不知道这一点。
起初我想到的是这样:
li(_, [], 0).
li(NAME, [H|T], Highest, X) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Temp < Occur,
Temp is Occur,
Highest is Temp, X is NAME.
li(NAME) :-
findall(T, pri(name(T), _, _, _), Info),
li(NAME, Info, Return, X),
write(Return), write(X).
这里有问题:
li(NAME, [H|T], Highest) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Temp < Occur,
Temp is Occur,
Highest is Temp.
这意味着:
Temp < Occur
,如果没有,请回溯以尝试其他操作。Occur
和Temp
。由于Temp
已经包含一些值,因此这与测试Occur
和Temp
是否为相同值相同,如果没有,请回溯尝试其他操作。 Highest
和Temp
。您似乎希望Highest
采用max(Occur,Temp)
的值。
在这种情况下:
li(NAME, [H|T], Highest) :-
find(NAME, H, Occur),
li(NAME, T, Temp),
Highest is max(Temp,Occur).
此
max(Temp,Occur)
(仅在此时知道Temp
和Occur
的值时有效)Highest
统一。如果Highest
仍然是新变量,则这类似于赋值。否则,如果Highest
已经包含某些内容,则类似于比较。要获得与获得的最大值关联的“名称”,请以相同的方式进行:
li(Name_max, [H|T], Temp_max) :-
find(Name_from_Head, H, Temp_from_Head),
li(Name_from_Tail, T, Temp_from_Tail),
% let's just print what we have right now:
format("From the Head, we get: Name = ~w, Temp = ~w", [Name_from_Head,Temp_from_Head]),
format("From the Tail, we get: Name = ~w, Temp = ~w", [Name_from_Tail,Temp_from_Tail]),
% now a little "helper predicate" can be used for clarity
% we pass it the 4 logical variables containing names and temps
% and the 2 logical variables that have been given to "li/3"
% to fill in with the best data:
select_max(Name_from_Tail, Temp_from_Tail,
Name_from_Head, Temp_from_Head,
Name_max, Temp_max),
% and we are done; just a printing before returning for fun
format("Our current max: Name = ~w, Temp = ~w", [Name_max,Temp_max]).
% The helper predicate has two clauses for the two
% mutually exclusive alternatives
% (the "=:=" case is in the first clause, arbitrarily)
select_max(Name_from_Tail, Temp_from_Tail,
Name_from_Head, Temp_from_Head,
Name_from_Tail, Temp_from_Tail) :-
Temp_from_Tail >= Temp_from_Head.
select_max(Name_from_Tail, Temp_from_Tail,
Name_from_Head, Temp_from_Head,
Name_from_Head, Temp_from_Head) :-
Temp_from_Tail < Temp_from_Head.
对于辅助谓词,您也可以写,也许更清楚:
select_max(Name_from_Tail, Temp_from_Tail,
Name_from_Head, Temp_from_Head,
Name_max, Temp_max) :-
Temp_from_Tail >= Temp_from_Head, % Guard
Name_max = Name_from_Tail, % Constrain variables to be equal!
Temp_max = Temp_from_Tail.
select_max(Name_from_Tail, Temp_from_Tail,
Name_from_Head, Temp_from_Head,
Name_max, Temp_max) :-
Temp_from_Tail < Temp_from_Head, % Guard
Name_max = Name_from_Head, % Constrain variables to be equal!
Temp_max = Temp_from_Head.
在SWI-Prolog中,库(aggregate)旨在为您的问题提供类似SQL的解决方案:
?- L=[a:1, b:2, c:3], aggregate(max(V,N),member(N:V,L),Max).
L = [a:1, b:2, c:3],
Max = max(3, c).