我正在学习Prolog,我陷入了知识库和基本规则的代码:
rectangle(a1, 3, 5). %Name,Width,Height
rectangle(a2, 1, 2).
rectangle(a3, 4, 3).
calcWH(T,C) :-
rectangle(T,W,_), C is W. % finds the width of the rect.
递归部分是:
calcWTH([],0). % Base case
calcWTH([H | T ] ,K) :-
length([H|T],L),
L =< 3,
calcWTH(T,M),
calcWH(H,O),
K is O+M.
我想用这个代码做什么,使用calcWTH我想计算矩形列表的总宽度。例如
calcWTH([a1,a2,a3],A)
按预期,返回8。令我困惑的是,这段代码只适用于一种方式,而不是另一种方式。例如,当我进行像
这样的查询时calcWTH(A,3)
首先找到A = [a1],然后A = [a2,a2,a2],然后我希望程序因部分length([H|T],L), L =< 3
而停止但是它无限期地进入循环。我在这里缺少什么?
答案 0 :(得分:1)
想想这是做什么的:
length([H|T],L), L =< 3
但是我们知道list / 2是按照更大的顺序创建列表, 所以我们知道如果长度3的列表失败,那么下一个列表 在后退跟踪上创建的将更大,所有其他列表..但是 prolog不知道。你可以想象写一个长度 也许,谓词以不同的顺序搜索列表 随机地,或从预定义的大尺寸到更小的列表。 然后我们希望回溯按原样工作。
无论如何,这就是你获得无限递归的原因,它将继续尝试不断增加的新列表。
您可能会发现添加约束是解决问题的好方法: