列表中的Prolog最小值

时间:2015-11-29 21:39:32

标签: prolog logic-programming

我正致力于定义一个在列表中找到最小值的谓词min_in_list/2。如果列表中的元素少于2个,则程序应输出"Error: There are not enough elements in the list",如果列表中的元素不是数字Eg。 [2,1,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 个答案:

答案 0 :(得分: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).

答案 1 :(得分:0)

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

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

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