4

首先,这是一个摆在我面前的家庭作业问题。

我应该编写一个谓词 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) 并为其提供 BT(如果深度为 4)时,它会递归 4 次并“返回”数字 4 四次。根据我的教授的说法,这是一种不正确的行为,因为它应该只返回数字 4 一次。(使用上面的示例,它会返回数字 2 两次)

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

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

4

1 回答 1

2

Since this is homework, I won't give you the full solution.

When your predicate hits a node that matches node(leaf, _, leaf), it first executes the second clause. That returns one. Then, when you ask it to backtrack, it will also execute the third clause, because that also matches the input with LT=leaf and RT=leaf, so it will recurse twice and hit the leaf case both times.

Next time, if you have to debug this kind of problem yourself, trace/1 is a good tool:

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

(Where it says creep, I pressed Enter.)

于 2012-10-12T23:52:33.510 回答