open Expr let rec eval env = function | Const f -> f | SymConst Pi -> 4.0 *. atan 1.0 | SymConst E -> exp 1.0 | Var v -> (try List.assoc v env with Not_found -> failwith ("unbound variable: " ^ v)) | Add (e1, e2) -> eval env e1 +. eval env e2 | Sub (e1, e2) -> eval env e1 -. eval env e2 | Mul (e1, e2) -> eval env e1 *. eval env e2 | Div (e1, e2) -> eval env e1 /. eval env e2 | Pow (e1, e2) -> eval env e1 ** eval env e2 | Neg e -> -.(eval env e) | Sin e -> sin (eval env e) | Cos e -> cos (eval env e) | Tan e -> tan (eval env e) | Sinh e -> sinh (eval env e) | Cosh e -> cosh (eval env e) | Tanh e -> tanh (eval env e) | Asin e -> asin (eval env e) | Acos e -> acos (eval env e) | Atan e -> atan (eval env e) | Atan2 (e1, e2) -> atan2 (eval env e1) (eval env e2) | Exp e -> exp (eval env e) | Ln e -> log (eval env e) | Log (base_e, arg) -> let b = eval env base_e in let a = eval env arg in log a /. log b | Sqrt e -> sqrt (eval env e) | Abs e -> abs_float (eval env e)