【问题标题】:Prolog minimum value in a listProlog 列表中的最小值
【发布时间】:2015-11-29 21:39:32
【问题描述】:

我正在定义一个谓词min_in_list/2,它将找到列表中的最小值。如果列表中的元素少于 2 个,则程序应输出 "Error: There are not enough elements in the list" 并且如果列表中的元素不是数字,例如。 [2,a,3]。程序应输出"Error: The element is not a number"。我创建了一个谓词,它可以找到最小值并检查列表是否少于两个值,但是在检查列表的元素是否不是数字并输出错误消息时遇到问题

我的代码:

    min_in_list([Min],_):- write('ERROR: List has fewer than two elements.').
min_in_list([],_):- write('ERROR: List has fewer than two elements.').
min_in_list([Min,_],Min).

min_in_list([H,K|T],M) :- 
    H =< K,                           
    min_in_list([H|T],M).

min_in_list([H,K|T],M) :- 
    H > K,                            
    min_in_list([K|T],M).

【问题讨论】:

  • 元素少于2个,不应该是少于1个吗?一个元素的列表仍然有最小值...
  • 不,我想要的谓词应该在只有一个元素或没有元素时输出错误消息。
  • 您应该浏览 Prolog 的预定义谓词库。例如,有些谓词可以帮助您识别数字与原子。
  • 你的意思可能不是真的min_in_list([Min,_],Min). 那意味着min_in_list([3,5], 3). 是真的。

标签: prolog logic-programming


【解决方案1】:

您要查找的测试是number/1,它会告诉您值是否为数字。我的最终代码如下所示:

min_in_list([], _)  :- domain_error(not_empty_list, []).
min_in_list([X], _) :- domain_error(not_single_item_list, [X]).
min_in_list([X,Y|Rest], Min) :- min_in_list(X, [Y|Rest], Min).

min_in_list(Min, [], Min) :- !.
min_in_list(Min, [X|Rest], FinalMin) :-
    (   number(X) ->
        (NewMin is min(Min, X),
         min_in_list(NewMin, Rest, FinalMin))
    ;
        type_error(number, X)
    ).

我仍然不完全确定如何格式化这样的条件,但将其拆分为单独的谓词似乎是一种可怕的浪费。希望有人会过来告诉我如何格式化它以使其具有吸引力。

如果您使用的是 SWI-Prolog,您可以使用 must_be/2 简化事情:

min_in_list(Min, [], Min).
min_in_list(Min, [X|Rest], FinalMin) :-
    must_be(number, X),
    NewMin is min(Min, X),
    min_in_list(NewMin, Rest, FinalMin).

【讨论】:

  • must_be/2 更好,因为它会为未实例化的X 抛出instantiation_error。 OTOH,(is)/2 已经进行了类似的检查。唯一的区别是X = 1+1(is)/2 接受,但不被must_be/2 接受。
【解决方案2】:

最简单的解决方案可以是:

list(Min, [Min]).
list(Min, [H|T]) :- list(PMin, T), Min is min(H, PMin).

但必须注意,这将是大数组的堆栈开销。

【讨论】:

    猜你喜欢
    • 2011-04-27
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多