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.)