| datatype expr = | |
| Val of int | |
| | Var of string | |
| | Add of expr * expr | |
| | Mul of expr * expr | |
| | Pow of expr * expr | |
| | Ln of expr;; | |
| fun pown a n = | |
| if n = 0 then 1 | |
| else if n = 1 then a | |
| else let val b = pown a (n div 2) in | |
| b * b * (if n mod 2 = 0 then 1 else a) end;; | |
| fun add n m = | |
| case (n, m) of | |
| (Val n, Val m) => Val (n+m) | |
| | (Val 0, f) => f | |
| | (f, Val 0) => f | |
| | (f, Val n) => add (Val n) f | |
| | (Val n, Add(Val m, f)) => add (Val (n+m)) f | |
| | (f, Add(Val n, g)) => add (Val n) (add f g) | |
| | (Add(f, g), h) => add f (add g h) | |
| | (f, g) => Add (f, g);; | |
| fun mul n m = | |
| case (n, m) of | |
| (Val n, Val m) => Val (n*m) | |
| | (Val 0, _) => Val 0 | |
| | (_, Val 0) => Val 0 | |
| | (Val 1, f) => f | |
| | (f, Val 1) => f | |
| | (f, Val n) => mul (Val n) f | |
| | (Val n, Mul (Val m, f)) => mul (Val (n*m)) f | |
| | (f, Mul (Val n, g)) => mul (Val n) (mul f g) | |
| | (Mul (f, g), h) => mul f (mul g h) | |
| | (f, g) => Mul (f, g);; | |
| fun pow m n = | |
| case (m, n) of | |
| (Val m, Val n) => Val (pown m n) | |
| | (_, Val 0) => Val 1 | |
| | (f, Val 1) => f | |
| | (Val 0, _) => Val 0 | |
| | (f, g) => Pow (f, g);; | |
| fun ln n = | |
| case n of | |
| (Val 1) => Val 0 | |
| | f => Ln f;; | |
| fun d x f = | |
| case f of | |
| Val _ => Val 0 | |
| | Var y => if x = y then Val 1 else Val 0 | |
| | Add (f, g) => add (d x f) (d x g) | |
| | Mul (f, g) => add (mul f (d x g)) (mul g (d x f)) | |
| | Pow (f, g) => mul (pow f g) (add (mul (mul g (d x f)) (pow f (Val (~1)))) (mul (ln f) (d x g))) | |
| | Ln f => mul (d x f) (pow f (Val (~1)));; | |
| fun count f = | |
| case f of | |
| Val _ => 1 | |
| | Var _ => 1 | |
| | Add (f, g) => count f + count g | |
| | Mul (f, g) => count f + count g | |
| | Pow (f, g) => count f + count g | |
| | Ln f => count f;; | |
| fun nest_aux s f n x = | |
| if n = 0 then x | |
| else let val x = f (s - n) x in | |
| nest_aux s f (n - 1) x end;; | |
| fun nest f n e = | |
| nest_aux n f n e;; | |
| fun deriv i f = | |
| let | |
| val d = d "x" f | |
| val _ = print (Int.toString (i + 1) ^ " count: " ^ Int.toString (count d) ^ "\n") in | |
| d | |
| end | |
| val x = Var "x" | |
| val f = pow x x | |
| val _ = nest deriv 10 f |