Prolog递归返回多个结果

时间:2012-10-12 23:35:56

标签: recursion prolog

首先,这是一个准备给我的家庭作业问题。

我应该编写一个带有二叉树的谓词btree_height \ 2,并且(现在)只返回树的高度。

二叉树表示为:

node(node(leaf, x, leaf), x, node(leaf, x, leaf)) 

其中x是节点的整数值。 (这只是一个示例树)。

我的代码如下:

btree_height(leaf, 0).
btree_height(node(leaf,_,leaf), 1).
btree_height(node(LT,_,RT), D):-
    btree_height(LT, DL), 
    btree_height(RT, DR),
    D is max(DL,DR)+1.

我遇到的问题是,当我打电话给btree_height(BT,D)并且如果深度为4则用BT提供它然后它会递归4次并且“返回”数字4四次。据我的教授说,这是一个不正确的行为,因为它应该只返回一次数字4。 (使用上面的例子,它返回数字2两次)

这是我第一次在Prolog编码,我不知道应该从哪里开始寻找。

如果它有所作为,这在技术上是SWI-Prolog ......

1 个答案:

答案 0 :(得分:2)

由于这是作业,我不会给你完整的解决方案。

当您的谓词命中与node(leaf, _, leaf)匹配的节点时,它首先执行第二个子句。返回一个。然后,当你要求它回溯时,它也会执行第三个子句,因为匹配输入LT=leafRT=leaf,所以它将递归两次并命中leaf案例两次。

下次,如果您必须自己调试此类问题,trace/1是一个很好的工具:

2 ?- trace.
true.

[trace] 2 ?- btree_height(node(node(leaf, x, leaf), x, node(leaf, x, leaf)), H).
   Call: (6) btree_height(node(node(leaf, x, leaf), x, node(leaf, x, leaf)), _G821) ? creep
   Call: (7) btree_height(node(leaf, x, leaf), _G903) ? creep
   Exit: (7) btree_height(node(leaf, x, leaf), 1) ? creep
   Call: (7) btree_height(node(leaf, x, leaf), _G903) ? creep
   Exit: (7) btree_height(node(leaf, x, leaf), 1) ? creep
   Call: (7) _G821 is max(1, 1)+1 ? creep
   Exit: (7) 2 is max(1, 1)+1 ? creep
   Exit: (6) btree_height(node(node(leaf, x, leaf), x, node(leaf, x, leaf)), 2) ? creep
H = 2 ;
   Redo: (7) btree_height(node(leaf, x, leaf), _G903) ? creep
   Call: (8) btree_height(leaf, _G903) ? creep
   Exit: (8) btree_height(leaf, 0) ? creep
   Call: (8) btree_height(leaf, _G903) ? creep
   Exit: (8) btree_height(leaf, 0) ? creep
   Call: (8) _G911 is max(0, 0)+1 ? creep
   Exit: (8) 1 is max(0, 0)+1 ? creep
   Exit: (7) btree_height(node(leaf, x, leaf), 1) ? creep
   Call: (7) _G821 is max(1, 1)+1 ? creep
   Exit: (7) 2 is max(1, 1)+1 ? creep
   Exit: (6) btree_height(node(node(leaf, x, leaf), x, node(leaf, x, leaf)), 2) ? creep
H = 2

(如果它显示creep,我按 Enter 。)