列表中的Prolog max
这似乎适用于mymax([1,5,3]、5)等查询,但无法执行 自行查找最大值并给出以下错误:列表中的Prolog max,prolog,Prolog,这似乎适用于mymax([1,5,3]、5)等查询,但无法执行 自行查找最大值并给出以下错误: mymax([], 'list_is_empty'). mymax([Head | []], Max) :- (Max >= Head). mymax([Head | List], Max) :- (Max > Head), mymax(List,Max). 我有点理解为什么会这样,尽管我无法用语言表达。 这是可以修复的还是我的算法完全不正确?该错误是由于与Head比较时Max仍处于未绑
mymax([], 'list_is_empty').
mymax([Head | []], Max) :- (Max >= Head).
mymax([Head | List], Max) :- (Max > Head), mymax(List,Max).
我有点理解为什么会这样,尽管我无法用语言表达。
这是可以修复的还是我的算法完全不正确?该错误是由于与Head比较时Max仍处于未绑定状态所致 您可以这样简化:
ERROR: >/2: Arguments are not sufficiently instantiated
编辑
我试图尽量减少对代码的修改,但正如@mat所指出的,这只适用于表达式列表,例如数字。然后你就可以写了
mymax([Max], Max).
mymax([Head | List], Max) :-
mymax(List, MaxList),
( Head > MaxList -> Max = Head ; Max = MaxList ).
如果您不确定列表的域(即其元素的类型),最好使用运算符:
1 ?- mymax([4+1, 3+3], N).
N = 3+3
但现在:
( Head @> MaxList -> ... )
如果你想让它变得简单,排序,反转,取下头部:
?- mymax([4+1, 3+3], N).
N = 4+1
否则,将第一个元素设置为最大的元素(到目前为止)。然后查看列表的其余部分,如果发现一个元素大于当前最大值,请用它替换当前最大值。这就是@capelical使用if-then-else控制谓词所做的(某种程度上)
一种不使用if-then谓词,而是使用谓词子句,并利用ISO谓词compare
的方法:
mymax(List, Max) :-
sort(List, Sorted),
reverse(Sorted, [Max|_]).
您还可以从任何开源Prolog实现(例如)的标准库中查看
max_list/2
和max_member/2
的实现,以获得更实用的方法(但仍使用if-then-else)。要找到列表的最大值,您可以说它是该列表的一员,此列表中没有比它更大的元素:
?- mymax(L, 13).
低级算术运算符,如
(>=)/2
和(>)/2
仅在其参数被实例化为具体的算术表达式时才起作用
使您的程序也能进行更一般的查询,如<代码> -MyMAX(列表,马克斯).<代码>,考虑使用约束,这些约束在所有主要的Prolog实现中都可用。 例如,在SICStus或SWI Prolog中使用有限域约束:
my_max(L, V) :-
member(V, L),
\+((member(X, L), X > V)).
或等效地使用foldl/4
:
:- use_module(library(clpfd)).
list_max([L|Ls], Max) :-
list_max_(Ls, L, Max).
list_max_([], Max, Max).
list_max_([L|Ls], Max0, Max) :-
Max1 #= max(Max0,L),
list_max_(Ls, Max1, Max).
示例查询和一些结果:
:- use_module(library(clpfd)).
list_max([L|Ls], Max) :- foldl(x_y_max, Ls, L, Max).
x_y_max(X, Y, Max) :- Max #= max(X, Y).
我不明白操作符->还有,你能解释一下为什么我们需要MaxList以及mymax(List,MaxList)通常做什么吗?(IF->THEN;ELSE)回答正确,像往常一样(+1),但这不是为了我们不应该在管道字符周围留空格:
[Head | Tail]
?@mat:同样,你是对的,但新手应该知道,交换两个目标是我们拥有的主要控制流“工具”,如果不是唯一的。否则,我们谈论的不是Prolog…您可能应该明确声明此谓词查找列表中的最大数。这种方法的问题不在于您的程序的时间复杂性为O(n^2)?而使用累加器会导致O(n)时间复杂度。我同意,这是个问题,但对于Prolog,我认为人们必须“思考不同”!不,那是苹果的。你不买Mac电脑,Mac电脑卖给你…:P
:- use_module(library(clpfd)).
list_max([L|Ls], Max) :- foldl(x_y_max, Ls, L, Max).
x_y_max(X, Y, Max) :- Max #= max(X, Y).
?- list_max(Ls, Max).
Ls = [Max] ;
Ls = [_G551, _G554],
Max#>=_G551,
Max#=max(_G551, _G554),
Max#>=_G554 ;
Ls = [_G636, _G639, _G642],
_G657#>=_G636,
_G657#=max(_G636, _G639),
Max#>=_G657,
_G657#>=_G639,
Max#=max(_G657, _G642),
Max#>=_G642.