Recursive function in OCaml - list

I have this portion of code that finds the next node in a graph using this format :
current node->(operator, cost, name of next node) list
:
let opPoss =(function
"A" -> [('h',4,"B");('b',10,"C")]
| "B" -> [('b',2,"C");('h',4,"D")]
| "C" -> [('b',6,"F")]
| "D" -> [('b',2,"C")]
and this one that finds the weight of each node:
let hEtat = (function
"A" -> 8
| "B" -> 3
| "C" -> 2
| "D" -> 5
| _ -> 0 );;
I have to implement a function that returns a list of next node for every node under this format:
(name of node, cost, weight)
, so I tried this:
let creerLesFils etat g opPoss hEtat=
let liste = opPoss etat in let rec creer liste g opPoss hEtat= match liste with
[]->[]
|(a, b, c)::t->(c, b, hEtat c)::creer t g opPoss hEtat;;
but it doesn't work, it shows me this:
;; Line 4, characters 45-47: Error: Syntax error
How can I properly implement the recursion?

Your syntax error is that you have let rec with no following in.
In essence, you define a local function named creer but you never use the definition for anything.
You might try adding something like this at the end of your code:
in
creer liste g opPoss hEtat
(This was difficult to answer because the code isn't formatted readably. You can use an automatic indentation tool, or indent manually.)

Related

Create a list with data extracted from a list of tuples - type issue

My data is ordered like this:
([(x1,y1,z1);(x2,y2,z2);(x3,y3,z3);........;(xn,yn,zn)], e:int)
Example: I try to create a list [x1;x2;x3;....;xn;e] where a value is found only once.
I began the following code but I encounter an issue with type.
let rec verifie_doublons_liste i liste = match liste with
| [] -> false
| head::tail -> i = head || verifie_doublons_liste i tail
let rec existence_doublon liste = match liste with
| [] -> false
| head::tail -> (verifie_doublons_liste head tail) ||
existence_doublon tail
let premier_du_triplet (x,y,z) = x
let deuxieme_du_triplet (x,y,z) = y
let troisieme_du_triplet (x,y,z) = z
let rec extract_donnees l = match l with
| [] -> []
| (x,y,z)::r -> (extract_donnees r)##(x::z::[])
let arrange donnees = match donnees with
| [],i -> i::[]
| (x,y,z)::[],i -> x::z::i::[]
| (x,y,z)::r,i -> (extract_donnees r)##(x::z::i::[])
Basically, you want to extract first elements in a list of tuples, and add the e elemnent at the end.
The easiest way is to use a List.map to extract the first elements
List.map premier_du_triplet
is a function that will take a list of 3-tuples and extract the first element of each.
then you can add the e element at the end using the "#" operator.
The more efficient and informative way would be to directly write a recursive function, say f that does just what you want.
When writing a recursive function, you need to ask yourself two things
what does it do in the simplest case (here, what does f [] do ?)
when you have a list in format head::tail, and you can already use f on the tail, what should you do to head and tail to obtain (f (head::tail)) ?
With this information, you should be able to write a recursive function that does what you want using pattern matching
here the simplest case is
| [] -> [e]
(you just add e at the end)
and the general case is
| h::t -> (premier_de_triplet h)::(f t)

F# : need help reversing order of ilist

I must use the following data type:
type ilist = E | L of int * ilist
I can't seem to find much help on working with lists outside of the standard type online ( [1;2;3] )
I am to write a function that takes a lists and reverses the order
for example: reverse (L(1, L(2, L(3, E)))) would output (L(3, L(2, L(1, E))))
So far here is my code:
let rec reverse l =
match l with
| E -> failwith "Empty List"
| L(h, E) -> h
| L(h, t) -> // append tail and recursive call with rest of list?
let list = reverse (L(1, L(2, L(3, E))))
printfn "reversed list: %A" list
Thanks for any help!
What you are lacking is a convenient way to append an int to an ilist:
let rec append x l =
match l with
| E -> L (x,E)
| L (h,t) -> L (h,append x t)
printfn "%A" (append 4 list)
Now use this function in your last match case to append h to the reversed t:
let rec reverse l =
match l with
| E -> E
| L (h,t) -> append h (reverse t)
Note that it's probably better to just return an empty list when the input list is empty (| E -> E), because failwith is something very ugly you should only use in the rarest cases.
Also note that your second match case | L(h, E) -> h is wrong, because it returns an int instead of an ilist. But it is not needed anyway, so just remove it. The singleton list L (h,E) will be matched with | L (h,t) -> ... instead, which in turn recursively matches t with | E -> E.
Here is a working example: https://repl.it/repls/PhonyAdventurousNet

convert tree to another tree with new format in Ocaml

I want to convert on tree to another tree with different type ,about 1 week i tried the different solution but i didn't successful, please help me.
my code is :
type (a',b') Tree = Lead of a'| Noeud of b'*a'*(a',b')Tree list
type strTree = st of int | Leaf of String | Tree of string *Strin* strTree list
val Tree-strTree :(a'->string)->(b'->string)->(a',b')Tree -> strTree
let Tree-strTree p pp a =
let rec mapA a' = match a' with
| Lead _ -> Tree ("","",[])
| Noeud (f,r,l)-> Tree(p f ,pp r ,fold_left(fun x y->x # [mapA y])[] l)
in
mapA a
Error: unbound value fold_left
I don't Know how i can use fold_left
There is a fold_left function in the List module. You just need to give the name of the module:
List.fold_left (fun x y -> ... )
However, as others have noted there are many other problems with your code, at least as you have shown it here.

Extracting data from a tuple in OCaml

I'm trying to use the CIL library to parse C source code. I'm searching for a particular function using its name.
let cil_func = Caml.List.find (fun g ->
match g with
| GFun(f,_) when (equal f.svar.vname func) -> true
| _ -> false
) cil_file.globals in
let body g = match g with GFun(f,_) -> f.sbody in
dumpBlock defaultCilPrinter stdout 1 (body cil_func)
So I have a type GFun of fundec * location, and I'm trying to get the sbody attribute of fundec.
It seems redundant to do a second pattern match, not to mention, the compiler complains that it's not exhaustive. Is there a better way of doing this?
You can define your own function that returns just the fundec:
let rec find_fundec fname = function
| [] -> raise Not_found
| GFun (f, _) :: _ when equal (f.svar.vname fname) -> f (* ? *)
| _ :: t -> find_fundec fname t
Then your code looks more like this:
let cil_fundec = find_fundec func cil_file.globals in
dumpBlock defaultCilPrinter stdout 1 cil_fundec.sbody
For what it's worth, the line marked (* ? *) looks wrong to me. I don't see why f.svar.vname would be a function. I'm just copying your code there.
Update
Fixed an error (one I often make), sorry.

OCaml: Can't figure out the error in this snippet

I am working on an OCaml assignment and am a bit stuck. Currently this is what I have:
let rec icent (image) =
match image with
| [] -> 0.0
| imgHead::imgTail -> (centImCol(image, 1)) +. (icent(imgHead))
;;
let rec jcent (image) =
match image with
| [] -> 0.0
| imgHead::imgTail -> (centImRow(imgHead, 1)) +. (jcent(imgTail))
;;
where the centIm* functions are properly defined. The required signature for this is int list list -> float. Currently, I am only achieving error after error and can't quite get a grasp on why. Any help would be appreciated.
let rec centImRow(image, start_j) =
match image with
| imgHead::imgTail -> (sumRowCount(imgHead, start_j)) + (centImRow(imgTail, start_j+1))
| _ -> 0
;;
let rec centImCol(image, start_i) =
match image with
| imgHead::imgTail -> (sumRowCount(imgHead, start_i)) + (centImCol(imgTail, start_i+1))
| _ -> 0
;;
The first problem I see is that your recursive call to icent is applied to the head of the list. But the head of a list is not a list. But icent is supposed to work for lists.
The recursive call of a list handling function is going to be applied to the tail of the list.
I'd also expect some function to be applied to the head of the list. Otherwise nothing is going on other than the recursion itself.