OCaml - Mirror image of a tree - recursion

My tree type is
type 'a tree = Tree of 'a * 'a tree list;;
How can I get the mirror image of a tree like this? For me is confusing having a list of children, because I do not know how to get individually to each child and do the recursion whitout losing the parent's track, any idea?
EDITED:
I have kept trying and I think I got the solution:
let spec arbol =
match arbol with
Tree(a,[])-> Tree(a,[])
| Tree(a,l)-> Tree(a, List.rev (
let rec aux = function
Tree(a,[])::[]->Tree(a,[])::[]
| Tree(a,[])::l-> [Tree(a,[])]#(aux l)
| Tree(a,t)::[]-> [Tree(a, (List.rev (aux t)))]
| Tree(a,t)::l-> [Tree(a, (List.rev (aux t)))]#(aux l)
in aux l));;
I have tried it with this tree:
let p = Tree(1, [
Tree(2,[]);
Tree(3, [
Tree(6,[]);
Tree(7,[])
]);
Tree(4,[]);
Tree(5,[])
]);;
And I got as result of # spec p;;
-: int tree = Tree (1, [
Tree (5,[]);
Tree (4,[]);
Tree (3,[
Tree(7,[]);
Tree(6,[])]);
Tree (2,[])
])
So I guess my function works as expected. Let me know if it is not correct

If I understand the function you're trying to compute, there is a very simple answer that takes one line of code.
Unfortunately your code introduces so many cases that it's hard to check by eye.
It looks to me like your aux function is intended to calculate the mirror image of a list of trees. However, it doesn't work on an empty list. If you rewrite aux to work on an empty list, you might find that you won't require so many different cases. In particular, you could remove your outermost match and half the cases in your inner match.
In fact, your aux function (if correct) does all the work. If you look at it properly, you could just use aux for everything.
Since you're using List.rev, I assume you could also use List.map. That would be something to look at also.
Update
Trees are inherently recursive structures, so when looking for a tree algorithm, it often helps to imagine how you would use your algorithm recursively. In this case, you could ask yourself how you would put together mirror images of all the subtrees of a tree to make a mirror image of the whole tree.

Related

Two different types of OCaml recursive functions

