symbolic mathematics engine in OCaml with differentiation, integration, simplification, and numerical methods
17

Configure Feed

Select the types of activity you want to include in your feed.

leibniz / lib / canonical.ml
5.0 kB 157 lines
1open Expr 2 3let rec compare_expr e1 e2 = 4 match (e1, e2) with 5 | Const a, Const b -> Float.compare a b 6 | Const _, _ -> -1 7 | _, Const _ -> 1 8 | SymConst a, SymConst b -> Stdlib.compare a b 9 | SymConst _, _ -> -1 10 | _, SymConst _ -> 1 11 | Var a, Var b -> String.compare a b 12 | Var _, _ -> -1 13 | _, Var _ -> 1 14 | Neg a, Neg b -> compare_expr a b 15 | Neg _, _ -> -1 16 | _, Neg _ -> 1 17 | Add (a1, a2), Add (b1, b2) -> 18 let c = compare_expr a1 b1 in 19 if c <> 0 then c else compare_expr a2 b2 20 | Add _, _ -> -1 21 | _, Add _ -> 1 22 | Sub (a1, a2), Sub (b1, b2) -> 23 let c = compare_expr a1 b1 in 24 if c <> 0 then c else compare_expr a2 b2 25 | Sub _, _ -> -1 26 | _, Sub _ -> 1 27 | Mul (a1, a2), Mul (b1, b2) -> 28 let c = compare_expr a1 b1 in 29 if c <> 0 then c else compare_expr a2 b2 30 | Mul _, _ -> -1 31 | _, Mul _ -> 1 32 | Div (a1, a2), Div (b1, b2) -> 33 let c = compare_expr a1 b1 in 34 if c <> 0 then c else compare_expr a2 b2 35 | Div _, _ -> -1 36 | _, Div _ -> 1 37 | Pow (a1, a2), Pow (b1, b2) -> 38 let c = compare_expr a1 b1 in 39 if c <> 0 then c else compare_expr a2 b2 40 | Pow _, _ -> -1 41 | _, Pow _ -> 1 42 | Sin a, Sin b -> compare_expr a b 43 | Sin _, _ -> -1 44 | _, Sin _ -> 1 45 | Cos a, Cos b -> compare_expr a b 46 | Cos _, _ -> -1 47 | _, Cos _ -> 1 48 | Tan a, Tan b -> compare_expr a b 49 | Tan _, _ -> -1 50 | _, Tan _ -> 1 51 | Sinh a, Sinh b -> compare_expr a b 52 | Sinh _, _ -> -1 53 | _, Sinh _ -> 1 54 | Cosh a, Cosh b -> compare_expr a b 55 | Cosh _, _ -> -1 56 | _, Cosh _ -> 1 57 | Tanh a, Tanh b -> compare_expr a b 58 | Tanh _, _ -> -1 59 | _, Tanh _ -> 1 60 | Asin a, Asin b -> compare_expr a b 61 | Asin _, _ -> -1 62 | _, Asin _ -> 1 63 | Acos a, Acos b -> compare_expr a b 64 | Acos _, _ -> -1 65 | _, Acos _ -> 1 66 | Atan a, Atan b -> compare_expr a b 67 | Atan _, _ -> -1 68 | _, Atan _ -> 1 69 | Atan2 (a1, a2), Atan2 (b1, b2) -> 70 let c = compare_expr a1 b1 in 71 if c <> 0 then c else compare_expr a2 b2 72 | Atan2 _, _ -> -1 73 | _, Atan2 _ -> 1 74 | Exp a, Exp b -> compare_expr a b 75 | Exp _, _ -> -1 76 | _, Exp _ -> 1 77 | Ln a, Ln b -> compare_expr a b 78 | Ln _, _ -> -1 79 | _, Ln _ -> 1 80 | Log (a1, a2), Log (b1, b2) -> 81 let c = compare_expr a1 b1 in 82 if c <> 0 then c else compare_expr a2 b2 83 | Log _, _ -> -1 84 | _, Log _ -> 1 85 | Sqrt a, Sqrt b -> compare_expr a b 86 | Sqrt _, _ -> -1 87 | _, Sqrt _ -> 1 88 | Abs a, Abs b -> compare_expr a b 89 90let rec canonicalize = function 91 | Const _ as c -> c 92 | SymConst _ as s -> s 93 | Var _ as v -> v 94 | Neg (Neg e) -> canonicalize e 95 | Neg e -> Neg (canonicalize e) 96 | Sub (e1, e2) -> canonicalize (Add (e1, Neg e2)) 97 | Div (e1, e2) -> canonicalize (Mul (e1, Pow (e2, Const (-.1.0)))) 98 | Add (e1, e2) -> 99 let c1 = canonicalize e1 in 100 let c2 = canonicalize e2 in 101 if compare_expr c1 c2 <= 0 then Add (c1, c2) else Add (c2, c1) 102 | Mul (e1, e2) -> 103 let c1 = canonicalize e1 in 104 let c2 = canonicalize e2 in 105 if compare_expr c1 c2 <= 0 then Mul (c1, c2) else Mul (c2, c1) 106 | Pow (e1, e2) -> Pow (canonicalize e1, canonicalize e2) 107 | Sin e -> Sin (canonicalize e) 108 | Cos e -> Cos (canonicalize e) 109 | Tan e -> Tan (canonicalize e) 110 | Sinh e -> Sinh (canonicalize e) 111 | Cosh e -> Cosh (canonicalize e) 112 | Tanh e -> Tanh (canonicalize e) 113 | Asin e -> Asin (canonicalize e) 114 | Acos e -> Acos (canonicalize e) 115 | Atan e -> Atan (canonicalize e) 116 | Atan2 (e1, e2) -> Atan2 (canonicalize e1, canonicalize e2) 117 | Exp e -> Exp (canonicalize e) 118 | Ln e -> Ln (canonicalize e) 119 | Log (e1, e2) -> Log (canonicalize e1, canonicalize e2) 120 | Sqrt e -> Sqrt (canonicalize e) 121 | Abs e -> Abs (canonicalize e) 122 123let equal e1 e2 = 124 let c1 = canonicalize e1 in 125 let c2 = canonicalize e2 in 126 compare_expr c1 c2 = 0 127 128let compare e1 e2 = 129 let c1 = canonicalize e1 in 130 let c2 = canonicalize e2 in 131 compare_expr c1 c2 132 133let rec hash = function 134 | Const f -> Hashtbl.hash ("Const", f) 135 | SymConst s -> Hashtbl.hash ("SymConst", s) 136 | Var v -> Hashtbl.hash ("Var", v) 137 | Add (e1, e2) -> Hashtbl.hash ("Add", hash e1, hash e2) 138 | Sub (e1, e2) -> Hashtbl.hash ("Sub", hash e1, hash e2) 139 | Mul (e1, e2) -> Hashtbl.hash ("Mul", hash e1, hash e2) 140 | Div (e1, e2) -> Hashtbl.hash ("Div", hash e1, hash e2) 141 | Pow (e1, e2) -> Hashtbl.hash ("Pow", hash e1, hash e2) 142 | Neg e -> Hashtbl.hash ("Neg", hash e) 143 | Sin e -> Hashtbl.hash ("Sin", hash e) 144 | Cos e -> Hashtbl.hash ("Cos", hash e) 145 | Tan e -> Hashtbl.hash ("Tan", hash e) 146 | Sinh e -> Hashtbl.hash ("Sinh", hash e) 147 | Cosh e -> Hashtbl.hash ("Cosh", hash e) 148 | Tanh e -> Hashtbl.hash ("Tanh", hash e) 149 | Asin e -> Hashtbl.hash ("Asin", hash e) 150 | Acos e -> Hashtbl.hash ("Acos", hash e) 151 | Atan e -> Hashtbl.hash ("Atan", hash e) 152 | Atan2 (e1, e2) -> Hashtbl.hash ("Atan2", hash e1, hash e2) 153 | Exp e -> Hashtbl.hash ("Exp", hash e) 154 | Ln e -> Hashtbl.hash ("Ln", hash e) 155 | Log (e1, e2) -> Hashtbl.hash ("Log", hash e1, hash e2) 156 | Sqrt e -> Hashtbl.hash ("Sqrt", hash e) 157 | Abs e -> Hashtbl.hash ("Abs", hash e)