【问题标题】:Prolog - Max value in recursionProlog - 递归中的最大值
【发布时间】:2020-04-05 21:56:20
【问题描述】:

您好,我正在为学校工作,我正在尝试获取通过递归返回的最大数量。 让我用例子更好地解释:

我有这个谓词:

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).

它不会触发任何错误但什么也没有发生,返回一个 false 并且什么也不打印。

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


    【解决方案1】:

    这里有个问题:

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

    这意味着:

    • 确保Temp &lt; 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.
    

    【讨论】:

    • 您好,感谢您的重播,正在工作,不知道可以这样。我只通过比较价值观来坚持。我有最高,但你知道我如何返回与该号码关联的名称吗?我在比较数字时很努力,当我得到一个更大的数字时,我会将一些变量更改为新名称并最终返回它。我知道正确的知道我没有变量。但是现在使用最大值我看不到如何知道 NAME 是关联的。我将编辑 aswer。
    • @Rafael 更新!如果一切都清楚,请不要忘记将问题标记为已回答,
    • 您好,感谢您的帮助。很好的解释。
    【解决方案2】:

    在 SWI-Prolog 中,library(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).
    

    【讨论】:

    • @DavidTonhofer:你的回答很有启发性。我的英语不够流利,无法像你那样解释。我的答案确实可能是 OT,因为它没有提到递归......
    猜你喜欢
    • 2011-12-09
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多