I'm making differentiating function in OCaml and I have some problems - list

first, this is my code :
module Problem1 = struct
type aexp =
| Const of int
| Var of string
| Power of string * int
| Times of aexp list
| Sum of aexp list
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
end
The interpretor says,
Error: This variant pattern is expected to have type aexp list
The constructor Sum does not belong to type list
But I intended the symbol m to be an aexp list.
Can't find what is wrong.

Actually your problem is simple and you would have seen it by using a tool that knows how to indent OCaml code ;-)
Look at how your last lines are indented with an OCaml indenter :
|Times l ->
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
Yes, that's right, since you created a new pattern matching in Times l, Sum m is included in it. You should write
|Times l -> begin
match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)];;
And it will work just fine.
By the way, you'll have another problem because you didn't write let rec diff ... but let diff and you're calling diff recursively.

To me, this part looks off: Times[diff (h, var);t]. Since t is an aexp list, you should use the other list constructor, ::, to make it `Times (diff (h, var) :: t).

If you put match .. with .. inside a case of another match .. with, you need wrap the internal one with begin .. end:
(* I do not check the code is correct *)
let diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times[Const i;Power (s, i - 1)] else Power (s, i)
|Times l ->
begin match l with
|h::t -> Sum[Times[diff (h, var);t];diff (t, var)]
end
|Sum m ->
match m with
|h::t -> Sum[diff(h, var); diff(t, var)]
Please install a proper auto-indentation tool such as tuareg or ocp-indent, since they can tell the proper program structure. Hand indentation often fools your eyes.

Related

This expression has type 'a list -> 'a list but an expression was expected of type int

let rec first_part n l =
if n = 0 then
[]
else
match l with
| [] -> []
| x :: xs -> x :: first_part n-1 xs
let rec second_part n l =
match l with
| [] -> []
| x :: xs ->
if n = 0 then l
else second_part n-1 xs
let rec split n l =
match n with
| 0-> ([], l)
| n -> (first_part n l , second_part n l)
This isn't a very well posed question. You don't show the details of the error or ask a specific question. You also didn't format the code in a readable way (I improved it for you).
Your problem is that
first_part n-1 xs
is parsed like this
(first_part n) - (1 xs)
Function calls in OCaml (juxtaposed expressions) have high precedence. So you need parentheses around (n - 1) in two places.

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

how to implement lambda-calculus in OCaml?

In OCaml, it seems that "fun" is the binding operator to me. Does OCaml have built-in substitution? If does, how it is implemented? is it implemented using de Bruijn index?
Just want to know how the untyped lambda-calculus can be implemented in OCaml but did not find such implementation.
As Bromind, I also don't exactly understand what you mean by saying "Does OCaml have built-in substitution?"
About lambda-calculus once again I'm not really understand but, if you talking about writing some sort of lambda-calculus interpreter then you need first define your "syntax":
(* Bruijn index *)
type index = int
type term =
| Var of index
| Lam of term
| App of term * term
So (λx.x) y will be (λ 0) 1 and in our syntax App(Lam (Var 0), Var 1).
And now you need to implement your reduction, substitution and so on. For example you may have something like this:
(* identity substitution: 0 1 2 3 ... *)
let id i = Var i
(* particular case of lift substitution: 1 2 3 4 ... *)
let lift_one i = Var (i + 1)
(* cons substitution: t σ(0) σ(1) σ(2) ... *)
let cons (sigma: index -> term) t = function
| 0 -> t
| x -> sigma (x - 1)
(* by definition of substitution:
1) x[σ] = σ(x)
2) (λ t)[σ] = λ(t[cons(0, (σ; lift_one))])
where (σ1; σ2)(x) = (σ1(x))[σ2]
3) (t1 t2)[σ] = t1[σ] t2[σ]
*)
let rec apply_subs (sigma: index -> term) = function
| Var i -> sigma i
| Lam t -> Lam (apply_subs (function
| 0 -> Var 0
| i -> apply_subs lift_one (sigma (i - 1))
) t)
| App (t1, t2) -> App (apply_subs sigma t1, apply_subs sigma t2)
As you can see OCaml code is just direct rewriting of definition.
And now small-step reduction:
let is_value = function
| Lam _ | Var _ -> true
| _ -> false
let rec small_step = function
| App (Lam t, v) when is_value v ->
apply_subs (cons id v) t
| App (t, u) when is_value t ->
App (t, small_step u)
| App (t, u) ->
App (small_step t, u)
| t when is_value t ->
t
| _ -> failwith "You will never see me"
let rec eval = function
| t when is_value t -> t
| t -> let t' = small_step t in
if t' = t then t
else eval t'
For example you can evaluate (λx.x) y:
eval (App(Lam (Var 0), Var 1))
- : term = Var 1
OCaml does not perform normal-order reduction and uses call-by-value semantics. Some terms of lambda calculus have a normal form than cannot be reached with this evaluation strategy.
See The Substitution Model of Evaluation, as well as How would you implement a beta-reduction function in F#?.
I don't exactly understand what you mean by saying "Does OCaml have built-in substitution? ...", but concerning how the lambda-calculus can be implemented in OCaml, you can indeed use fun : just replace all the lambdas by fun, e.g.:
for the church numerals: you know that zero = \f -> (\x -> x), one = \f -> (\x -> f x), so in Ocaml, you'd have
let zero = fun f -> (fun x -> x)
let succ = fun n -> (fun f -> (fun x -> f (n f x)))
and succ zero gives you one as you expect it, i.e. fun f -> (fun x -> f x) (to highlight it, you can for instance try (succ zero) (fun s -> "s" ^ s) ("0") or (succ zero) (fun s -> s + 1) (0)).
As far as I remember, you can play with let and fun to change the evaluation strategy, but to be confirmed...
N.B.: I put all parenthesis just to make it clear, maybe some can be removed.

I'm in trouble with making a differentiating function in OCaml (not about syntax issue)

type aexp =
| Const of int
| Var of string
| Power of string * int
| Times of aexp list
| Sum of aexp list
let rec diff : aexp * string -> aexp
= fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) ->
if s = var then Times [Const i; Power (s, i - 1)] else Power (s, i)
|Times l ->
begin match l with
|h::t -> Sum ((Times (diff (h, var) :: t)) # (h :: Times (diff (Times t, var))))
end
|Sum l ->
begin match l with
|h::t -> Sum (diff(h, var) :: diff(t, var))
end
This code is expected to work as follows :
diff (Times[Const 2; Var "x"], "x")
then the output must be
Times[Const 2; Const 1]
because if we differentiate 2x, the result is 2
but the error occurs and it says :
File "", line 18, characters 20-25:
Error: This variant expression is expected to have type 'a list
The constructor Times does not belong to type list
Why this error happens? I think there are some spots that are wrong, but I can't find any logical incorrectness.
Some mathematical notes:
The derivative of a variable not x by a variable x is zero, not the original variable.
The same for a power of a variable not x, it is also a constant relative to x.
Why only powers of variables, (a+b)^i is not possible. The more general case is as easy as the special case.
For the derivative of the product consider three factors and include that the first recursive step splits u and v*w
(u*v*w)' = u'*v*w + u*(v'*w+v*w')
In a prefix notation this can be written as
diff(*[u,v,w])=+[*[u',v,w],*[u,+[*[v',w],*[v,w']]]]
which should be reflected in something like
|h::t -> Sum ((Times (diff (h, var) :: t)) # (Times (h :: (diff (Times t, var)))))
As two-element lists, could this also be written as
|h::t -> Sum ( Times (diff (h, var) :: t) , Times (h ,diff (Times t, var)))
Let's look at this expression:
h :: Times (diff (Times t, var))
for simplicity let's substitute diff (Times t, var), with the dtdv, so that we have
h :: Times dtdv
The :: infix constructor requires that an expression to the left of its should have type 'a, while an expression to the right should have a value of type 'a list. An expression to the right is Times dtdv, and constructor Times creates values of type aexp, not values of type list.
Btw, you also have two more errors and two more warnings. These errors are of the same kind, i.e., you're trying to apply a value of type aexp in a place where a list is required, i.e., here:
Times (diff (h, var) :: t)) # (h :: Times (diff (Times t, var))
Let's simplify it again
Times (dhv::t) # rest
The # operator expects lists on both sides, and Times something, as we already discussed, are not a list.
It looks like, that it is hard for you to pass through the big amount of parenthesis and precedence rules. I hate parenthesis. So, I always try to use let ... in sparingly, e.g., let's rewrite the following expression:
Sum ((Times (diff (h, var) :: t)) # (h :: Times (diff (Times t, var))))
With a more verbose, but understanble version:
let h' = diff (h,var) in
let t' = diff (Times t,var) in
let lhs = Times (h'::t) in
let rhs = h :: Times t' in
Sum (lhs#rhs)
Now it is much more readable, and you can tackle with all problems one by one.
Also, I'm would suggest not to try to solve everything in a big fat function, but instead separate things into smaller functions that are easier to handle, this will also solve you a problem with the match inside a match, e.g., the following function has a structure that is much easier to understand:
let rec diff : aexp * string -> aexp = fun (exp, var) ->
match exp with
|Const a -> Const 0
|Var x -> if x = var then Const 1 else Var x
|Power (s, i) -> diff_power s i
|Times l -> diff_times l
|Sum l -> diff_sum l
and diff_power s i =
if s = var then Times [Const i; Power (s, i - 1)] else Power (s, i)
and diff_times l = match l with
|h::t -> Sum ((Times (diff (h, var) :: t)) # (h :: Times (diff (Times t, var))))
and diff_sum l = match l with
|h::t -> Sum (diff(h, var) :: diff(t, var))

Ocaml type error confusion: why is this making an error?

let rec add_tail l e = match l with
| [] -> [e]
| (h::t) -> h::(add_tail t e)
let rec fill_help l x n = match n = 0 with
true -> l
| false -> add_tail(l, x); fill_help(l, x, n-1)
let fill x n =
let l = [] in
fill_help(l, x, n)
and I'm getting the error in the interpreter
# #use "prac.ml";;
val prod : int list -> int = <fun>
val add_tail : 'a list -> 'a -> 'a list = <fun>
File "prac.ml", line 13, characters 21-27:
Error: This expression has type 'a * 'b
but an expression was expected of type 'c list
line 13 would be
| false -> add_tail(l, x); fill_help(l, x, n-1)
First of all you call fill_help with a tuple as an argument ((l, x, n-1)) even though it's not defined to take one. You should call fill_help as fill_help l x (n-1) instead. Same for add_tail.
Secondly you call a side-effect-free function (add_tail) and throw away its return value. This is almost always an error. It looks like you expect l to be different after the call to add_tail. It won't be. You probably want fill_help (add_tail l x) x (n-1).