|
1 signature EXP_LOG_EXPRESSION = sig |
|
2 |
|
3 exception DUP |
|
4 |
|
5 datatype expr = |
|
6 ConstExpr of term |
|
7 | X |
|
8 | Uminus of expr |
|
9 | Add of expr * expr |
|
10 | Minus of expr * expr |
|
11 | Inverse of expr |
|
12 | Mult of expr * expr |
|
13 | Div of expr * expr |
|
14 | Ln of expr |
|
15 | Exp of expr |
|
16 | Power of expr * term |
|
17 | LnPowr of expr * expr |
|
18 | ExpLn of expr |
|
19 | Powr of expr * expr |
|
20 | Powr_Nat of expr * expr |
|
21 | Powr' of expr * term |
|
22 | Root of expr * term |
|
23 | Absolute of expr |
|
24 | Sgn of expr |
|
25 | Min of expr * expr |
|
26 | Max of expr * expr |
|
27 | Floor of expr |
|
28 | Ceiling of expr |
|
29 | Frac of expr |
|
30 | NatMod of expr * expr |
|
31 | Sin of expr |
|
32 | Cos of expr |
|
33 | ArcTan of expr |
|
34 | Custom of string * term * expr list |
|
35 |
|
36 val preproc_term_conv : Proof.context -> conv |
|
37 val expr_to_term : expr -> term |
|
38 val reify : Proof.context -> term -> expr * thm |
|
39 val reify_simple : Proof.context -> term -> expr * thm |
|
40 |
|
41 type custom_handler = |
|
42 Lazy_Eval.eval_ctxt -> term -> thm list * Asymptotic_Basis.basis -> thm * Asymptotic_Basis.basis |
|
43 |
|
44 val register_custom : |
|
45 binding -> term -> custom_handler -> local_theory -> local_theory |
|
46 val register_custom_from_thm : |
|
47 binding -> thm -> custom_handler -> local_theory -> local_theory |
|
48 val expand_custom : Proof.context -> string -> custom_handler option |
|
49 |
|
50 val to_mathematica : expr -> string |
|
51 val to_maple : expr -> string |
|
52 val to_maxima : expr -> string |
|
53 val to_sympy : expr -> string |
|
54 val to_sage : expr -> string |
|
55 |
|
56 val reify_mathematica : Proof.context -> term -> string |
|
57 val reify_maple : Proof.context -> term -> string |
|
58 val reify_maxima : Proof.context -> term -> string |
|
59 val reify_sympy : Proof.context -> term -> string |
|
60 val reify_sage : Proof.context -> term -> string |
|
61 |
|
62 val limit_mathematica : string -> string |
|
63 val limit_maple : string -> string |
|
64 val limit_maxima : string -> string |
|
65 val limit_sympy : string -> string |
|
66 val limit_sage : string -> string |
|
67 |
|
68 end |
|
69 |
|
70 structure Exp_Log_Expression : EXP_LOG_EXPRESSION = struct |
|
71 |
|
72 |
|
73 datatype expr = |
|
74 ConstExpr of term |
|
75 | X |
|
76 | Uminus of expr |
|
77 | Add of expr * expr |
|
78 | Minus of expr * expr |
|
79 | Inverse of expr |
|
80 | Mult of expr * expr |
|
81 | Div of expr * expr |
|
82 | Ln of expr |
|
83 | Exp of expr |
|
84 | Power of expr * term |
|
85 | LnPowr of expr * expr |
|
86 | ExpLn of expr |
|
87 | Powr of expr * expr |
|
88 | Powr_Nat of expr * expr |
|
89 | Powr' of expr * term |
|
90 | Root of expr * term |
|
91 | Absolute of expr |
|
92 | Sgn of expr |
|
93 | Min of expr * expr |
|
94 | Max of expr * expr |
|
95 | Floor of expr |
|
96 | Ceiling of expr |
|
97 | Frac of expr |
|
98 | NatMod of expr * expr |
|
99 | Sin of expr |
|
100 | Cos of expr |
|
101 | ArcTan of expr |
|
102 | Custom of string * term * expr list |
|
103 |
|
104 type custom_handler = |
|
105 Lazy_Eval.eval_ctxt -> term -> thm list * Asymptotic_Basis.basis -> thm * Asymptotic_Basis.basis |
|
106 |
|
107 type entry = { |
|
108 name : string, |
|
109 pat : term, |
|
110 net_pat : term, |
|
111 expand : custom_handler |
|
112 } |
|
113 |
|
114 type entry' = { |
|
115 pat : term, |
|
116 net_pat : term, |
|
117 expand : custom_handler |
|
118 } |
|
119 |
|
120 exception DUP |
|
121 |
|
122 structure Custom_Funs = Generic_Data |
|
123 ( |
|
124 type T = { |
|
125 name_table : entry' Name_Space.table, |
|
126 net : entry Item_Net.T |
|
127 } |
|
128 fun eq_entry ({name = name1, ...}, {name = name2, ...}) = (name1 = name2) |
|
129 val empty = |
|
130 { |
|
131 name_table = Name_Space.empty_table "Exp-Log Custom Function", |
|
132 net = Item_Net.init eq_entry (fn {net_pat, ...} => [net_pat]) |
|
133 } |
|
134 |
|
135 fun merge ({name_table = tbl1, net = net1}, {name_table = tbl2, net = net2}) = |
|
136 {name_table = Name_Space.join_tables (fn _ => raise DUP) (tbl1, tbl2), |
|
137 net = Item_Net.merge (net1, net2)} |
|
138 val extend = I |
|
139 ) |
|
140 |
|
141 fun rewrite' ctxt old_prems bounds thms ct = |
|
142 let |
|
143 val thy = Proof_Context.theory_of ctxt |
|
144 fun apply_rule t thm = |
|
145 let |
|
146 val lhs = thm |> Thm.concl_of |> Logic.dest_equals |> fst |
|
147 val _ = Pattern.first_order_match thy (lhs, t) (Vartab.empty, Vartab.empty) |
|
148 val insts = (lhs, t) |> apply2 (Thm.cterm_of ctxt) |> Thm.first_order_match |
|
149 val thm = Thm.instantiate insts thm |
|
150 val prems = Thm.prems_of thm |
|
151 val frees = fold Term.add_frees prems [] |
|
152 in |
|
153 if exists (member op = bounds o fst) frees then |
|
154 NONE |
|
155 else |
|
156 let |
|
157 val thm' = thm OF (map (Thm.assume o Thm.cterm_of ctxt) prems) |
|
158 val prems' = fold (insert op aconv) prems old_prems |
|
159 val crhs = thm |> Thm.concl_of |> Logic.dest_equals |> snd |> Thm.cterm_of ctxt |
|
160 in |
|
161 SOME (thm', crhs, prems') |
|
162 end |
|
163 end |
|
164 handle Pattern.MATCH => NONE |
|
165 fun rewrite_subterm prems ct (Abs (x, _, _)) = |
|
166 let |
|
167 val (u, ctxt') = yield_singleton Variable.variant_fixes x ctxt; |
|
168 val (v, ct') = Thm.dest_abs (SOME u) ct; |
|
169 val (thm, prems) = rewrite' ctxt' prems (x :: bounds) thms ct' |
|
170 in |
|
171 if Thm.is_reflexive thm then |
|
172 (Thm.reflexive ct, prems) |
|
173 else |
|
174 (Thm.abstract_rule x v thm, prems) |
|
175 end |
|
176 | rewrite_subterm prems ct (_ $ _) = |
|
177 let |
|
178 val (cs, ct) = Thm.dest_comb ct |
|
179 val (thm, prems') = rewrite' ctxt prems bounds thms cs |
|
180 val (thm', prems'') = rewrite' ctxt prems' bounds thms ct |
|
181 in |
|
182 (Thm.combination thm thm', prems'') |
|
183 end |
|
184 | rewrite_subterm prems ct _ = (Thm.reflexive ct, prems) |
|
185 val t = Thm.term_of ct |
|
186 in |
|
187 case get_first (apply_rule t) thms of |
|
188 NONE => rewrite_subterm old_prems ct t |
|
189 | SOME (thm, rhs, prems) => |
|
190 case rewrite' ctxt prems bounds thms rhs of |
|
191 (thm', prems) => (Thm.transitive thm thm', prems) |
|
192 end |
|
193 |
|
194 fun rewrite ctxt thms ct = |
|
195 let |
|
196 val thm1 = Thm.eta_long_conversion ct |
|
197 val rhs = thm1 |> Thm.cprop_of |> Thm.dest_comb |> snd |
|
198 val (thm2, prems) = rewrite' ctxt [] [] thms rhs |
|
199 val rhs = thm2 |> Thm.cprop_of |> Thm.dest_comb |> snd |
|
200 val thm3 = Thm.eta_conversion rhs |
|
201 val thm = Thm.transitive thm1 (Thm.transitive thm2 thm3) |
|
202 in |
|
203 fold (fn prem => fn thm => Thm.implies_intr (Thm.cterm_of ctxt prem) thm) prems thm |
|
204 end |
|
205 |
|
206 fun preproc_term_conv ctxt = |
|
207 let |
|
208 val thms = Named_Theorems.get ctxt @{named_theorems "real_asymp_reify_simps"} |
|
209 val thms = map (fn thm => thm RS @{thm HOL.eq_reflection}) thms |
|
210 in |
|
211 rewrite ctxt thms |
|
212 end |
|
213 |
|
214 fun register_custom' binding pat expand context = |
|
215 let |
|
216 val n = pat |> fastype_of |> strip_type |> fst |> length |
|
217 val maxidx = Term.maxidx_of_term pat |
|
218 val vars = map (fn i => Var ((Name.uu_, maxidx + i), @{typ real})) (1 upto n) |
|
219 val net_pat = Library.foldl betapply (pat, vars) |
|
220 val {name_table = tbl, net = net} = Custom_Funs.get context |
|
221 val entry' = {pat = pat, net_pat = net_pat, expand = expand} |
|
222 val (name, tbl) = Name_Space.define context true (binding, entry') tbl |
|
223 val entry = {name = name, pat = pat, net_pat = net_pat, expand = expand} |
|
224 val net = Item_Net.update entry net |
|
225 in |
|
226 Custom_Funs.put {name_table = tbl, net = net} context |
|
227 end |
|
228 |
|
229 fun register_custom binding pat expand = |
|
230 let |
|
231 fun decl phi = |
|
232 register_custom' binding (Morphism.term phi pat) expand |
|
233 in |
|
234 Local_Theory.declaration {syntax = false, pervasive = false} decl |
|
235 end |
|
236 |
|
237 fun register_custom_from_thm binding thm expand = |
|
238 let |
|
239 val pat = thm |> Thm.concl_of |> HOLogic.dest_Trueprop |> dest_comb |> snd |
|
240 in |
|
241 register_custom binding pat expand |
|
242 end |
|
243 |
|
244 fun expand_custom ctxt name = |
|
245 let |
|
246 val {name_table, ...} = Custom_Funs.get (Context.Proof ctxt) |
|
247 in |
|
248 case Name_Space.lookup name_table name of |
|
249 NONE => NONE |
|
250 | SOME {expand, ...} => SOME expand |
|
251 end |
|
252 |
|
253 fun expr_to_term e = |
|
254 let |
|
255 fun expr_to_term' (ConstExpr c) = c |
|
256 | expr_to_term' X = Bound 0 |
|
257 | expr_to_term' (Add (a, b)) = |
|
258 @{term "(+) :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
259 | expr_to_term' (Mult (a, b)) = |
|
260 @{term "( *) :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
261 | expr_to_term' (Minus (a, b)) = |
|
262 @{term "(-) :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
263 | expr_to_term' (Div (a, b)) = |
|
264 @{term "(/) :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
265 | expr_to_term' (Uminus a) = |
|
266 @{term "uminus :: real => _"} $ expr_to_term' a |
|
267 | expr_to_term' (Inverse a) = |
|
268 @{term "inverse :: real => _"} $ expr_to_term' a |
|
269 | expr_to_term' (Ln a) = |
|
270 @{term "ln :: real => _"} $ expr_to_term' a |
|
271 | expr_to_term' (Exp a) = |
|
272 @{term "exp :: real => _"} $ expr_to_term' a |
|
273 | expr_to_term' (Powr (a,b)) = |
|
274 @{term "(powr) :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
275 | expr_to_term' (Powr_Nat (a,b)) = |
|
276 @{term "powr_nat :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
277 | expr_to_term' (LnPowr (a,b)) = |
|
278 @{term "ln :: real => _"} $ |
|
279 (@{term "(powr) :: real => _"} $ expr_to_term' a $ expr_to_term' b) |
|
280 | expr_to_term' (ExpLn a) = |
|
281 @{term "exp :: real => _"} $ (@{term "ln :: real => _"} $ expr_to_term' a) |
|
282 | expr_to_term' (Powr' (a,b)) = |
|
283 @{term "(powr) :: real => _"} $ expr_to_term' a $ b |
|
284 | expr_to_term' (Power (a,b)) = |
|
285 @{term "(^) :: real => _"} $ expr_to_term' a $ b |
|
286 | expr_to_term' (Floor a) = |
|
287 @{term Multiseries_Expansion.rfloor} $ expr_to_term' a |
|
288 | expr_to_term' (Ceiling a) = |
|
289 @{term Multiseries_Expansion.rceil} $ expr_to_term' a |
|
290 | expr_to_term' (Frac a) = |
|
291 @{term "Archimedean_Field.frac :: real \<Rightarrow> real"} $ expr_to_term' a |
|
292 | expr_to_term' (NatMod (a,b)) = |
|
293 @{term "Multiseries_Expansion.rnatmod"} $ expr_to_term' a $ expr_to_term' b |
|
294 | expr_to_term' (Root (a,b)) = |
|
295 @{term "root :: nat \<Rightarrow> real \<Rightarrow> _"} $ b $ expr_to_term' a |
|
296 | expr_to_term' (Sin a) = |
|
297 @{term "sin :: real => _"} $ expr_to_term' a |
|
298 | expr_to_term' (ArcTan a) = |
|
299 @{term "arctan :: real => _"} $ expr_to_term' a |
|
300 | expr_to_term' (Cos a) = |
|
301 @{term "cos :: real => _"} $ expr_to_term' a |
|
302 | expr_to_term' (Absolute a) = |
|
303 @{term "abs :: real => _"} $ expr_to_term' a |
|
304 | expr_to_term' (Sgn a) = |
|
305 @{term "sgn :: real => _"} $ expr_to_term' a |
|
306 | expr_to_term' (Min (a,b)) = |
|
307 @{term "min :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
308 | expr_to_term' (Max (a,b)) = |
|
309 @{term "max :: real => _"} $ expr_to_term' a $ expr_to_term' b |
|
310 | expr_to_term' (Custom (_, t, args)) = Envir.beta_eta_contract ( |
|
311 fold (fn e => fn t => betapply (t, expr_to_term' e )) args t) |
|
312 in |
|
313 Abs ("x", @{typ "real"}, expr_to_term' e) |
|
314 end |
|
315 |
|
316 fun reify_custom ctxt t = |
|
317 let |
|
318 val thy = Proof_Context.theory_of ctxt |
|
319 val t = Envir.beta_eta_contract t |
|
320 val t' = Envir.beta_eta_contract (Term.abs ("x", @{typ real}) t) |
|
321 val {net, ...} = Custom_Funs.get (Context.Proof ctxt) |
|
322 val entries = Item_Net.retrieve_matching net (Term.subst_bound (Free ("x", @{typ real}), t)) |
|
323 fun go {pat, name, ...} = |
|
324 let |
|
325 val n = pat |> fastype_of |> strip_type |> fst |> length |
|
326 val maxidx = Term.maxidx_of_term t' |
|
327 val vs = map (fn i => (Name.uu_, maxidx + i)) (1 upto n) |
|
328 val args = map (fn v => Var (v, @{typ "real => real"}) $ Bound 0) vs |
|
329 val pat' = |
|
330 Envir.beta_eta_contract (Term.abs ("x", @{typ "real"}) |
|
331 (Library.foldl betapply (pat, args))) |
|
332 val (T_insts, insts) = Pattern.match thy (pat', t') (Vartab.empty, Vartab.empty) |
|
333 fun map_option _ [] acc = SOME (rev acc) |
|
334 | map_option f (x :: xs) acc = |
|
335 case f x of |
|
336 NONE => NONE |
|
337 | SOME y => map_option f xs (y :: acc) |
|
338 val t = Envir.subst_term (T_insts, insts) pat |
|
339 in |
|
340 Option.map (pair (name, t)) (map_option (Option.map snd o Vartab.lookup insts) vs []) |
|
341 end |
|
342 handle Pattern.MATCH => NONE |
|
343 in |
|
344 get_first go entries |
|
345 end |
|
346 |
|
347 fun reify_aux ctxt t' t = |
|
348 let |
|
349 fun is_const t = |
|
350 fastype_of (Abs ("x", @{typ real}, t)) = @{typ "real \<Rightarrow> real"} |
|
351 andalso not (exists_subterm (fn t => t = Bound 0) t) |
|
352 fun is_const' t = not (exists_subterm (fn t => t = Bound 0) t) |
|
353 fun reify'' (@{term "(+) :: real => _"} $ s $ t) = |
|
354 Add (reify' s, reify' t) |
|
355 | reify'' (@{term "(-) :: real => _"} $ s $ t) = |
|
356 Minus (reify' s, reify' t) |
|
357 | reify'' (@{term "( *) :: real => _"} $ s $ t) = |
|
358 Mult (reify' s, reify' t) |
|
359 | reify'' (@{term "(/) :: real => _"} $ s $ t) = |
|
360 Div (reify' s, reify' t) |
|
361 | reify'' (@{term "uminus :: real => _"} $ s) = |
|
362 Uminus (reify' s) |
|
363 | reify'' (@{term "inverse :: real => _"} $ s) = |
|
364 Inverse (reify' s) |
|
365 | reify'' (@{term "ln :: real => _"} $ (@{term "(powr) :: real => _"} $ s $ t)) = |
|
366 LnPowr (reify' s, reify' t) |
|
367 | reify'' (@{term "exp :: real => _"} $ (@{term "ln :: real => _"} $ s)) = |
|
368 ExpLn (reify' s) |
|
369 | reify'' (@{term "ln :: real => _"} $ s) = |
|
370 Ln (reify' s) |
|
371 | reify'' (@{term "exp :: real => _"} $ s) = |
|
372 Exp (reify' s) |
|
373 | reify'' (@{term "(powr) :: real => _"} $ s $ t) = |
|
374 (if is_const t then Powr' (reify' s, t) else Powr (reify' s, reify' t)) |
|
375 | reify'' (@{term "powr_nat :: real => _"} $ s $ t) = |
|
376 Powr_Nat (reify' s, reify' t) |
|
377 | reify'' (@{term "(^) :: real => _"} $ s $ t) = |
|
378 (if is_const' t then Power (reify' s, t) else raise TERM ("reify", [t'])) |
|
379 | reify'' (@{term "root"} $ s $ t) = |
|
380 (if is_const' s then Root (reify' t, s) else raise TERM ("reify", [t'])) |
|
381 | reify'' (@{term "abs :: real => _"} $ s) = |
|
382 Absolute (reify' s) |
|
383 | reify'' (@{term "sgn :: real => _"} $ s) = |
|
384 Sgn (reify' s) |
|
385 | reify'' (@{term "min :: real => _"} $ s $ t) = |
|
386 Min (reify' s, reify' t) |
|
387 | reify'' (@{term "max :: real => _"} $ s $ t) = |
|
388 Max (reify' s, reify' t) |
|
389 | reify'' (@{term "Multiseries_Expansion.rfloor"} $ s) = |
|
390 Floor (reify' s) |
|
391 | reify'' (@{term "Multiseries_Expansion.rceil"} $ s) = |
|
392 Ceiling (reify' s) |
|
393 | reify'' (@{term "Archimedean_Field.frac :: real \<Rightarrow> real"} $ s) = |
|
394 Frac (reify' s) |
|
395 | reify'' (@{term "Multiseries_Expansion.rnatmod"} $ s $ t) = |
|
396 NatMod (reify' s, reify' t) |
|
397 | reify'' (@{term "sin :: real => _"} $ s) = |
|
398 Sin (reify' s) |
|
399 | reify'' (@{term "arctan :: real => _"} $ s) = |
|
400 ArcTan (reify' s) |
|
401 | reify'' (@{term "cos :: real => _"} $ s) = |
|
402 Cos (reify' s) |
|
403 | reify'' (Bound 0) = X |
|
404 | reify'' t = |
|
405 case reify_custom ctxt t of |
|
406 SOME ((name, t), ts) => |
|
407 let |
|
408 val args = map (reify_aux ctxt t') ts |
|
409 in |
|
410 Custom (name, t, args) |
|
411 end |
|
412 | NONE => raise TERM ("reify", [t']) |
|
413 and reify' t = if is_const t then ConstExpr t else reify'' t |
|
414 in |
|
415 case Envir.eta_long [] t of |
|
416 Abs (_, @{typ real}, t'') => reify' t'' |
|
417 | _ => raise TERM ("reify", [t]) |
|
418 end |
|
419 |
|
420 fun reify ctxt t = |
|
421 let |
|
422 val thm = preproc_term_conv ctxt (Thm.cterm_of ctxt t) |
|
423 val rhs = thm |> Thm.concl_of |> Logic.dest_equals |> snd |
|
424 in |
|
425 (reify_aux ctxt t rhs, thm) |
|
426 end |
|
427 |
|
428 fun reify_simple_aux ctxt t' t = |
|
429 let |
|
430 fun is_const t = |
|
431 fastype_of (Abs ("x", @{typ real}, t)) = @{typ "real \<Rightarrow> real"} |
|
432 andalso not (exists_subterm (fn t => t = Bound 0) t) |
|
433 fun is_const' t = not (exists_subterm (fn t => t = Bound 0) t) |
|
434 fun reify'' (@{term "(+) :: real => _"} $ s $ t) = |
|
435 Add (reify'' s, reify'' t) |
|
436 | reify'' (@{term "(-) :: real => _"} $ s $ t) = |
|
437 Minus (reify'' s, reify'' t) |
|
438 | reify'' (@{term "( *) :: real => _"} $ s $ t) = |
|
439 Mult (reify'' s, reify'' t) |
|
440 | reify'' (@{term "(/) :: real => _"} $ s $ t) = |
|
441 Div (reify'' s, reify'' t) |
|
442 | reify'' (@{term "uminus :: real => _"} $ s) = |
|
443 Uminus (reify'' s) |
|
444 | reify'' (@{term "inverse :: real => _"} $ s) = |
|
445 Inverse (reify'' s) |
|
446 | reify'' (@{term "ln :: real => _"} $ s) = |
|
447 Ln (reify'' s) |
|
448 | reify'' (@{term "exp :: real => _"} $ s) = |
|
449 Exp (reify'' s) |
|
450 | reify'' (@{term "(powr) :: real => _"} $ s $ t) = |
|
451 Powr (reify'' s, reify'' t) |
|
452 | reify'' (@{term "powr_nat :: real => _"} $ s $ t) = |
|
453 Powr_Nat (reify'' s, reify'' t) |
|
454 | reify'' (@{term "(^) :: real => _"} $ s $ t) = |
|
455 (if is_const' t then Power (reify'' s, t) else raise TERM ("reify", [t'])) |
|
456 | reify'' (@{term "root"} $ s $ t) = |
|
457 (if is_const' s then Root (reify'' t, s) else raise TERM ("reify", [t'])) |
|
458 | reify'' (@{term "abs :: real => _"} $ s) = |
|
459 Absolute (reify'' s) |
|
460 | reify'' (@{term "sgn :: real => _"} $ s) = |
|
461 Sgn (reify'' s) |
|
462 | reify'' (@{term "min :: real => _"} $ s $ t) = |
|
463 Min (reify'' s, reify'' t) |
|
464 | reify'' (@{term "max :: real => _"} $ s $ t) = |
|
465 Max (reify'' s, reify'' t) |
|
466 | reify'' (@{term "Multiseries_Expansion.rfloor"} $ s) = |
|
467 Floor (reify'' s) |
|
468 | reify'' (@{term "Multiseries_Expansion.rceil"} $ s) = |
|
469 Ceiling (reify'' s) |
|
470 | reify'' (@{term "Archimedean_Field.frac :: real \<Rightarrow> real"} $ s) = |
|
471 Frac (reify'' s) |
|
472 | reify'' (@{term "Multiseries_Expansion.rnatmod"} $ s $ t) = |
|
473 NatMod (reify'' s, reify'' t) |
|
474 | reify'' (@{term "sin :: real => _"} $ s) = |
|
475 Sin (reify'' s) |
|
476 | reify'' (@{term "cos :: real => _"} $ s) = |
|
477 Cos (reify'' s) |
|
478 | reify'' (Bound 0) = X |
|
479 | reify'' t = |
|
480 if is_const t then |
|
481 ConstExpr t |
|
482 else |
|
483 case reify_custom ctxt t of |
|
484 SOME ((name, t), ts) => |
|
485 let |
|
486 val args = map (reify_aux ctxt t') ts |
|
487 in |
|
488 Custom (name, t, args) |
|
489 end |
|
490 | NONE => raise TERM ("reify", [t']) |
|
491 in |
|
492 case Envir.eta_long [] t of |
|
493 Abs (_, @{typ real}, t'') => reify'' t'' |
|
494 | _ => raise TERM ("reify", [t]) |
|
495 end |
|
496 |
|
497 fun reify_simple ctxt t = |
|
498 let |
|
499 val thm = preproc_term_conv ctxt (Thm.cterm_of ctxt t) |
|
500 val rhs = thm |> Thm.concl_of |> Logic.dest_equals |> snd |
|
501 in |
|
502 (reify_simple_aux ctxt t rhs, thm) |
|
503 end |
|
504 |
|
505 fun simple_print_const (Free (x, _)) = x |
|
506 | simple_print_const (@{term "uminus :: real => real"} $ a) = |
|
507 "(-" ^ simple_print_const a ^ ")" |
|
508 | simple_print_const (@{term "(+) :: real => _"} $ a $ b) = |
|
509 "(" ^ simple_print_const a ^ "+" ^ simple_print_const b ^ ")" |
|
510 | simple_print_const (@{term "(-) :: real => _"} $ a $ b) = |
|
511 "(" ^ simple_print_const a ^ "-" ^ simple_print_const b ^ ")" |
|
512 | simple_print_const (@{term "( * ) :: real => _"} $ a $ b) = |
|
513 "(" ^ simple_print_const a ^ "*" ^ simple_print_const b ^ ")" |
|
514 | simple_print_const (@{term "inverse :: real => _"} $ a) = |
|
515 "(1 / " ^ simple_print_const a ^ ")" |
|
516 | simple_print_const (@{term "(/) :: real => _"} $ a $ b) = |
|
517 "(" ^ simple_print_const a ^ "/" ^ simple_print_const b ^ ")" |
|
518 | simple_print_const t = Int.toString (snd (HOLogic.dest_number t)) |
|
519 |
|
520 fun to_mathematica (Add (a, b)) = "(" ^ to_mathematica a ^ " + " ^ to_mathematica b ^ ")" |
|
521 | to_mathematica (Minus (a, b)) = "(" ^ to_mathematica a ^ " - " ^ to_mathematica b ^ ")" |
|
522 | to_mathematica (Mult (a, b)) = "(" ^ to_mathematica a ^ " * " ^ to_mathematica b ^ ")" |
|
523 | to_mathematica (Div (a, b)) = "(" ^ to_mathematica a ^ " / " ^ to_mathematica b ^ ")" |
|
524 | to_mathematica (Powr (a, b)) = "(" ^ to_mathematica a ^ " ^ " ^ to_mathematica b ^ ")" |
|
525 | to_mathematica (Powr_Nat (a, b)) = "(" ^ to_mathematica a ^ " ^ " ^ to_mathematica b ^ ")" |
|
526 | to_mathematica (Powr' (a, b)) = "(" ^ to_mathematica a ^ " ^ " ^ |
|
527 to_mathematica (ConstExpr b) ^ ")" |
|
528 | to_mathematica (LnPowr (a, b)) = "Log[" ^ to_mathematica a ^ " ^ " ^ to_mathematica b ^ "]" |
|
529 | to_mathematica (ExpLn a) = "Exp[Ln[" ^ to_mathematica a ^ "]]" |
|
530 | to_mathematica (Power (a, b)) = "(" ^ to_mathematica a ^ " ^ " ^ |
|
531 to_mathematica (ConstExpr b) ^ ")" |
|
532 | to_mathematica (Root (a, @{term "2::real"})) = "Sqrt[" ^ to_mathematica a ^ "]" |
|
533 | to_mathematica (Root (a, b)) = "Surd[" ^ to_mathematica a ^ ", " ^ |
|
534 to_mathematica (ConstExpr b) ^ "]" |
|
535 | to_mathematica (Uminus a) = "(-" ^ to_mathematica a ^ ")" |
|
536 | to_mathematica (Inverse a) = "(1/(" ^ to_mathematica a ^ "))" |
|
537 | to_mathematica (Exp a) = "Exp[" ^ to_mathematica a ^ "]" |
|
538 | to_mathematica (Ln a) = "Log[" ^ to_mathematica a ^ "]" |
|
539 | to_mathematica (Sin a) = "Sin[" ^ to_mathematica a ^ "]" |
|
540 | to_mathematica (Cos a) = "Cos[" ^ to_mathematica a ^ "]" |
|
541 | to_mathematica (ArcTan a) = "ArcTan[" ^ to_mathematica a ^ "]" |
|
542 | to_mathematica (Absolute a) = "Abs[" ^ to_mathematica a ^ "]" |
|
543 | to_mathematica (Sgn a) = "Sign[" ^ to_mathematica a ^ "]" |
|
544 | to_mathematica (Min (a, b)) = "Min[" ^ to_mathematica a ^ ", " ^ to_mathematica b ^ "]" |
|
545 | to_mathematica (Max (a, b)) = "Max[" ^ to_mathematica a ^ ", " ^ to_mathematica b ^ "]" |
|
546 | to_mathematica (Floor a) = "Floor[" ^ to_mathematica a ^ "]" |
|
547 | to_mathematica (Ceiling a) = "Ceiling[" ^ to_mathematica a ^ "]" |
|
548 | to_mathematica (Frac a) = "Mod[" ^ to_mathematica a ^ ", 1]" |
|
549 | to_mathematica (ConstExpr t) = simple_print_const t |
|
550 | to_mathematica X = "X" |
|
551 |
|
552 (* TODO: correct translation of frac() for Maple and Sage *) |
|
553 fun to_maple (Add (a, b)) = "(" ^ to_maple a ^ " + " ^ to_maple b ^ ")" |
|
554 | to_maple (Minus (a, b)) = "(" ^ to_maple a ^ " - " ^ to_maple b ^ ")" |
|
555 | to_maple (Mult (a, b)) = "(" ^ to_maple a ^ " * " ^ to_maple b ^ ")" |
|
556 | to_maple (Div (a, b)) = "(" ^ to_maple a ^ " / " ^ to_maple b ^ ")" |
|
557 | to_maple (Powr (a, b)) = "(" ^ to_maple a ^ " ^ " ^ to_maple b ^ ")" |
|
558 | to_maple (Powr_Nat (a, b)) = "(" ^ to_maple a ^ " ^ " ^ to_maple b ^ ")" |
|
559 | to_maple (Powr' (a, b)) = "(" ^ to_maple a ^ " ^ " ^ |
|
560 to_maple (ConstExpr b) ^ ")" |
|
561 | to_maple (LnPowr (a, b)) = "ln(" ^ to_maple a ^ " ^ " ^ to_maple b ^ ")" |
|
562 | to_maple (ExpLn a) = "ln(exp(" ^ to_maple a ^ "))" |
|
563 | to_maple (Power (a, b)) = "(" ^ to_maple a ^ " ^ " ^ |
|
564 to_maple (ConstExpr b) ^ ")" |
|
565 | to_maple (Root (a, @{term "2::real"})) = "sqrt(" ^ to_maple a ^ ")" |
|
566 | to_maple (Root (a, b)) = "root(" ^ to_maple a ^ ", " ^ |
|
567 to_maple (ConstExpr b) ^ ")" |
|
568 | to_maple (Uminus a) = "(-" ^ to_maple a ^ ")" |
|
569 | to_maple (Inverse a) = "(1/(" ^ to_maple a ^ "))" |
|
570 | to_maple (Exp a) = "exp(" ^ to_maple a ^ ")" |
|
571 | to_maple (Ln a) = "ln(" ^ to_maple a ^ ")" |
|
572 | to_maple (Sin a) = "sin(" ^ to_maple a ^ ")" |
|
573 | to_maple (Cos a) = "cos(" ^ to_maple a ^ ")" |
|
574 | to_maple (ArcTan a) = "arctan(" ^ to_maple a ^ ")" |
|
575 | to_maple (Absolute a) = "abs(" ^ to_maple a ^ ")" |
|
576 | to_maple (Sgn a) = "signum(" ^ to_maple a ^ ")" |
|
577 | to_maple (Min (a, b)) = "min(" ^ to_maple a ^ ", " ^ to_maple b ^ ")" |
|
578 | to_maple (Max (a, b)) = "max(" ^ to_maple a ^ ", " ^ to_maple b ^ ")" |
|
579 | to_maple (Floor a) = "floor(" ^ to_maple a ^ ")" |
|
580 | to_maple (Ceiling a) = "ceil(" ^ to_maple a ^ ")" |
|
581 | to_maple (Frac a) = "frac(" ^ to_maple a ^ ")" |
|
582 | to_maple (ConstExpr t) = simple_print_const t |
|
583 | to_maple X = "x" |
|
584 |
|
585 fun to_maxima (Add (a, b)) = "(" ^ to_maxima a ^ " + " ^ to_maxima b ^ ")" |
|
586 | to_maxima (Minus (a, b)) = "(" ^ to_maxima a ^ " - " ^ to_maxima b ^ ")" |
|
587 | to_maxima (Mult (a, b)) = "(" ^ to_maxima a ^ " * " ^ to_maxima b ^ ")" |
|
588 | to_maxima (Div (a, b)) = "(" ^ to_maxima a ^ " / " ^ to_maxima b ^ ")" |
|
589 | to_maxima (Powr (a, b)) = "(" ^ to_maxima a ^ " ^ " ^ to_maxima b ^ ")" |
|
590 | to_maxima (Powr_Nat (a, b)) = "(" ^ to_maxima a ^ " ^ " ^ to_maxima b ^ ")" |
|
591 | to_maxima (Powr' (a, b)) = "(" ^ to_maxima a ^ " ^ " ^ |
|
592 to_maxima (ConstExpr b) ^ ")" |
|
593 | to_maxima (ExpLn a) = "exp (log (" ^ to_maxima a ^ "))" |
|
594 | to_maxima (LnPowr (a, b)) = "log(" ^ to_maxima a ^ " ^ " ^ to_maxima b ^ ")" |
|
595 | to_maxima (Power (a, b)) = "(" ^ to_maxima a ^ " ^ " ^ |
|
596 to_maxima (ConstExpr b) ^ ")" |
|
597 | to_maxima (Root (a, @{term "2::real"})) = "sqrt(" ^ to_maxima a ^ ")" |
|
598 | to_maxima (Root (a, b)) = to_maxima a ^ "^(1/" ^ |
|
599 to_maxima (ConstExpr b) ^ ")" |
|
600 | to_maxima (Uminus a) = "(-" ^ to_maxima a ^ ")" |
|
601 | to_maxima (Inverse a) = "(1/(" ^ to_maxima a ^ "))" |
|
602 | to_maxima (Exp a) = "exp(" ^ to_maxima a ^ ")" |
|
603 | to_maxima (Ln a) = "log(" ^ to_maxima a ^ ")" |
|
604 | to_maxima (Sin a) = "sin(" ^ to_maxima a ^ ")" |
|
605 | to_maxima (Cos a) = "cos(" ^ to_maxima a ^ ")" |
|
606 | to_maxima (ArcTan a) = "atan(" ^ to_maxima a ^ ")" |
|
607 | to_maxima (Absolute a) = "abs(" ^ to_maxima a ^ ")" |
|
608 | to_maxima (Sgn a) = "signum(" ^ to_maxima a ^ ")" |
|
609 | to_maxima (Min (a, b)) = "min(" ^ to_maxima a ^ ", " ^ to_maxima b ^ ")" |
|
610 | to_maxima (Max (a, b)) = "max(" ^ to_maxima a ^ ", " ^ to_maxima b ^ ")" |
|
611 | to_maxima (Floor a) = "floor(" ^ to_maxima a ^ ")" |
|
612 | to_maxima (Ceiling a) = "ceil(" ^ to_maxima a ^ ")" |
|
613 | to_maxima (Frac a) = let val x = to_maxima a in "(" ^ x ^ " - floor(" ^ x ^ "))" end |
|
614 | to_maxima (ConstExpr t) = simple_print_const t |
|
615 | to_maxima X = "x" |
|
616 |
|
617 fun to_sympy (Add (a, b)) = "(" ^ to_sympy a ^ " + " ^ to_sympy b ^ ")" |
|
618 | to_sympy (Minus (a, b)) = "(" ^ to_sympy a ^ " - " ^ to_sympy b ^ ")" |
|
619 | to_sympy (Mult (a, b)) = "(" ^ to_sympy a ^ " * " ^ to_sympy b ^ ")" |
|
620 | to_sympy (Div (a, b)) = "(" ^ to_sympy a ^ " / " ^ to_sympy b ^ ")" |
|
621 | to_sympy (Powr (a, b)) = "(" ^ to_sympy a ^ " ** " ^ to_sympy b ^ ")" |
|
622 | to_sympy (Powr_Nat (a, b)) = "(" ^ to_sympy a ^ " ** " ^ to_sympy b ^ ")" |
|
623 | to_sympy (Powr' (a, b)) = "(" ^ to_sympy a ^ " ** " ^ |
|
624 to_sympy (ConstExpr b) ^ ")" |
|
625 | to_sympy (ExpLn a) = "exp (log (" ^ to_sympy a ^ "))" |
|
626 | to_sympy (LnPowr (a, b)) = "log(" ^ to_sympy a ^ " ** " ^ to_sympy b ^ ")" |
|
627 | to_sympy (Power (a, b)) = "(" ^ to_sympy a ^ " ** " ^ |
|
628 to_sympy (ConstExpr b) ^ ")" |
|
629 | to_sympy (Root (a, @{term "2::real"})) = "sqrt(" ^ to_sympy a ^ ")" |
|
630 | to_sympy (Root (a, b)) = "root(" ^ to_sympy a ^ ", " ^ to_sympy (ConstExpr b) ^ ")" |
|
631 | to_sympy (Uminus a) = "(-" ^ to_sympy a ^ ")" |
|
632 | to_sympy (Inverse a) = "(1/(" ^ to_sympy a ^ "))" |
|
633 | to_sympy (Exp a) = "exp(" ^ to_sympy a ^ ")" |
|
634 | to_sympy (Ln a) = "log(" ^ to_sympy a ^ ")" |
|
635 | to_sympy (Sin a) = "sin(" ^ to_sympy a ^ ")" |
|
636 | to_sympy (Cos a) = "cos(" ^ to_sympy a ^ ")" |
|
637 | to_sympy (ArcTan a) = "atan(" ^ to_sympy a ^ ")" |
|
638 | to_sympy (Absolute a) = "abs(" ^ to_sympy a ^ ")" |
|
639 | to_sympy (Sgn a) = "sign(" ^ to_sympy a ^ ")" |
|
640 | to_sympy (Min (a, b)) = "min(" ^ to_sympy a ^ ", " ^ to_sympy b ^ ")" |
|
641 | to_sympy (Max (a, b)) = "max(" ^ to_sympy a ^ ", " ^ to_sympy b ^ ")" |
|
642 | to_sympy (Floor a) = "floor(" ^ to_sympy a ^ ")" |
|
643 | to_sympy (Ceiling a) = "ceiling(" ^ to_sympy a ^ ")" |
|
644 | to_sympy (Frac a) = "frac(" ^ to_sympy a ^ ")" |
|
645 | to_sympy (ConstExpr t) = simple_print_const t |
|
646 | to_sympy X = "x" |
|
647 |
|
648 fun to_sage (Add (a, b)) = "(" ^ to_sage a ^ " + " ^ to_sage b ^ ")" |
|
649 | to_sage (Minus (a, b)) = "(" ^ to_sage a ^ " - " ^ to_sage b ^ ")" |
|
650 | to_sage (Mult (a, b)) = "(" ^ to_sage a ^ " * " ^ to_sage b ^ ")" |
|
651 | to_sage (Div (a, b)) = "(" ^ to_sage a ^ " / " ^ to_sage b ^ ")" |
|
652 | to_sage (Powr (a, b)) = "(" ^ to_sage a ^ " ^ " ^ to_sage b ^ ")" |
|
653 | to_sage (Powr_Nat (a, b)) = "(" ^ to_sage a ^ " ^ " ^ to_sage b ^ ")" |
|
654 | to_sage (Powr' (a, b)) = "(" ^ to_sage a ^ " ^ " ^ |
|
655 to_sage (ConstExpr b) ^ ")" |
|
656 | to_sage (ExpLn a) = "exp (log (" ^ to_sage a ^ "))" |
|
657 | to_sage (LnPowr (a, b)) = "log(" ^ to_sage a ^ " ^ " ^ to_sage b ^ ")" |
|
658 | to_sage (Power (a, b)) = "(" ^ to_sage a ^ " ^ " ^ |
|
659 to_sage (ConstExpr b) ^ ")" |
|
660 | to_sage (Root (a, @{term "2::real"})) = "sqrt(" ^ to_sage a ^ ")" |
|
661 | to_sage (Root (a, b)) = to_sage a ^ "^(1/" ^ to_sage (ConstExpr b) ^ ")" |
|
662 | to_sage (Uminus a) = "(-" ^ to_sage a ^ ")" |
|
663 | to_sage (Inverse a) = "(1/(" ^ to_sage a ^ "))" |
|
664 | to_sage (Exp a) = "exp(" ^ to_sage a ^ ")" |
|
665 | to_sage (Ln a) = "log(" ^ to_sage a ^ ")" |
|
666 | to_sage (Sin a) = "sin(" ^ to_sage a ^ ")" |
|
667 | to_sage (Cos a) = "cos(" ^ to_sage a ^ ")" |
|
668 | to_sage (ArcTan a) = "atan(" ^ to_sage a ^ ")" |
|
669 | to_sage (Absolute a) = "abs(" ^ to_sage a ^ ")" |
|
670 | to_sage (Sgn a) = "sign(" ^ to_sage a ^ ")" |
|
671 | to_sage (Min (a, b)) = "min(" ^ to_sage a ^ ", " ^ to_sage b ^ ")" |
|
672 | to_sage (Max (a, b)) = "max(" ^ to_sage a ^ ", " ^ to_sage b ^ ")" |
|
673 | to_sage (Floor a) = "floor(" ^ to_sage a ^ ")" |
|
674 | to_sage (Ceiling a) = "ceil(" ^ to_sage a ^ ")" |
|
675 | to_sage (Frac a) = "frac(" ^ to_sage a ^ ")" |
|
676 | to_sage (ConstExpr t) = simple_print_const t |
|
677 | to_sage X = "x" |
|
678 |
|
679 fun reify_mathematica ctxt = to_mathematica o fst o reify_simple ctxt |
|
680 fun reify_maple ctxt = to_maple o fst o reify_simple ctxt |
|
681 fun reify_maxima ctxt = to_maxima o fst o reify_simple ctxt |
|
682 fun reify_sympy ctxt = to_sympy o fst o reify_simple ctxt |
|
683 fun reify_sage ctxt = to_sage o fst o reify_simple ctxt |
|
684 |
|
685 fun limit_mathematica s = "Limit[" ^ s ^ ", X -> Infinity]" |
|
686 fun limit_maple s = "limit(" ^ s ^ ", x = infinity);" |
|
687 fun limit_maxima s = "limit(" ^ s ^ ", x, inf);" |
|
688 fun limit_sympy s = "limit(" ^ s ^ ", x, oo)" |
|
689 fun limit_sage s = "limit(" ^ s ^ ", x = Infinity)" |
|
690 |
|
691 end |