Created
April 14, 2013 09:32
-
-
Save cohama/5382094 to your computer and use it in GitHub Desktop.
ocaml-expr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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