Prolog predicate single node in tree - prolog

Code a predicate that finds all nodes in the tree with exactly one single child node.
Given the tree
treeEx(X) :-
X = t(73,t(31,t(5,nil,nil),nil),t(101,t(83,nil,t(97,nil,nil)),nil)).
73
/ \
31 101
/ /
5 83
/
97
It should return L = [31, 101, 83]
I have tried the following, but it returns all nodes. I do not know how to list only the single child nodes.
single(nil,[]).
single(t(X,L,R),[X|S]) :-
append(SL,SR,S), single(L,SL), single(R,SR).

[..] a predicate that finds all nodes in the tree with exactly one single child node.
First think about which cases You're interested in:
t(V,nil,R) := a node with value V and a single (right) child R.
t(V,L,nil) := a node with value V and a single (left) child L.
Then think about the other cases, which You're not interested in (in as general terms as possible):
t(V,nil,nil) := a node with value V and no children.
t(V,L,R) := a node with value V and both a left (L) and right (R) child.
Next think about what You want to "do": Collect the values of the cases You're interested in in a list. Thus, when You have a case You're interested in, then You'd need to add the value V to a list with Your results:
[V|RestResults] % whatever RestResults is, not important atm
With that, You can write Your predicate: You know it has one "input" parameter (the tree) and one "output" parameter (the list). First the cases You're interested in:
single(t(V, nil, R), [V|Vr]) :- single(R, Vr).
single(t(V, L, nil), [V|Vl]) :- single(L, Vl).
You add the value V to the results (list of values) You get from the single child branch.
Next the cases You're not interested in. First the easy one:
single(t(_,nil,nil), []).
That's a leaf node (no children). Its value isn't interesting, and there are no results that might come from its children, so the result list is the empty list.
Finally, the most complex case:
single(t(_, L, R), X) :- single(L, Vl), single(R, Vr), append(Vl, Vr, X).
Two children; the value isn't interesting in this case, but the children are: You need to gather their result lists and append them to create the result list of this node.
Now, the order in which You write these rules is normally important in Prolog, but in this case the order doesn't matter (when Prolog uses the "wrong" rule for a node, e.g. the last one - two children - for a t(_,nil,nil), then it quickly arrives in a situation - single(nil, _) - where no rule matches, and backtracks to the "correct" rule). Nonetheless I'd sort the rules according to how "specific" their pattern is: First the rule for no children, then the two for one child, and finally the one for two children.
(Live on ideone)

Related

How to convert tree to list in Prolog?

Implement the predicate treeToList(X,List), where X is a given ordered non-empty binary tree, and List is an ordered list of elements in nodes of the tree.
4
/ \
2 6
/ \ / \
1 3 5 7
is an ordered tree given as an input to predicate "treeToList".
Your program must compute the list [1,2,3,4,5,6,7].
Here is the codes I had so far:
treeToList(X,List) :- binaryTree(X), convert(X,List).
convert( tree(Element,void,void), List) :- List=[Element].
The helping predicate convert(X,List) is true if X is a given non-empty tree, and List is a representation of this tree as an ordered list.
But I have no idea how to write the recursive part of this question
convert( tree(Root,Left,Right), List) :-
Can someone help me with this part?
You never explicitly said what your data structure looks like in Prolog, but I can infer that you have basically two kinds of tree node:
tree(Element, Left, Right)
void
To handle any recursive data structure, you write a recursive predicate. Usually (but not always) you want clauses for each kind of element. In Haskell, this is a bit more clear because you have to define your types and their constructors, but you can apply the same reasoning here. So your convert/2 predicate is going to have a clause for each of your kinds of element:
convert(void, ...) :- ...
convert(tree(Element, Left, Right), ...) :- ...
You can see right away that the first clause is going to be pretty simple:
convert(void, []).
The second clause is where things get a bit more interesting. The key is to recursively apply convert/2 to the subtrees on the left and right, and then you need to do something with the element you have:
convert(tree(Element, Left, Right), Rest) :-
convert(Left, LeftList),
convert(Right, RightList),
append(LeftList, [Element|RightList], Rest).
Note that I'm prepending the current element to the right list before appending. This is to insert the element in its proper place in the list for an in-order traversal, to get you the result you want:
?- convert(tree(4, tree(2, tree(1, void, void), tree(3, void, void)),
tree(6, tree(5, void, void), tree(7, void, void))),
List).
List = [1, 2, 3, 4, 5, 6, 7].
This gives you an in-order traversal. If you wanted a pre-order or a post-order traversal you would instead place the element in another position, such as at the start of the result or the end of the result.
Your tree has, based on the question, two "families" of data:
the constant void; and
a compound term with a tree/3 with as arguments the value and the left and right subtree.
We can implement a predicate like #DanielLyons demonstrated. We can slightly optimize this by defining a predicate convert/3 where we the first parameter is the tree to convert, the second parameter is the head of the list, and the third parameter is the tail of the list.
We can thus define our predicate as:
convert(void, L, L).
convert(tree(V, L, R), H, T2) :-
convert(L, H, [V|T1]),
convert(R, T1, T2).
If we thus encounter a void, then the start and the end of the list remain the same. If we encounter a tree(V, L, R), we will first recursively call convert(L, H, [V|T1]). By writing [V|T1] as tail, we thus force Prolog to yield the V value in the result. The tail T1 is then the start of the convert/3 of the second subtree.
We then can define convert/2 in terms of convert/3:
convert(T, L) :-
convert(T, L, []).

