代码之家  ›  专栏  ›  技术社区  ›  user6039980 hvgotcodes

Prolog-参数没有充分实例化。列表/递归

  •  0
  • user6039980 hvgotcodes  · 技术社区  · 6 年前

    我试图从给定列表“L”中获取最大值,并将其分配给变量,因此我编写了以下函数:

    max(L,X):-
        [H|Q]=L,
        (X<H -> X=H),
        length(Q,QLEN),
        (QLEN>0 -> max(Q,X)),
        true.
    

    但是在编译代码和提示后 max([1,2,3],X) 在内部 SWI-Prolog ,我得到以下错误:

    错误:参数未充分实例化错误:In:错误:
    [9] \u 1064<1错误:[8]最大值([1,2 |…])_1092)位于c:/users/kais/desktop/tp3。pl:24错误:[7]

    为什么我会犯这样的错误?

    2 回复  |  直到 4 年前
        1
  •  3
  •   Frank Shearar    6 年前

    正如你试图比较的评论中所说 H 具有 X 未实例化。这个问题的解决方案是创建一个谓词 maxList/3 把它叫进去 maxList/2 具体如下:

    maxList([H|T], Max) :-
        maxList(T, H, Max).
    
    maxList([], Max, Max).
    maxList([H|T], Max0, Max) :-
        Max1 is max(H, Max0),
        maxList(T, Max1, Max).
    
    ?- maxList([1,2,3],X).
    X = 3.
    

    max/2 只返回两个参数之间的最大值。可能的实现 最大值/2 可以是:

    myMax(M,A,B):-
        A > B ->  M = A;
        M = B.
    
    ?- myMax(A,1,2).
    A = 2.
    

    顺便说一句,SWI中已经有一个内置谓词来执行此操作,称为 max_list/2 (我之前发布的代码实际上来自此实现):

    ?- max_list([1,2,3],X).
    X = 3.
    
        2
  •  1
  •   user6620167 user6620167    6 年前

    另一种可能的实现,不依赖于辅助谓词,可以根据以下逻辑完成:

    1. 如果列表仅包含一个元素,则为最大值。
    2. 如果列表 L 包含多个元素,即它的形式 [H|T] ,以及 T M ,然后是 L H 如果 H>=M ,否则 M .

    粗略编码可以是:

    maxList([X],X).
    maxList([H|T],H) :-
      maxList(T,M),
      H >= M.
    maxList([H|T],M) :-
      maxList(T,M),
      H < M.
    

    这留下了改进的空间,但尊重上述逻辑,并为每个非空整数列表返回最大的元素。