Skip to content

Instantly share code, notes, and snippets.

@cohama
Created April 14, 2013 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cohama/5382094 to your computer and use it in GitHub Desktop.
Save cohama/5382094 to your computer and use it in GitHub Desktop.
ocaml-expr
type expression =
| Const of float
| Var of string
| Sum of expression * expression
| Diff of expression * expression
| Prod of expression * expression
| Quot of expression * expression;;
exception Unbound_variable of string;;
let rec eval env exp =
match exp with
| Const c -> c
| Var v ->
(try
List.assoc v env
with
Not_found -> raise(Unbound_variable v))
| Sum(f, g) -> eval env f +. eval env g
| Diff(f, g) -> eval env f -. eval env g
| Prod(f, g) -> eval env f *. eval env g
| Quot(f, g) -> eval env f /. eval env g;;
(*
let ans = eval [("x", 1.0); ("y", 3.14)] (Prod(Sum(Var "x", Const 2.0), Var "y")) in
print_float ans
*)
let rec deriv exp dv =
match exp with
| Const _ -> Const 0.0
| Var v -> if v = dv then Const 1.0 else Const 0.0
| Sum(f, g) -> Sum(deriv f dv, deriv g dv)
| Diff(f, g) -> Diff(deriv f dv, deriv g dv)
| Prod(f, g) -> Sum(Prod(deriv f dv, g), Prod(f, deriv g dv))
| Quot(f, g) -> Quot(Diff(Prod(deriv f dv, g), Prod(f, deriv g dv)), Prod(g, g));;
(*
let ans = deriv (Quot(Const 1.0, Var "x")) "x"
*)
let print_expr exp =
(* Local function definitions *)
(* prec means precedence *)
let open_paren prec op_prec =
if prec > op_prec then "(" else "" in
let close_paren prec op_prec =
if prec > op_prec then ")" else "" in
let rec print prec exp =
match exp with
| Const c -> string_of_float c
| Var v -> v
| Sum(f, g) ->
(open_paren prec 0) ^
(print 0 f) ^ " + " ^ (print 0 g) ^
(close_paren prec 0)
| Diff(f, g) ->
(open_paren prec 0) ^
(print 0 f) ^ " - " ^ (print 1 g) ^
(close_paren prec 0)
| Prod(f, g) ->
(open_paren prec 2) ^
(print 2 f) ^ " * " ^ (print 2 g) ^
(close_paren prec 2)
| Quot(f, g) ->
(open_paren prec 2) ^
(print 2 f) ^ " / " ^ (print 3 g) ^
(close_paren prec 2)
in print 0 exp;;
let e = Sum(Prod(Const 2.0, Sum(Var "y", Var "x")), Const 1.0) in
print_string (print_expr e); print_newline ();
print_string (print_expr (deriv e "y")); print_newline ();;
(* output
2. * (y + x) + 1.
0. * (y + x) + 2. * (1. + 0.) + 0.
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment