在序言中查找数组的最小值

时间:2018-11-10 18:58:32

标签: prolog

我试图编写代码以在Prolog中查找数组(具有> 1个元素)的最小值。

min([H,T|[]], H) :- H < T.
min([H,T|[]], T) :- H >= T.
min([H|T], M) :- min(T, N), min([H|N], M).

但是当我尝试运行它时:

min([1,2,3], K)

涉及单个数组的递归。但是我的第一句话是防止这种情况发生。我假设首先定义的规则在prolog希望减少时会获得更高的优先级。

有人可以帮助我解决错误吗?

链接到代码:https://swish.swi-prolog.org/p/min-array.pl

1 个答案:

答案 0 :(得分:0)

如果逐步执行,很容易发现错误。但是您可能已经尝试过了,所以我不会尝试重复您已经做过的事情。

但是是的,规则具有优先权,但是没有这个优先权与您的想法不同。我非常努力地理解前两行在您脑海中的作用,但这对我来说太困难了。但是,如果您只是运行该程序或进行跟踪,则可以在计算机上看到它的作用,并尝试与它的作用进行比较和对比。

但是要解决该问题,您必须具有两个不同的谓词,而不仅仅是一个谓词。

一个谓词是至少获得两件事。

第二个谓词是通过将第一个谓词应用于第一个和第二个,然后将第一个,第二个和第三个的min的分钟最小化,从而将列表减少为许多事物的最小值,例如:

min([x0, x1, x2, ...) = min(min(min....(x0, x1), x2), ...)

但是第一分钟不是第二分钟。在Prolog中,第一分钟是算术函数。

?- X is min(1, 2).
X = 1.

如果min([1,2,3], X)X is min(min(1, 2), 3)将成功。否则可能会失败。

如何在列表中将min写入min(min(min(...)))中?是个好问题。我发现SWI中的foldl谓词非常好,因此我不会减少自己,但是如果您不喜欢使用foldl进行减少,则可以编写reduce。

min([H|T], Min) :- foldl(min, T, H, Min).
min(A, B, Min) :- Min is min(A, B).

那么多分钟...也许太多分钟?我不知道。您应该更清楚地知道多少分钟是太多分钟。这段代码可能太多了吗?