3 *) |
3 *) |
4 |
4 |
5 signature APPROXIMATION = |
5 signature APPROXIMATION = |
6 sig |
6 sig |
7 val approx: int -> Proof.context -> term -> term |
7 val approx: int -> Proof.context -> term -> term |
|
8 val approximate: Proof.context -> term -> term |
|
9 val approximation_tac : int -> (string * int) list -> int option -> Proof.context -> int -> tactic |
8 end |
10 end |
9 |
11 |
10 structure Approximation: APPROXIMATION = |
12 structure Approximation: APPROXIMATION = |
11 struct |
13 struct |
|
14 |
|
15 fun reorder_bounds_tac prems i = |
|
16 let |
|
17 fun variable_of_bound (Const (@{const_name Trueprop}, _) $ |
|
18 (Const (@{const_name Set.member}, _) $ |
|
19 Free (name, _) $ _)) = name |
|
20 | variable_of_bound (Const (@{const_name Trueprop}, _) $ |
|
21 (Const (@{const_name HOL.eq}, _) $ |
|
22 Free (name, _) $ _)) = name |
|
23 | variable_of_bound t = raise TERM ("variable_of_bound", [t]) |
|
24 |
|
25 val variable_bounds |
|
26 = map (`(variable_of_bound o Thm.prop_of)) prems |
|
27 |
|
28 fun add_deps (name, bnds) |
|
29 = Graph.add_deps_acyclic (name, |
|
30 remove (op =) name (Term.add_free_names (Thm.prop_of bnds) [])) |
|
31 |
|
32 val order = Graph.empty |
|
33 |> fold Graph.new_node variable_bounds |
|
34 |> fold add_deps variable_bounds |
|
35 |> Graph.strong_conn |> map the_single |> rev |
|
36 |> map_filter (AList.lookup (op =) variable_bounds) |
|
37 |
|
38 fun prepend_prem th tac |
|
39 = tac THEN rtac (th RSN (2, @{thm mp})) i |
|
40 in |
|
41 fold prepend_prem order all_tac |
|
42 end |
|
43 |
|
44 fun approximation_conv ctxt ct = |
|
45 approximation_oracle (Proof_Context.theory_of ctxt, Thm.term_of ct |> tap (tracing o Syntax.string_of_term ctxt)); |
|
46 |
|
47 fun approximate ctxt t = |
|
48 approximation_oracle (Proof_Context.theory_of ctxt, t) |
|
49 |> Thm.prop_of |> Logic.dest_equals |> snd; |
|
50 |
|
51 (* Should be in HOL.thy ? *) |
|
52 fun gen_eval_tac conv ctxt = CONVERSION |
|
53 (Object_Logic.judgment_conv (Conv.params_conv (~1) (K (Conv.concl_conv (~1) conv)) ctxt)) |
|
54 THEN' rtac TrueI |
|
55 |
|
56 val form_equations = @{thms interpret_form_equations}; |
|
57 |
|
58 fun rewrite_interpret_form_tac ctxt prec splitting taylor i st = let |
|
59 fun lookup_splitting (Free (name, _)) |
|
60 = case AList.lookup (op =) splitting name |
|
61 of SOME s => HOLogic.mk_number @{typ nat} s |
|
62 | NONE => @{term "0 :: nat"} |
|
63 val vs = nth (Thm.prems_of st) (i - 1) |
|
64 |> Logic.strip_imp_concl |
|
65 |> HOLogic.dest_Trueprop |
|
66 |> Term.strip_comb |> snd |> List.last |
|
67 |> HOLogic.dest_list |
|
68 val p = prec |
|
69 |> HOLogic.mk_number @{typ nat} |
|
70 |> Thm.cterm_of ctxt |
|
71 in case taylor |
|
72 of NONE => let |
|
73 val n = vs |> length |
|
74 |> HOLogic.mk_number @{typ nat} |
|
75 |> Thm.cterm_of ctxt |
|
76 val s = vs |
|
77 |> map lookup_splitting |
|
78 |> HOLogic.mk_list @{typ nat} |
|
79 |> Thm.cterm_of ctxt |
|
80 in |
|
81 (rtac (Thm.instantiate ([], [(@{cpat "?n::nat"}, n), |
|
82 (@{cpat "?prec::nat"}, p), |
|
83 (@{cpat "?ss::nat list"}, s)]) |
|
84 @{thm "approx_form"}) i |
|
85 THEN simp_tac (put_simpset (simpset_of @{context}) ctxt) i) st |
|
86 end |
|
87 |
|
88 | SOME t => |
|
89 if length vs <> 1 |
|
90 then raise (TERM ("More than one variable used for taylor series expansion", [Thm.prop_of st])) |
|
91 else let |
|
92 val t = t |
|
93 |> HOLogic.mk_number @{typ nat} |
|
94 |> Thm.cterm_of ctxt |
|
95 val s = vs |> map lookup_splitting |> hd |
|
96 |> Thm.cterm_of ctxt |
|
97 in |
|
98 rtac (Thm.instantiate ([], [(@{cpat "?s::nat"}, s), |
|
99 (@{cpat "?t::nat"}, t), |
|
100 (@{cpat "?prec::nat"}, p)]) |
|
101 @{thm "approx_tse_form"}) i st |
|
102 end |
|
103 end |
12 |
104 |
13 fun calculated_subterms (@{const Trueprop} $ t) = calculated_subterms t |
105 fun calculated_subterms (@{const Trueprop} $ t) = calculated_subterms t |
14 | calculated_subterms (@{const HOL.implies} $ _ $ t) = calculated_subterms t |
106 | calculated_subterms (@{const HOL.implies} $ _ $ t) = calculated_subterms t |
15 | calculated_subterms (@{term "op <= :: real \<Rightarrow> real \<Rightarrow> bool"} $ t1 $ t2) = [t1, t2] |
107 | calculated_subterms (@{term "op <= :: real \<Rightarrow> real \<Rightarrow> bool"} $ t1 $ t2) = [t1, t2] |
16 | calculated_subterms (@{term "op < :: real \<Rightarrow> real \<Rightarrow> bool"} $ t1 $ t2) = [t1, t2] |
108 | calculated_subterms (@{term "op < :: real \<Rightarrow> real \<Rightarrow> bool"} $ t1 $ t2) = [t1, t2] |