During two weeks I've been doing some simple programs in OCaml. I've noticed that when we are working with a recursive structure T and we want to have the information I on T then depending on the information I we have two types of recursive function.
For simplicity let's assume T is a binary tree. So I'll use the following type :
type 'a tree = Empty | 'a * 'a tree * 'a tree
Now let's say the information I can be calculated from left to right on the binary tree. When I am saying left to right it means that the information I can be calculated from the root to the leaves without getting backward.
To be more clear let's say the information I we want to have is simply "the number of nodes of the binary tree". Then what's nice with this information is that when we get to all leaves then we get I, so we are going left to right in the sense that we begin from the root and expend recursively to the left and right subtree and the end case is when we arrived at the leaves.
So we simply have :
let rec nodes = function
|Empty -> 0 (*it's ok we are done here*)
|Node(_,l,r) -> 1 + nodes l + nodes r
What's very nice is that when the information can be calculated left to right then OCaml's pattern matching is a very strong tool and the information I can be calculated in an easy way.
So more generally we have :
let rec get_information = function
| Empty -> (*here we are done so we return a constant value*)
|Node(_,l,r)-> (*here we apply recusrively the function to the left and right tree*)
Now here comes my problem. Let's say I is an information that can't be calculated from left to right but from right to left. So it means that to get the information I we need to begin from the leaves of the tree and extend recursively to the top and we are done only when we get to the root of the binary tree (so the end case is when we get to the root of the binary tree and not the leaves).
For example, let's say the information I is : "the binary tree has the propriety that for every node the number of nodes in his left subtree is strictly superior to the number of nodes in his right subtree". If we want to solve this in linear time then we need to begin from the leaves and expend recursively to the top (note that I don't necessarily want a solution to the problem).
So to me, it's tricky to write a function that gets the information I when I is a right to left information (it needs to begin from the leaves and extend to the top). On the contrary pattern-matching is perfect when the information is a left to right information.
So my question is how to do when we need to write a function that gets the information I (when I is right to left)? Are there techniques to solve these kind of problems? Is it still possible to use pattern matching in a tricky way in order to get the desired result?
Pattern matching is useful for writing both kinds of function. Higher order functions called folds can also be used.
First, a concrete version. We will want to know whether a tree is left leaning, and if so, how many nodes it has. An int option will represent this nicely, with None indicating any non-left leaning tree.
type 'a tree = Empty | Branch of 'a * 'a tree * 'a tree
let rec tree_info = function
| Empty -> Some 0
| Branch (_, l, r) ->
match tree_info l, tree_info r with
| Some x, Some y when x >= y -> Some (x + y + 1)
| _ -> None
let is_left_leaning tree =
match tree_info tree with
| Some _ -> true
| None -> false
(Note that the condition x >= y is not 'strictly greater than', but this is deliberate; x > y is a poor choice. I'll leave figuring out why as an exercise.)
We can also express this style of function in terms of an operation called a right fold. For this operation one provides a value for each constructor of the datatype being folded over: in each place that constructor occurs, the fold operation will use that value to compute the result of the fold:
let rec foldr empty branch = function
| Empty -> empty
| Branch (x, l, r) ->
branch x (foldr empty branch l) (foldr empty branch r)
Note that the empty value and the Empty constructor have the same arity, and the branch value and the Branch constructor have the same arity, with corresponding argument types. That's characteristic of a right fold.
Given foldr, we can easily define map:
let map f tree =
foldr Empty (fun x l r -> Branch (f x, l, r)) tree
Or of course, 'tree_info':
let tree_info tree =
foldr
(Some 0)
(fun _ l r ->
match l, r with
| Some x, Some y when x >= y -> Some (x + y + 1)
| _ -> None)
tree
This is the alternative to pattern matching on the constructors of tree.

How do I create a function which reverses an int list in OCaml?

I have a type intlist:
type intlist = Nil | Cons of int * intlist
and I'd now like to write a function that reverses the list. I have no real idea how to go about this. in class, our prof defined a function within a function, I believe, but I don't have the solution with me. How would one do this, simply? I would appreciate if we can keep the coding rather rudimentary, seeing as I'm relatively new to this.
So far, I only have
let reverse (l : intlist) : intlist =
match l with
Nil -> Nil
| Cons(a, Nil) -> Cons(a, Nil)
This is how I tend to create these kinds of functions, so I've written the trivial part (which granted, may not actually be what I need to start with). Any help is appreciated, thanks!
You indeed need a helper function, since for the reversing you need to build another list, so you need a function that will recurse into one list, while building another list, i.e., that has two arguments. In fact, this helper function is called rev_append and it is appending a reversed contents of one list to another. But let's try to make it using a helper function defined in the scope of the rev function:
let rev xs =
let rec loop xs ys = match xs with
| Nil -> ys
| Cons (x,xs) -> loop xs (Cons (x,ys)) in
loop xs Nil
So, to reverse a list we just take each element of a list and put it into another list. Since list behaves like a stack we are getting the reversed list for free. It is like Hanoi towers, when you pick elements from one list (tower) and put them to another, they will end up in a reversed order.

F# tree-building function causes stack overflow in Xamarin Studio

I'm trying to build up some rules in a tree structure, with logic gates i.e. and, not, or as well as conditions, e.g. property x equals value y. I wrote the most obvious recursive function first, which worked. I then tried to write a version that wouldn't cause a stack-overflow in continuation passing style taking my cue from this post about generic tree folding and this answer on stackoverflow.
It works for small trees (depth of approximately 1000), but unfortunately when using a large tree it causes a stackoverflow when I run it on my Mac with Xamarin Studio. Can anyone tell me whether I've misunderstood how F# treats tail-recursive code or whether this code isn't tail-recursive?
The full sample is here.
let FoldTree andF orF notF leafV t data =
let rec Loop t cont =
match t with
| AndGate (left, right)->
Loop left (fun lacc ->
Loop right (fun racc ->
cont (andF lacc racc)))
| OrGate (left, right)->
Loop left (fun lacc ->
Loop right (fun racc ->
cont (orF lacc racc)))
| NotGate exp ->
Loop exp (fun acc -> cont (notF acc))
| EqualsExpression(property,value) -> cont (leafV (property,value))
Loop t id
let evaluateContinuationPassingStyle tree data =
FoldTree (&&) (||) (not) (fun (prop,value) -> data |> Map.find prop |> ((=) value)) tree data
The code is tail-recursive, you got it right. But the problem is with Mono. See, Mono is not as high-quality implementation of .NET as the official thing. In particular, it doesn't do tail call elimination. Like, at all.
For the simplest (and most prevalent) case of self-recursion this doesn't matter too much, because the compiler catches it earlier. The F# compiler is smart enough to spot that the function is calling itself, figure out under what conditions, and convert it into a neat while loop, so that the compiled code doesn't make any calls at all.
But when your tail call is to a function passed as parameter, the compiler can't do that, because the actual function being called isn't known until runtime. In fact, even mutual recursion of two functions can't be converted into a loop reliably.
Possible solutions:
Switch to .NET Core.
Don't use recursive continuations, use accumulator instead (might not be possible).
Use self-recursion and pass manually maintained stack of continuations.
If all else fails, use a mutable stack.

In-order traversal in BST-Ocaml

I'm working with a polymorphic binary search tree with the standard following type definition:
type tree =
Empty
| Node of int * tree * tree (*value, left sub tree, right sub tree*);;
I want to do an in order traversal of this tree and add the values to a list, let's say. I tried this:
let rec in_order tree =
match tree with
Empty -> []
| Node(v,l,r) -> let empty = [] in in_order r#empty;
v::empty;
in_order l#empty
;;
But it keeps returning an empty list every time. I don't see why it is doing that.
When you're working with recursion you need to always reason as follows:
How do I solve the easiest version of the problem?
Supposing I have a solution to an easier problem, how can I modify it to solve a harder problem?
You've done the first part correctly, but the second part is a mess.
Part of the problem is that you've not implemented the thing you said you want to implement. You said you want to do a traversal and add the values to a list. OK, so then the method should take a list somewhere -- the list you are adding to. But it doesn't. So let's suppose it does take such a parameter and see if that helps. Such a list is traditionally called an accumulator for reasons which will become obvious.
As always, get the signature right first:
let rec in_order tree accumulator =
OK, what's the easy solution? If the tree is empty then adding the tree contents to the accumulator is simply the identity:
match tree with
| Empty -> accumulator
Now, what's the recursive case? We suppose that we have a solution to some smaller problems. For instance, we have a solution to the problem of "add everything on one side to the accumulator with the value":
| Node (value, left, right) ->
let acc_with_right = in_order right accumulator in
let acc_with_value = value :: acc_with_right in
OK, we now have the accumulator with all the elements from one side added. We can then use that to add to it all the elements from the other side:
in_order left acc_with_value
And now we can make the whole thing implement the function you tried to write in the first place:
let in_order tree =
let rec aux tree accumulator =
match tree with
| Empty -> accumulator
| Node (value, left, right) ->
let acc_with_right = aux right accumulator in
let acc_with_value = value :: acc_with_right in
aux left acc_with_value in
aux tree []
And we're done.
Does that all make sense? You have to (1) actually implement the exact thing you say you're going to implement, (2) solve the base case, and (3) assume you can solve smaller problems and combine them into solutions to larger problems. That's the pattern you use for all recursive problem solving.
I think your problem boils down to this. The # operator returns a new list that is the concatenation of two other lists. It doesn't modify the other lists. In fact, nothing ever modifies a list in OCaml. Lists are immutable.
So, this expression:
r # empty
Has no effect on the value named empty. It will remain an empty list. In fact, the value empty can never be changed either. Variables in OCaml are also immutable.
You need to imagine constructing and returning your value without modifying lists or variables.
When you figure it out, it won't involve the ; operator. What this operator does is to evaluate two expressions (to the left and right), then return the value of the expression at the right. It doesn't combine values, it performs an action and discards its result. As such, it's not useful when working with lists. (It is used for imperative constructs, like printing values.)
If you thought about using # where you're now using ;, you'd be a lot closer to a solution.

How to create a Prolog predicate that removes 2nd to last element?

I need help creating a predicate that removes the 2nd to last element of a list and returns that list written in Prolog. So far I have
remove([],[]).
remove([X],[X]).
remove([X,Y],[Y]).
That is as far as I've gotten. I need to figure out a way to recursively go through the list until it is only two elements long and then reassemble the list to be returned. Help with explanation if you can.
Your definition so far is perfect! It is a little bit too specialized, so we will have to extend it. But your program is a solid foundation.
You "only" need to extend it.
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X,_,Y], [X,Y]).
remove([X,Y,_,Z], [X,Y,Z]).
remove([X,Y,Z,_,Z2], [X,Y,Z,Z2]).
...
OK, you see how to continue. Now, let us identify common cases:
...
remove([X,Y,_,Z], [X,Y,Z]).
% ^^^ ^^^
remove([X,Y,Z,_,Z2], [X,Y,Z,Z2]).
% ^^^^^ ^^^^^
...
So, we have a common list prefix. We could say:
Whenever we have a list and its removed list, we can conclude that by adding one element on both sides, we get a longer list of that kind.
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
Please note that the :- is really an arrow. It means: Provided what is true on the right-hand side, also what is found on the left-hand side will be true.
H-h-hold a minute! Is this really the case? How to test this? (If you test just for positive cases, you will always get a "yes".) We don't have the time to conjure up some test cases, do we? So let us let Prolog do the hard work for us! So, Prolog, fill in the blanks!
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
?- remove(Xs,Ys). % most general goal
Xs = [], Ys = []
; Xs = [A], Ys = [A]
; Xs = [_,A], Ys = [A]
; Xs = [A], Ys = [A] % redundant, but OK
; Xs = [A,B], Ys = [A,B], unexpected % WRONG
; Xs = [A,_,B], Ys = [A,B]
; Xs = [A,B], Ys = [A,B], unexpected % WRONG again!
; Xs = [A,B,C], Ys = [A,B,C], unexpected % WRONG
; Xs = [A,B,_,C], Ys = [A,B,C]
; ... .
It is tempting to reject everything and start again from scratch.
But in Prolog you can do better than that, so let's calm down to estimate the actual damage:
Some answers are incorrect. And some answers are correct.
It could be that our current definition is just a little bit too general.
To better understand the situation, I will look at the unexpected success remove([1,2],[1,2]) in detail. Who is the culprit for it?
Even the following program slice/fragment succeeds.
remove([],[]).
remove([X],[X]) :- false.
remove([_,X],[X]) :- false.
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
While this is a specialization of our program it reads: that remove/2 holds for all lists that are the same. That can't be true! To fix the problem we have to do something in the remaining visible part. And we have to specialize it. What is problematic here is that the recursive rule also holds for:
remove([1,2], [1,2]) :-
remove([2], [2]).
remove([2], [2]) :-
remove([], []).
That kind of conclusion must be avoided. We need to restrict the rule to those cases were the list has at least two further elements by adding another goal (=)/2.
remove([X|Xs], [Y|Ys]) :-
Xs = [_,_|_],
remove(Xs, Ys).
So what was our error? In the informal
Whenever we have a list and its removed list, ...
the term "removed list" was ambiguous. It could mean that we are referring here to the relation remove/2 (which is incorrect, because remove([],[]) holds, but still nothing is removed), or we are referring here to a list with an element removed. Such errors inevitably happen in programming since you want to keep your intuitions afresh by using a less formal language than Prolog itself.
For reference, here again (and for comparison with other definitions) is the final definition:
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X|Xs], [X|Ys]) :-
Xs = [_,_|_],
remove(Xs,Ys).
There are more efficient ways to do this, but this is the most straight-forward way.
I will try to provide another solution which is easier to construct if you only consider the meaning of "second last element", and describe each possible case explicitly:
rem_2nd_last([], []).
rem_2nd_last([First|Rest], R) :-
rem_2nd_last_2(Rest, First, R). % "Lag" the list once
rem_2nd_last_2([], First, [First]).
rem_2nd_last_2([Second|Rest], First, R) :-
rem_2nd_last_3(Rest, Second, First, R). % "Lag" the list twice
rem_2nd_last_3([], Last, _SecondLast, [Last]). % End of list: drop second last
rem_2nd_last_3([This|Rest], Prev, PrevPrev, [PrevPrev|R]) :-
rem_2nd_last_3(Rest, This, Prev, R). % Rest of list
The explanation is hiding in plain view in the definition of the three predicates.
"Lagging" is a way to reach back from the end of the list but keep the predicate always deterministic. You just grab one element and pass the rest of the list as the first argument of a helper predicate. One way, for example, to define last/2, is:
last([H|T], Last) :-
last_1(T, H, Last).
last_1([], Last, Last).
last_1([H|T], _, Last) :-
last_1(T, H, Last).

Resources