Reputation: 55
I need to count all the internal nodes of a binary tree using prolog I can count all of the nodes using the following code
internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3 + 1.
internal(nil, 0).
And I thought that by changing the base case to
internal(tree(_,nil, nil), 0).
I could get it to work but it returns false.
here is a test case that should return 4 internal(tree(8,tree(5,tree(2,nil,nil),tree(7,nil,nil)), tree(9,nil,tree(15,tree(11,nil,nil),nil))),I).
Could anyone tell me where my mistake is? Thanks
After reading your suggestions I've got this but it still fails.
internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3.
internal(tree(_,nil, R), I):- !, internal(R, I3), I is I3 + 1.
internal(tree(_,L, nil), I):- !, internal(L, I3), I is I3 + 1.
internal(tree(_,nil, nil), 0).
internal(nil, 0).
Upvotes: 2
Views: 1784
Reputation: 476614
If you change the predicate to:
internal(tree(_,nil, nil), 0).
internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3 + 1.
then this will fail for trees with a nil
child and a non-nil
child this will fail.
Indeed: if the tree is tree(1, nil, tree(2, nil, nil))
, then Prolog will first try to satisfy the base case, but sine nil
is not equal to a tree(_, nil, nil)
, that fails. Next it aims to satisfy the recursive case, and first unifies L = nil
, and R = tree(2, nil, nil)
. Now it calls internal(L, I2)
, but since internal(nil, I1)
can not be satisfied it fails.
We can thus first construct a predicate that satisfies if the two subtrees result in an internal node:
isinternal(tree(_, _, _), _).
isinternal(_, tree(_, _, _)).
so this predicate succeeds if at least one of the subtrees is a tree(_, _, _).
. Now we can use this predicate to count the number of internal nodes:
internal(nil, 0).
internal(tree(_, nil, nil), 0).
internal(tree(_, L, R), I) :-
isinternal(L, R),
internal(L, NL),
internal(R, NR),
I is NL + NR + 1.
The above can be improved in terms of readability. I leave this as an exercise.
Upvotes: 1