Prolog program about lists

I am a new programmer in Prolog and i tried to do a program that says: make the predicate penta(X), where X is a list and returns true when in X there are 5 consecutive elements where : the first element is the sum between the first and the second. Also the third element is the difference between the 5th and the 4th for example: X = [ ... 5, 7, 12, 18, 30, ... ].
So I did this:
penta(X) :-
\+length(X,0), //here i verify if the lists contains less than 5 elements so it gives false.
\+length(X,1),
\+length(X,2),
\+length(X,3),
\+length(X,4),
(A, B, C, D, E | X),
C is A + B,
C is D - E,
penta(X).
This actually does not compile so it doesn't work yet. Tell me what's wrong with it if you would like.
thank you very much.
In prolog, we write predicates not functions. A predicate defines a rule which will succeed or fail on sets of instantiated variables. So you want a predicate, penta(X) that succeeds if X is a list that contains 5 consecutive elements meeting your criteria.
Start from the top. Either the 5 consecutive elements that meet the criteria are at the head of your list, or they are later in the list.
% Succeed if the first 5 elements meets the criteria
penta([A, B, C, D, E |_]) :-
... % what goes here for this to succeed?
% Succeeds if the rest of the list succeeds, without the first element
penta([_|T]) :- penta(T).
I think these are the only two rules you need. Anything else you query that doesn't match these will fail by default, which is what you want. You don't need to check for the length for the 0 through 4 length cases. Those cases will fail the above predicates.
You'll notice that, depending upon how you implement the above, it might succeed several times. That is, it may find more than one solution. You need to decide if that's what you want, or if you want it to stop after one solution. I'll leave that as further exercise.

How do I check is full binary tree?

