Prolog递归不起作用

时间:2017-05-25 10:54:37

标签: prolog

我正在学习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而停止但是它无限期地进入循环。我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

想想这是做什么的:

length([H|T],L), L =< 3
  1. 列出清单
  2. 检查其长度是否小于3,如果是 - 则成功,其他明智的回溯到长度/ 2并尝试制作另一个列表,然后检查该列表的长度是否小于3.
  3. 但是我们知道list / 2是按照更大的顺序创建列表,     所以我们知道如果长度3的列表失败,那么下一个列表     在后退跟踪上创建的将更大,所有其他列表..但是     prolog不知道。你可以想象写一个长度     也许,谓词以不同的顺序搜索列表     随机地,或从预定义的大尺寸到更小的列表。     然后我们希望回溯按原样工作。

    无论如何,这就是你获得无限递归的原因,它将继续尝试不断增加的新列表。

    您可能会发现添加约束是解决问题的好方法:

    Using a constrained variable with `length/2`