Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
列表中的Prolog max_Prolog - Fatal编程技术网

列表中的Prolog max

列表中的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([1,5,3]、5)等查询,但无法执行 自行查找最大值并给出以下错误:

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.