How do I check full binary tree in prolog? I have the 2 base cases
1) if is empty tree, return yes
2) if is just root only, return yes
I'm stuck at the third one and I not sure what should I do with it. We only allow to use 1 arity: full(T).
btree([]).
btree([H|T]):-btree(T).
btree([H|T]):-btree(H),btree(T).
full([]).
full([H]).
full([H|T]):-
anyone can guide me please. My idea is a tree does not have two nonempty tree then it is a full binary tree.
P/S: I am still new to stackoverflow. If I did ask something silly or improper way please do tell me. I want to learn how to use stackoverflow and also make sure of it in proper way.
I would first probably choose a different representation for binary tree. In Prolog, it's generally more conventional and efficient to use a simple atom (such as nil) as a nil node, and something like btree(Value, Left, Right) as the tree term. Outside of that, the solution looks quite like what #pyon suggested.
% full_btree succeeds if `Tree` is a full binary tree
full_btree(Tree) :-
full_btree(Tree, _).
full_btree(nil, 0).
full_btree(b(_, LeftTree, RightTree), Depth) :-
Depth #> 0,
SubDepth #= Depth - 1,
full_btree(LeftTree, SubDepth),
full_btree(RightTree, SubDepth).
The condition Depth #> 0 ensures, regardless of inputs, that the depth will not become negative, and thus helps ensure termination.
I'm going to assume that you represent trees as follows:
A leaf is an empty list.
A non-leaf node is a three-element list, whose last two elements are the subtrees.
Then:
helper([], 0).
helper([_,L,R], H) :- H #= G + 1, helper(L, G), helper(R, G).
/* Old version: helper([_,L,R], H) :- helper(L, G), helper(R, G), H is G + 1.
* The improvement in the new version was suggested by lurker. Thanks!
*/
full(T) :- helper(T, _).
This works because full binary trees can be inductively defined as follows:
A leaf node is a full binary tree of height 0.
An non-leaf node whose children are both full binary trees of height G, is itself a full binary tree of height G + 1.
Ok, since there is already an answer that doesn't answer the question at face value, here is mine. It doesn't add much anything to the answer by #lurker, it just offers details and explanations that were too much for comments. It also avoids CLP(FD) completely, which is why I felt it should be a separate answer.
You can start (as #lurker has) by using a more conventional binary tree representation. The empty tree is nil, and the non-empty tree is bt(Value, Left, Right) where Value is the value at this node and Left and Right are the left and right sub-trees. This is the conventional representation because it is at the very least more memory efficient. A "leaf" (a tree without sub-trees) is, in your original representation:
.(Value, .([], .([], [])))
instead of:
bt(Value, nil, nil)
The amount of memory needed to represent the two would be different between different Prolog implementations, but I don't know how to make the first smaller than the second.
Then: as #false commented above, a list is usually a collection of Things which conventionally has the following properties:
There can be no Things, or any number of Things in the collection;
The order of Things matters;
All the Things are somehow the same.
Using a list like you do breaks the last convention: the first argument is a value, while the second and third arguments are trees.
This doesn't exclude using list for representing a binary tree but it is unfamiliar.
With this out of the way: successor arithmetic is a silly way of doing actual arithmetic, but it is very convenient if you want to use pattern matching for non-negative integers. You cannot do it with the built-in integer type of Prolog, like 0 or -23 or whatever. Successor arithmetic gives you:
a zero which is structurally different from all positive integers: 0 vs s(_)
adding and subtracting is done by pattern matching, and both are done with the same operation: X + 1 is s(X).
negative numbers are not possible
So, you could define your "full tree" like this:
full_btree(T) :-
full_btree(T, _).
full_btree(nil, 0).
full_btree(bt(_, L, R), s(D)) :-
full_btree(L, D),
full_btree(R, D).
The s(D) and the two Ds state that the tree in your first argument is one deeper than the sub-trees, and that both sub-trees are the same depth. The empty tree nil has a depth of 0 (as defined in the first clause of full_btree/2).
This works as follows:
?- full_btree(nil).
true.
?- full_btree(bt(x, nil, nil)).
true.
?- full_btree(bt(x, bt(y, nil, nil), nil)).
false.
?- full_btree(bt(x, bt(y, nil, nil), bt(z, nil, nil))).
true.
?- full_btree(T), numbervars(T).
T = nil ;
T = bt(A, nil, nil) ;
T = bt(A, bt(B, nil, nil), bt(C, nil, nil)) ;
T = bt(A, bt(B, bt(C, nil, nil), bt(D, nil, nil)), bt(E, bt(F, nil, nil), bt(G, nil, nil))) . % and so on
One more thing: to close the circle, you can do successor arithmetic with lists, too. Just use [] instead of 0 and [_|X] for s(X). With this, you would have:
full_tree(nil, []).
full_tree(bt(_, L, R), [_|D]) :-
full_tree(L, D),
full_tree(R, D).
This is slightly less memory efficient, instead of s(s(s(0))) you would have .(_, .(_, ,(_, []))). However! it is now much easier to make actual integers out of the successor-notation integers, and the other way round: just use length/2. Writing a predicate that converts between s(s(...)) and an integer that works both ways in pure Prolog is not as trivial. I think it is possible to search Stackoverflow for such questions.

Recursive similarity between trees according to the number of common subtrees in Prolog

I am stufying Prolog using SWI Prolog and I am finding many difficult with this code snippet that found if 2 binary trees have N common subtree (having the same root):
/* BASE CASE: T1 and T2 are two tree composed of only the root X so it is
TRUE that they have exactly one common subtree
*/
delta(tree(X,[]),tree(X,[]),1):- !.
/* RULE: T1 and T2 are DIFFERENT and are structured tree.
It is TRUE that T1 and T2 have N subtrees if it is TRUE that:
*/
delta(tree(X,RX),tree(X,RX1),N):- sons(RX,SX),
sons(RX1,SX)
subdelta(RX,RX1,N),
!.
/* Else whatever T1 and T2 it is true that they have 0 common tree
(here we are in the case that the previous delta\2 predicate are
boot failed)
*/
delta(_,_,0):- !.
subdelta([],[],1).
subdelta([T1|R1],[T2|R2], N):-
delta(T1,T2,N1),
subdelta(R1,R2, NR),
N is (1 + N1)*NR.
I think that the delta/3 predicate it is true if the first tree have N common subtrees with the second tree
He rappresent the tree in this way:
tree(F, LIST_OF_SUBTREES).
So for example this is a tree composed by a root X and two leaves u and v:
tree(x, [tree(u,[]), tree(v,[])])
I think that the delta/3 predicate it is declined into the 3 possible cases:
1) T1 and T2 are two tree composed of only the root X so it is TRUE that they have exactly one common subtree
**2) T1 and T2 are DIFFERENT and are structured tree that have more levels so it is TRUE that T1 and T2 have N subtrees if it is TRUE that: ?!?!
3) Else, if both the prevuous delta\2 predicate are failed, whatever T1 and T2 it is true that they have 0 common tree
I think that this interpretation is correct (I hope so...) but I have some difficulties to understand the second rule: what could be sons/2 predicate (it seems to me that this is note a SWI Prolog built in predicate and I have no its implementation on the slide where I am studyin)
What is for you? And what is it's logic?
Tnx
Andrea
Your interpretation of the three rules seems reasonable to me. For comparison, I would rephrase them as:
delta(T1, T2, 1) holds if T1 and T2 have the same value and are empty (leaf nodes).
delta(T1, T2, N) holds if T1 and T2 have N common subtrees.
delta(T1, T2, 0) holds if T1 and T2 have 0 common subtrees.
I'm unclear on why these cuts are necessary. I suppose they're green cuts, because a pair of trees can't have 1, N and 0 common subtrees simultaneously.
sons/2 is interesting. I could imagine it working a few different ways. One thing we know for sure is that if two trees have common subtrees, sons/2 should generate the same value; it must work that way because otherwise sons(RX, SX), sons(RX1, SX) wouldn't ever work. (Note that there's a missing comma on that line).
One question that remains is, does sons/2 work by generating all the subtrees, or just the nearest pair? It seems likely to me that it generates the nearest pair only, because subdelta/3 calls delta/3, leading to indirect recursion. If sons/2 generated all subtrees, this would result in unbounded recursion or at least a lot of unnecessary work. So I would bet that sons/2 looks like this:
sons(tree(_,Children), X) :- member(X, Children).
This suggests at least one case where delta/3 is going to do something more intelligent than one would expect at first blush: the case where T1 and T2 are reflections of each other. sons/2 of T1 and T2 will unify the left with the right and then the right with the left, so you'll get the maximal similarity from sharing subtrees but not exact structure.
What's most surprising to me about this is that delta/3 doesn't seem to be counting differences, it seems to be counting similarities. This isn't what one would expect from the name, but it follows from the implementation. And it's hard to imagine how one would count differences directly--what is the upper limit? With files, for instance, you can count the differences by saying, each line could be the same (0) or different (1) and then adding up the differences.
Hope this is on the right track and helps!

