练习3.17“人工智能的Prolog编程”,作者: 伊万·布特拉科(Ivan Btrako)
我了解max谓词,但是在跟踪maxList时遇到了麻烦。我正在尝试用伪代码编写逻辑来帮助我
但是,我不了解给出的解决方案,因此尝试跟踪它并失败了。我在将MaxRest映射到Max和基本情况时遇到了麻烦。另外,我不理解为什么在将[X,Y | Rest]与[Y | T]统一时prolog不会给出错误。示例[1,3,[7,2]]与[3 | [7,2]]。
max(X,Y,X):-
X>=Y.
max(X,Y,Y):-
X<Y.
maxlist( [X], X). %what does this line do?
maxlist( [X,Y|Rest], Max):-
maxlist( [Y|Rest], MaxRest),
max(X, MaxRest,Max).
任何帮助跟踪将不胜感激。
答案 0 :(得分:2)
由于您了解max/3
,因此无法解释。
maxlist( [X], X). %what does this line do?
maxlist( [X,Y|Rest], Max):-
maxlist( [Y|Rest], MaxRest),
max(X, MaxRest,Max).
这是经典的递归列表模式,该模式在处理项目之前进行递归。带有尾部调用的普通递归列表模式为
process_list([H|T],R) :-
process_item(H,R),
process_list(T,R).
process_list([],R).
但是这里是
process_list([H|T],R) :-
process_list(T,R),
process_item(H,R).
process_list([],R).
在遍历列表后处理项目的地方。
这也一次处理两个项目,即
[H1,H2|T]
因为比较需要两项。
此
maxlist( [X,Y|Rest], Max):-
maxlist( [Y|Rest], MaxRest),
只是将值从列表中删除,然后将它们推入堆栈,以便在回溯时将具有一个用于比较的值,即MaxRest
是{中所有值的最大值{1}}和当前值Rest
。您可能会认为应该是X
,但是当列表中只有一项时,列表实际上是Y
,实际上是[Y|[]]
,并且与该子句{{ 1}}。
那么[Y]
的作用是什么?列表的常见基本情况只是返回列表的maxlist( [X], X).
,但是在这种情况下,仅需要最后一个值作为值返回,因此这将maxlist( [X], X).
从第一个列表中移出参数,并将其作为第二个参数中的值返回,以便当列表中只有一项时,它变为predicate([],R).
,这是最大值。当执行X
时,它具有MaxRest
返回值的值,并且在解构列表时在堆栈上具有max(X, MaxRest,Max)
的值。结果是MaxRest
,它作为X
中的第三个参数返回,在再次回溯时成为Max
的值。
问问这是否没有道理。
我不明白为什么Prolog在统一时不给出错误 [X,Y | Rest]与[Y | Rest]。
示例[1,3,[7,2]]与[3 | [7,2]]
实际上
maxlist( [X,Y|Rest], Max)
因此,尽管您的示例确实给出了错误,但这并不是要做什么
MaxRest
从列表?- [1,3,[7,2]] = [3|[7,2]].
false.
开始,并与[X,Y|Rest] and [Y|Rest]
统一
[1,2,3,4]
请注意,[X,Y|Rest]
将是?- [1,2,3,4] = [X,Y|Rest].
X = 1,
Y = 2,
Rest = [3, 4].
。
[Y|Rest]
请勿尝试将[2|[3,4]]
与?- [1,2,3,4] = [X,Y|Rest],A = [Y|Rest].
X = 1,
Y = 2,
Rest = [3, 4],
A = [2, 3, 4].
统一,而应将[X,Y|Rest]
与[Y|Rest]
与Rest
,{{1 }}存储在堆栈中,但没有传递到stackframe的下一级。
如果您真的想了解列表,请使用此列表查看它们
Rest
如果您拥有本书的第4版,请参阅第61页的图3.1。
答案 1 :(得分:2)
Prolog谓词根据逻辑来定义关系,该逻辑说如果(:-
)主体为true,则子句的头部为true。这可以帮助您正确读取谓词:
max(X,Y,X):-
X>=Y.
这说:
X
是X
和Y
的最大值。如果X >= Y
为真。
您可以类似地阅读max(X,Y,Y)
的条款。
现在看看:
maxlist( [X], X).
在这里,我们将maxlist
定义为列表的最大值。该特殊条款说:
X
是列表[X]
的最大值。
在这种情况下,没有 if 条件(:-
),因为无需其他条件即可建立此规则。
然后有一个递归子句:
maxlist( [X,Y|Rest], Max):-
maxlist( [Y|Rest], MaxRest),
max(X, MaxRest,Max).
这说:
Max
是列表[X,Y|Rest]
的最大值如果MaxRest
是列表[Y|Rest]
的最大值而Max
是列表的最大值X
和MaxRest
的最大值。
此递归子句和先前的基本案例子句完全定义maxlist
。如果您仔细阅读该书,它应该看起来完全合乎逻辑。
我不明白为什么将
[X,Y|Rest]
与[Y|T]
统一时prolog不会给出错误
我不明白此评论。 Prolog在代码中没有尝试统一这两个术语。您的示例示例[1,3,[7,2]]
和[3|[7,2]]
不会统一,因为第一个是三个元素的列表:1、3和[7,2],而另一个是三个元素的列表:3 ,7和2。要使两个列表不可统一,不仅长度必须相同,而且列表中的每个对应术语也必须不可统一。
然后,什么会使[X,Y|Rest]
和[Y|T]
无法确定?您可以将[X,Y|Rest]
编写为[X|[Y|Rest]]
,如果满足以下条件,则很容易看到它们是无法确定的:
X = Y,
[Y|Rest] = T
换句话说,列表必须具有(a)至少两个元素,并且(b)前两个元素相同。