Understanding the semantics behind the code - ocaml

I have an OCaml code, and I have a hard time to formalize the function mi_pol into Coq because I am not understand clearly what exactly this code working, for example at the
aux (vec_add add const (vector ci v)) args ps
and
args.(i-1) <- mat_add add args.(i-1) (matrix ci m); aux const args ps
and
aux (vec_0 z dim) (Array.make n (mat_0 z dim)) ps
This is the code:
let vector = List.map;;
let clist x =
let rec aux k = if k <= 0 then [] else x :: aux (k-1) in aux;;
let vec_add add v1 v2 =
try List.map2 add v1 v2
with Invalid_argument _ ->
error_fmt "sum of two vectors of different size";;
let mat_add add m1 m2 =
try List.map2 (vec_add add) m1 m2
with Invalid_argument _ ->
error_fmt "sum of two matrices of different size";;
(*vector zero *)
let vec_0 z dim = clist z dim;;
(* matrix zero *)
let mat_0 z dim = clist (vec_0 z dim) dim;;
let comp f g x = f (g x);;
(* matrix transpose *)
let transpose ci =
let rec aux = function
| [] | [] :: _ -> []
| cs -> List.map (comp ci List.hd) cs :: aux (List.map List.tl cs)
in aux;;
(* matrix *)
let matrix ci m =
try transpose ci m
with Failure _ -> error_fmt "ill-formed matrix";;
let mi_pol z add ci =
let rec aux const args = function
| [] -> { mi_const = const; mi_args = Array.to_list args }
| Polynomial_sum qs :: ps -> aux const args (qs # ps)
| Polynomial_coefficient (Coefficient_matrix [v]) :: ps
| Polynomial_coefficient (Coefficient_vector v) :: ps ->
aux (vec_add add const (vector ci v)) args ps
| Polynomial_product [p] :: ps -> aux const args (p :: ps)
| Polynomial_product [Polynomial_coefficient (Coefficient_matrix m);
Polynomial_variable i] :: ps ->
args.(i-1) <- mat_add add args.(i-1) (matrix ci m);
aux const args ps
| _ -> not_supported "todo"
in fun dim n -> function
| Polynomial_sum ps -> aux (vec_0 z dim) (Array.make n (mat_0 z dim)) ps
| _ -> not_supported
"todo";;
Any help is very appreciate. If you can have a Coq code for mi_pol it will help me a lot.

It appears to take a polynomial on a vector space, and compute the sum of all the (transpose of) (matrix) coefficients attached to each variable. args is an array such that args.(i) is the sum of all coefficients on the i-th variable, and const the sum of constant scalars.
I don't know what's the meaning of this operation, but I suspect it doesn't mean much in the general case (working over arbitrary products of sums of products of ...; that would lead to strange non-linear/homogeneous behaviors). I suppose there are implicit constraints on what the shape of actual values of this polynomial type are, for example it may be linear in all variables.

Related

Different ways of declaring a function

When declaring a function, I've 3 different ways:
let f x = ...
let f = (fun x -> ...)
let f = function
| ... -> (pattern matching)
It's this last one that I don't fully understand how it works.
I was doing a function that, considering a list (we'll assume it has integers in it but could be anything), reverses it, pretty basic, but with a complexity of O(n). After struggling for an hour at least I check the answer, and it is written like this:
let reverse lst =
let rec aux acc = function
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
I thought that using the key word function was just another way of doing patter matching, but when I do this:
let reverse lst =
let rec aux acc =
match aux with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
It doesn't work, and idk why. On top of that, why can we add tl at the end of the first function? Isn't aux a single argument function?
There are a few problems with this question. First, the code you give as the solution for reverse is not valid OCaml. It matches aux (which is a function) against list patterns. Most likely aux was supposed to be acc. But even so it doesn't seem right because it should have two arguments (the accumulated result and the input that still needs to be processed).
Second, your two code examples are the same. You seem to be saying that one works and one doesn't work. That doesn't make sense since they're the same.
IMHO you need to rewrite the question if you want to get a helpful answer.
Ocaml uses currying, which means that a two-argument function is the same thing that a function whose return value is a function.
To define a two-argument function, you can combine all the ways you know of creating one-argument functions:
let f x y = x + y
let f x = (fun y -> x + y)
let f x = function
| y -> x + y
let f = (fun x -> (fun y -> x + y))
let f = function
| x -> function
| y -> x + y
let f x = (let g y = x + y in g)
etc, etc.
All these definitions for f lead to the same result:
val f : int -> int -> int = <fun>
# f 3 4;;
- : int = 7
Note that the signature of f is:
val f : int -> int -> int = <fun>
If we added parentheses to better understand this signature, it would be this:
val f : int -> (int -> int) = <fun>
Meaning that f is a one-argument function whose return value is a one-argument function whose return value is an int.
Indeed, if we partially apply f:
# f 3;;
- : int -> int = <fun>
# let add_three = f 3;;
val add_three : int -> int = <fun>
# add_three 4;;
- : int = 7
The code you give at the end of your question is wrong. It's most likely intended to be this:
let reverse lst =
let rec aux acc l =
match l with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst;;
val reverse : 'a list -> 'a list = <fun>
# reverse [1;2;3;4;5];;
- : int list = [5; 4; 3; 2; 1]

Combining two functions in OCaml

My task is to remove the duplicates from a list. To do that I have to first sort the list.
I have written the function that sorts the list and the one that remove the
duplicates(once they are sorted) but I don't know how to combine them.
Example:
input: [4;5;2;2;1;3;3]
output: [1;2;3;4;5]
let rec setify = function
| [] -> []
| x :: l -> insert x (setify l)
and insert elem = function
| [] -> [elem]
| x :: l -> if elem < x then elem :: x :: l
else x :: insert elem l;;
let rec rem =function
|[] -> []
| x :: []-> x :: []
| x :: y :: rest -> if x = y then rem (y :: rest)
else x :: rem (y :: rest) ;;
You want to make the function that takes a list, creates the sorted list, and deduplicates that. In other words, you want:
let task list =
let sorted_list = setify list in
rem sorted_list
It is possible to do this in arbitrarily more complicated ways, but the above is one straightforward, one-action-per-line version. Since the phrasing of the title of your question invites it, here is one of the more sophisticated ways:
(* it's possible to write a generic combinator of functions, that takes two functions f and g *)
let combine f g =
(* and returns a function *)
fun x ->
(* that maps x to f(g(x)) *)
f (g x)
(* this function is typed as:
val combine : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
*)
(* the task can then be expressed as the combination of setify and rem: *)
let task = combine rem setify
Don't use this style unless something is actually gained from it. Most of
the times it only makes programs less readable and slower with no corresponding benefit. *)

Using FOIL in SML

I'm writing a small program that takes coefficients of two polynomials and FOILs them together, however I can only seem to multiply elements at the same indices.
fun polyMult([],[]) = []
| polyMult(M, []) = []
| polyMult([], N) = []
| polyMult(M as x::xs, N as y::ys) =
(x * y) :: polyMult(M, ys);
I can successfully multiply the first element of M by every element of N, but then afterwards I want to be able to advance one element in M and then take that and multiply it by every element in N.
Is there any way I can advance the index in M and repeat the multiplication process? I.E
polyMult(tl(M) as x::xs, N as y::ys) =
(x * y) :: polyMult(M, ys);
Something along these lines
fun foldL F y nil = y
| foldL F y (x::xr) = foldL F (F(x,y)) xr;
fun polymult(M, nil) = nil
| polymult(nil, N) = nil
| polymult(m::mr, N) = foldL(fn(x,a) => x * a) m N::polymult(mr,N);
But you will need to figure out how to make it only accept real numbers and not integers as it does now ;)

Rotate list in OCaml

I want to write a function rotate n l that returns a new list containing the same elements as l, "rotated" n times to the right. For example,
rotate 0 [1;2;3;4] should return [1;2;3;4]
rotate 1 [1;2;3;4] should return [4;1;2;3]
rotate 2 [1;2;3;4] should return [3;4;1;2]
rotate 3 [1;2;3;4] should return [2;3;4;1]
rotate 4 [1;2;3;4] should return [1;2;3;4]
etc.
The behavior of rotate n for n less than 0 should be the same as for n equal to 0.
I want to write this without using the list concatenation operator # from Pervasives.
Update: Here is the rotation function I wrote:
let rot1 l =
let rec iterate acc = function
[] -> []
| [x] -> x :: List.rev acc
| x :: l -> iterate (x :: acc) l
in
iterate [] l;;
But I want it to do the same thing without using List.rev.
Is there a way to do this?
Agree with Jeffrey, show us what you tried. Here's a small hint in case you need to get started. If you can write a function that performs only 1 rotation i.e. equivalent to rotate 1 l. (I call it one_rot). Then rotate can be easily defined as:
let rec rotate n l =
match n with
| 0 -> l
| _ -> rotate (n-1) (one_rot l)
Your solution is perfectly fine for me. Not sure what you have against List.rev but here's a completely stand alone one_rot. Note that we have to sacrifice tail recursion. You could probably make this quite a bit shorter too:
let rec last = function
| [] -> assert false
| [x] -> x
| x::xs -> last xs
let rec init = function
| [] -> []
| [x] -> []
| x::xs -> x::(init xs)
let one_rot l = (last l)::(init l)
This problem can be solved by combining these 3 functions:
cat(skip(list, places), take(list, places))
The implementation looks like:
let rec cat = function
([], y) -> y
| (x::xs, y) -> x :: cat (xs, y)
let rec skip = function
([], _) -> []
| (_::xs as xs1, c) -> if c > 0 then skip(xs, c - 1) else xs1
let rec take = function
([], _) -> []
| (x::xs, c) -> if c > 0 then x :: take(xs, c - 1) else []
let cycle l i =
cat (skip (l, i), take (l, i))
cycle ([1;2;3;4;5;6], 3);;
val it : int list = [4; 5; 6; 1; 2; 3]

Haskell reading matrix from a list in file and use it

I need to get a Matrix from a list in file. Example:
file.txt:
[1,2,3,4,5,6,7,8,9]
I want to read it in this form: [[1,2,3],[4,5,6],[7,8,9]].
Moreover, I need to manipulate it in another function like:
func m x y = do{ printMatrix m;
return $ m !! x !! y;
}
Is it possible?
There is the rather naive way of using nested lists for your matrix. If your input is already in this Haskellish form, you can also use the function read to parse the input. For example:
type Matrix a = [[a]]
readMatrix :: FilePath -> IO (Matrix a)
readMatrix path = f <- getFile path
return $ read f
elemAt :: Int -> Int -> Matrix a -> a
elemAt x y m = m !! x !! y
-- and so on
a solution could be:
l2m ::(Eq a) ⇒ Int → [a] → [[a]]
l2m rsize as
| rsize ≡ 0 = []
| as ≡ [] = []
| otherwise = [(take rsize as)] ++ l2m rsize (drop rsize as)
aij :: (Eq a) ⇒ Int → Int → [[a]] → a
aij i j as = (as !! (i - 1)) !! (j - 1)
to use this function you will have to get your input to a (Eq a) => [a].
hope this helps ε/2