Prolog-递归最大值

问题描述 投票:0回答:2

[您好,我正在上学,但我正在尝试获取递归返回的最大数字。让我用示例更好地解释:

我有这个谓词:

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).
prolog swi-prolog
2个回答
1
投票

这里有问题:

li(NAME, [H|T], Highest) :- 
   find(NAME, H, Occur), 
   li(NAME, T, Temp), 
   Temp < Occur, 
   Temp is Occur,
   Highest is Temp.

这意味着:

  • 请确保Temp < Occur,如果没有,请回溯以尝试其他操作。
  • 然后统一数值OccurTemp。由于Temp已经包含一些值,因此这与测试OccurTemp是否为相同值相同,如果没有,请回溯尝试其他操作。
  • 然后统一数值HighestTemp

您似乎希望Highest采用max(Occur,Temp)的值。

在这种情况下:

li(NAME, [H|T], Highest) :- 
   find(NAME, H, Occur), 
   li(NAME, T, Temp), 
   Highest is max(Temp,Occur).

  1. 计算max(Temp,Occur)(仅在此时知道TempOccur的值时有效)
  2. 将结果与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.

0
投票

在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).
© www.soinside.com 2019 - 2024. All rights reserved.