1

How do I get a predicate in prolog to return a value?

I need to find a node of a tree and also check if its a min heap or not. I'm guessing it goes something like this:-

getnode(tree(_, node, _), node).

My code so far is this

minheap(tree(L, Node, empty)) :-
    getnode(L, Val),
    Node =< Val,
    minheap(L).
minheap(tree(empty, Node, R)) :-
    getnode(R, Val),
    Node =< Val,
    minheap(R).

getnode(tree(_,n,_)  , n).

Input is of the type-

minheap(tree(empty,3,tree(tree(empty,8,empty),5,tree(empty,7,empty)))).

Output should be true.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • What is the format of the `tree/3`? `tree(Left,Value,Right)`? – Willem Van Onsem Apr 03 '17 at 14:29
  • Yes,Thats correct – John Keaton Apr 03 '17 at 14:32
  • A tree rooted at a node is a min-heap iff the value of the node is less than (or at least not greater than) values of all (usually: both) child nodes _and_ all subtrees rooted at children are min-heaps, too. Is your code able to test _all_ children of a given node? – CiaPan Apr 03 '17 at 14:33
  • That is exactly where I am stuck. How do I get a extract a node from the input. My logic might be incorrect at this point. – John Keaton Apr 03 '17 at 14:35
  • @JohnKeaton: also mind that **variables start with an uppercase**. So for `getnode/2` the `n` is **interpreted as a constant**. – Willem Van Onsem Apr 03 '17 at 14:51

1 Answers1

0

In order to solve this, you better define some utility predicates that make life simpler.

For instance predicate lower/2. lower(Tree,Value) that succeeds if either Tree is empty, or the value of the Tree is higher than Value. So you can implement this like:

lower(empty,_).
lower(tree(_,TreeValue,_),Value) :-
    TreeValue >= Value.

Next we define the predicate minheap/1. An empty tree is definitely a minheap. Furthermore a tree is a minheap if its children are lower and all the children are minheap/1s themselves, so:

minheap(empty).
minheap(tree(Left,Value,Right)) :-
    lower(Left,Value),
    lower(Right,Value),
    minheap(Left),
    minheap(Right).

and that's it. This is better than trying to do all the work in the minheap/1 predicate since in that case you should handle five cases: empty, tree(empty,val,empty), tree(tree(..),val,empty), tree(empty,val,tree(..)) and tree(tree(..),val,tree(..)). By using the lower/2 helper predicate, we only have to handle two cases: empty and tree/3.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555