0

Assuming here is a binary search tree, and given the rule that above(X,Y) - X is directly above Y. Also I created the rule root(X) - X has no parent.

Then, I was trying to figure out what the depth of node in this tree. Assume the root node of tree is "r" So I got fact level(r,0). In order to implement the rule level(N,D) :-, what I was thinking is it should be have a recursion here. Thus, I tried

level(N,D): \+ root(N), above(X,N), D is D+1, level(X,D). 

So if N is not a root, there has a node X above N and level D plus one, then recursion. But when I tested this, it just works for the root condition. When I created more facts, such as node "s" is leftchild of node "r", My query is level(s,D). It returns me "no". I traced the query, it shows me

  1    1  Call: level(s,_16) ? 
  1    1  Fail: level(s,_16) ?

I just confusing why it fails when I call level(s,D)?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
user1234567
  • 57
  • 2
  • 11

1 Answers1

0

There are some problems with your query:

  • In Prolog you cannot write something like D is D+1, because a variable can only be assigned one value;
  • at the moment you call D is D+1, D is not yet instantiated, so it will probably cause an error; and
  • You never state (at least not in the visible code) that the level/2 of the root is 0.

A solution is to first state that the level of any root is 0:

level(N,0) :-
    root(N).

Now we have to define the inductive case: first we indeed look for a parent using the above/2 predicate. Performing a check that N is no root/1 is not necessary strictly speaking, because it would conflict with the fact that there is an above/2. Next we determine the level of that parent LP and finally we calculate the level of our node by stating that L is LP+1 where L is the level of N and LP the level op P:

level(N,L) :-
    above(P,N),
    level(P,LP),
    L is LP+1.

Or putting it all together:

level(N,0) :-
    root(N).
level(N,L) :-
    above(P,N),
    level(P,LP),
    L is LP+1.

Since you did not provide a sample tree, I have no means to test whether this predicate behaves as you expect it to.


About root/1

Note that by writing root/1, you introduce data duplication: you can simply write:

root(R) :-
    \+ above(_,R).
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Yes! level(N,D) :- above(X,N), depth(X,O), D is O+1. is what I did later. But I lost the base case. I followed by the recursion. So above is my general case and the base case really annoyed me cause I tried "level(N,D) :- root(N), D is 0." "level(N,0)." and they does not work. The base case is necessary. I was thought I should represent all of variables that provided in "()" after":-". – user1234567 Feb 29 '16 at 19:23
  • The first one should work `level(N,D) :- root(N),D is 0.` The second means every `N` has level `0` (thus all nodes of the tree). – Willem Van Onsem Mar 01 '16 at 11:19