How does maplist work in a program that inserts elements into an AVL Tree

I am studying Prolog and I could not follow the lessons so I have some doubts relating to a particular use of the maplist built in SWI Prolog predicate.
So let me explain my situation:
I have a personal predicate named addavl(Tree/Height, Element, NewTree/Height) that insert the element Element into the AVL tree Tree (where Height is the height of this original tree) and generate a new AVL tree named NewTree that contains Element and that have a new height Height
Now I have a list of elements and I would add these elements to an AVL tree (that at the beginning is void), so I have the following predicate (that work fine).
I have some doubts related to the use of maplist/4 SWI Prolog built in predicate and I would also know if my general interpretation of all this predicate is correct or if am I missing something.
/* Predicate that from a given list of elements build an AVL Tree: */
buildTree(List,Tree):-
length(List, N), % N: the number of element in List
/* Create L1 as a list that have the same number of element of List
For example if List have N=4 element L1=[A,B,C,D] where A,B,C,D
are variable that are not yet set
*/
length(L1,N),
/* Se fosse: append(L1,[Tree],NewList) otterrei: NewList=[A,B,C,D|Tree]
ma essendo NewList=[_|L2] so L2=[B,C,D|Tree]
*/
append(L1,[Tree],[_|L2]),
/* Put the couple (nil,0) in the L1 head so I have that A=(nil,0) that
represents an empty AVL tree:
*/
L1=[nil/0 |_],
/* Call addavl passing as parameter the tree in the L1 head, the value
to insert in the List Head and the head of L2 as the current new Tree-
When the variable Tree is reached it represents the final AVL tree
*/
maplist(addavl, L1, List, L2).
My interpretation of the entire predicate is the following one:
First N variable contains the length of the original element list List that I would to insert in the AVL tree
Then is created a new list L1 that have the same number of element of the original list List, but in this case L1 contains variables that are not yet set up with a value.
So for example, if the original element list is:
List = [5, 8, 3, 4] the L1 list will be something like: L1 = [A, B, C, D]
where A, B, C, D are variables that are not yet valorized.
Now there is this statement that must be satisfied:
append(L1,[Tree],[_|L2]),
that I read in this way:
if I had append(L1,[Tree],NewList) instead the previous statement I would have that:
NewList = [A,B,C,D,Tree] where A,B,C,D are the previous not set variable of the L1 List and Tree is a new not set variable.
But in my case I have that NewList = [_|L2] so L2 = [B,C,D,Tree].
Now the meaning of the previous append operation is the creation of the L2 list that at the beginning contains n not valorized variables (in the previous example 4 not valorized variables: B,C,D, Tree).
Each of these variables represents a Tree in which it was inserted a new element in the original list List
So, at the beginning the program put the void AVL tree in the head of this list (in my example in the A variable) by this instruction: L1=[nil/0 |_],
So in the head of the L1 variabile there is the void tree that have 0 as height (and a void tree is a correct AVL Tree)
And now I have the FIRST DOUBT: by the previous operation I have valorized the head variable of the L1 list but previous of this operation I have created the NewList=[_|L2] list using this statement:
append(L1,[Tree],[_|L2])
This means that the _ anonymous variable of [_|L2] list match with nil/0 AVL tree?
This work in this way also if I have valorized the L1 head after that I have create the [_|L2] list appending L1 list to [Tree]?
Ok, if my interpretation is correct go on to my SECOND DOUBT that it is related to how exactly work the maplist SWI Prolog built in predicate..
I have:
maplist(addavl, L1, List, L2).
What exactly do this predicate?
Reading on the official documentation: http://www.swi-prolog.org/pldoc/man?predicate=maplist%2F2
it seems to me that work in the following way:
I have the addavl predicate that is the GOAL that have to be satisfied on each element of the lists
Remembering that addval predicate work in this way: addavl(Tree/Height, Element, NewTree/Height).
So:
1) L1 is the list of the AVL Tree (the first is the void AVL Tree: nil/0)
2) List is the original list that contain the element to insert
3) L2 is the list that contains the AVL tree that I will create.
So I think that now work in the following way:
First take the void AVL Tree (nil/0) from the head of L1, take the first element do add from List, execute the GOAL (insert this element into the void AVL Tree) and put the result in the head of the L2 list (that, according to my previous example, is the B variable, so the B variable contains the AVL Tree that contain the first element of the List element) list**
Then repeat this procedure inserting all the other elements in of the elements list List and finally, the last element of the L2 list (the Tree variable) will represent the final AVL Tree in which all the elements were inserted.
Is my reasoning correct or am I missing something?
in Prolog we say "not yet instantiated variable" or "uninstantited variable".
About L1=[nil/0 |_], we can call it "initializing it with an initial value".
the _ in [_|L2] does indeed match the init value, and we don't care about it.
(this gives an idea of calling append(L1, [Tree], [nil/0 | L2]), instead of the two calls in original code).
Yes, order of operations is not important. X=t(A), A=2 or A=2, X=t(A) both result in the same substitution, A=2, X=t(2).
maplist( pred, ...Lists ...) works so that pred must be satisfied on elements from lists, taken pair-wise (or by columns). E.g. maplist(plus, [1,2,3],[4,X,8],[5,6,Y]).
The lists L1 and L2 both share structure:
nil/0 B C D Tree
------------------
L1
-----------------
L2
maplist sees them, and processes them, by feeding them by columns to addavl:
nil/0 B C D % L1
E1 E2 E3 E4 % List
B C D Tree % L2
so yes, it does it like you say.
I don't think your teacher will accept this as an answer. You should write a direct recursive solution instead. Both variants describe same iterative computational process of progressively adding elements into a tree, using the output of previous call as input to the next. But in any given implementation one can be optimized far better than the other. Using lists, here, will most probably be less efficient than a recursive variant.

Resources