23 val varify: string list -> thm -> thm |
23 val varify: string list -> thm -> thm |
24 val unfold_eqs: Proof.context -> thm list -> conv |
24 val unfold_eqs: Proof.context -> thm list -> conv |
25 val match_instantiate: (cterm -> cterm) -> cterm -> thm -> thm |
25 val match_instantiate: (cterm -> cterm) -> cterm -> thm -> thm |
26 val by_tac: (int -> tactic) -> cterm -> thm |
26 val by_tac: (int -> tactic) -> cterm -> thm |
27 val make_hyp_def: thm -> Proof.context -> thm * Proof.context |
27 val make_hyp_def: thm -> Proof.context -> thm * Proof.context |
28 val by_abstraction: Proof.context -> thm list -> (Proof.context -> cterm -> |
28 val by_abstraction: bool * bool -> Proof.context -> thm list -> |
29 thm) -> cterm -> thm |
29 (Proof.context -> cterm -> thm) -> cterm -> thm |
30 |
30 |
31 (* a faster COMP *) |
31 (* a faster COMP *) |
32 type compose_data |
32 type compose_data |
33 val precompose: (cterm -> cterm list) -> thm -> compose_data |
33 val precompose: (cterm -> cterm list) -> thm -> compose_data |
34 val precompose2: (cterm -> cterm * cterm) -> thm -> compose_data |
34 val precompose2: (cterm -> cterm * cterm) -> thm -> compose_data |
127 |
128 |
128 fun abs_context ctxt = (ctxt, Termtab.empty, 1, false) |
129 fun abs_context ctxt = (ctxt, Termtab.empty, 1, false) |
129 |
130 |
130 fun context_of (ctxt, _, _, _) = ctxt |
131 fun context_of (ctxt, _, _, _) = ctxt |
131 |
132 |
132 fun replace (cv, ct) = Thm.forall_elim ct o Thm.forall_intr cv |
133 fun replace (_, (cv, ct)) = Thm.forall_elim ct o Thm.forall_intr cv |
133 |
134 |
134 fun abs_instantiate (_, tab, _, beta_norm) = |
135 fun abs_instantiate (_, tab, _, beta_norm) = |
135 fold replace (map snd (Termtab.dest tab)) #> |
136 fold replace (Termtab.dest tab) #> |
136 beta_norm ? Conv.fconv_rule (Thm.beta_conversion true) |
137 beta_norm ? Conv.fconv_rule (Thm.beta_conversion true) |
137 |
138 |
138 fun generalize cvs = |
139 fun lambda_abstract cvs t = |
139 let |
140 let |
140 val no_name = "" |
141 val frees = map Free (Term.add_frees t []) |
141 |
142 val cvs' = filter (fn cv => member (op aconv) frees (Thm.term_of cv)) cvs |
142 fun dest (Free (n, _)) = n |
143 val vs = map (Term.dest_Free o Thm.term_of) cvs' |
143 | dest _ = no_name |
144 in (Term.list_abs_free (vs, t), cvs') end |
144 |
|
145 fun gen vs (t as Free (n, _)) = |
|
146 let val i = find_index (equal n) vs |
|
147 in |
|
148 if i >= 0 then insert (op aconvc) (nth cvs i) #> pair (Bound i) |
|
149 else pair t |
|
150 end |
|
151 | gen vs (t $ u) = gen vs t ##>> gen vs u #>> (op $) |
|
152 | gen vs (Abs (n, T, t)) = |
|
153 gen (no_name :: vs) t #>> (fn u => Abs (n, T, u)) |
|
154 | gen _ t = pair t |
|
155 |
|
156 in (fn ct => gen (map (dest o Thm.term_of) cvs) (Thm.term_of ct) []) end |
|
157 |
145 |
158 fun fresh_abstraction cvs ct (cx as (ctxt, tab, idx, beta_norm)) = |
146 fun fresh_abstraction cvs ct (cx as (ctxt, tab, idx, beta_norm)) = |
159 let val (t, cvs') = generalize cvs ct |
147 let val (t, cvs') = lambda_abstract cvs (Thm.term_of ct) |
160 in |
148 in |
161 (case Termtab.lookup tab t of |
149 (case Termtab.lookup tab t of |
162 SOME (cv, _) => (cv, cx) |
150 SOME (cv, _) => (Drule.list_comb (cv, cvs'), cx) |
163 | NONE => |
151 | NONE => |
164 let |
152 let |
165 val (n, ctxt') = yield_singleton Variable.variant_fixes "x" ctxt |
153 val (n, ctxt') = yield_singleton Variable.variant_fixes "x" ctxt |
166 val cv = certify ctxt (Free (n, map typ_of cvs' ---> typ_of ct)) |
154 val cv = certify ctxt' (Free (n, map typ_of cvs' ---> typ_of ct)) |
167 val cv' = Drule.list_comb (cv, cvs') |
155 val cu = Drule.list_comb (cv, cvs') |
168 val e = (t, (cv, fold_rev Thm.cabs cvs' ct)) |
156 val e = (t, (cv, fold_rev Thm.cabs cvs' ct)) |
169 val beta_norm' = beta_norm orelse not (null cvs') |
157 val beta_norm' = beta_norm orelse not (null cvs') |
170 in (cv', (ctxt', Termtab.update e tab, idx + 1, beta_norm')) end) |
158 in (cu, (ctxt', Termtab.update e tab, idx + 1, beta_norm')) end) |
171 end |
159 end |
172 |
|
173 fun abs_arg f cvs ct = |
|
174 let val (cf, cu) = Thm.dest_comb ct |
|
175 in f cvs cu #>> Thm.capply cf end |
|
176 |
160 |
177 fun abs_comb f g cvs ct = |
161 fun abs_comb f g cvs ct = |
178 let val (cf, cu) = Thm.dest_comb ct |
162 let val (cf, cu) = Thm.dest_comb ct |
179 in f cvs cf ##>> g cvs cu #>> uncurry Thm.capply end |
163 in f cvs cf ##>> g cvs cu #>> uncurry Thm.capply end |
|
164 |
|
165 fun abs_arg f = abs_comb (K pair) f |
|
166 |
|
167 fun abs_args f cvs ct = |
|
168 (case Thm.term_of ct of |
|
169 _ $ _ => abs_comb (abs_args f) f cvs ct |
|
170 | _ => pair ct) |
180 |
171 |
181 fun abs_list f g cvs ct = |
172 fun abs_list f g cvs ct = |
182 (case Thm.term_of ct of |
173 (case Thm.term_of ct of |
183 Const (@{const_name Nil}, _) => pair ct |
174 Const (@{const_name Nil}, _) => pair ct |
184 | Const (@{const_name Cons}, _) $ _ $ _ => |
175 | Const (@{const_name Cons}, _) $ _ $ _ => |
188 fun abs_abs f cvs ct = |
179 fun abs_abs f cvs ct = |
189 let val (cv, cu) = Thm.dest_abs NONE ct |
180 let val (cv, cu) = Thm.dest_abs NONE ct |
190 in f (cv :: cvs) cu #>> Thm.cabs cv end |
181 in f (cv :: cvs) cu #>> Thm.cabs cv end |
191 |
182 |
192 val is_atomic = (fn _ $ _ => false | Abs _ => false | _ => true) |
183 val is_atomic = (fn _ $ _ => false | Abs _ => false | _ => true) |
193 val is_arithT = (fn @{typ int} => true | @{typ real} => true | _ => false) |
|
194 fun is_number t = |
|
195 (case try HOLogic.dest_number t of |
|
196 SOME (T, _) => is_arithT T |
|
197 | NONE => false) |
|
198 |
184 |
199 fun abstract (ext_logic, with_theories) = |
185 fun abstract (ext_logic, with_theories) = |
200 let |
186 let |
201 fun abstr1 cvs ct = abs_arg abstr cvs ct |
187 fun abstr1 cvs ct = abs_arg abstr cvs ct |
202 and abstr2 cvs ct = abs_comb abstr1 abstr cvs ct |
188 and abstr2 cvs ct = abs_comb abstr1 abstr cvs ct |
221 if ext_logic then abstr3 cvs ct else fresh_abstraction cvs ct |
207 if ext_logic then abstr3 cvs ct else fresh_abstraction cvs ct |
222 | Const (@{const_name All}, _) $ _ => |
208 | Const (@{const_name All}, _) $ _ => |
223 if ext_logic then abstr_abs cvs ct else fresh_abstraction cvs ct |
209 if ext_logic then abstr_abs cvs ct else fresh_abstraction cvs ct |
224 | Const (@{const_name Ex}, _) $ _ => |
210 | Const (@{const_name Ex}, _) $ _ => |
225 if ext_logic then abstr_abs cvs ct else fresh_abstraction cvs ct |
211 if ext_logic then abstr_abs cvs ct else fresh_abstraction cvs ct |
226 | @{term "uminus :: int => _"} $ _ => abstr1 cvs ct |
212 | t => (fn cx => |
227 | @{term "uminus :: real => _"} $ _ => abstr1 cvs ct |
213 if is_atomic t orelse can HOLogic.dest_number t then (ct, cx) |
228 | @{term "op + :: int => _"} $ _ $ _ => abstr2 cvs ct |
214 else if with_theories andalso |
229 | @{term "op + :: real => _"} $ _ $ _ => abstr2 cvs ct |
215 I.is_builtin_theory_term (context_of cx) t |
230 | @{term "op - :: int => _"} $ _ $ _ => abstr2 cvs ct |
216 then abs_args abstr cvs ct cx |
231 | @{term "op - :: real => _"} $ _ $ _ => abstr2 cvs ct |
217 else fresh_abstraction cvs ct cx)) |
232 | @{term "op * :: int => _"} $ _ $ _ => abstr2 cvs ct |
|
233 | @{term "op * :: real => _"} $ _ $ _ => abstr2 cvs ct |
|
234 | @{term "op div :: int => _"} $ _ $ _ => abstr2 cvs ct |
|
235 | @{term "op mod :: int => _"} $ _ $ _ => abstr2 cvs ct |
|
236 | @{term "op / :: real => _"} $ _ $ _ => abstr2 cvs ct |
|
237 | @{term "op < :: int => _"} $ _ $ _ => abstr2 cvs ct |
|
238 | @{term "op < :: real => _"} $ _ $ _ => abstr2 cvs ct |
|
239 | @{term "op <= :: int => _"} $ _ $ _ => abstr2 cvs ct |
|
240 | @{term "op <= :: real => _"} $ _ $ _ => abstr2 cvs ct |
|
241 | Const (@{const_name apply}, _) $ _ $ _ => abstr2 cvs ct |
|
242 | Const (@{const_name fun_upd}, _) $ _ $ _ $ _ => abstr3 cvs ct |
|
243 | t => |
|
244 if is_atomic t orelse is_number t then pair ct |
|
245 else fresh_abstraction cvs ct) |
|
246 in abstr [] end |
218 in abstr [] end |
247 |
219 |
248 fun with_prems thms f ct = |
220 fun with_prems thms f ct = |
249 fold_rev (Thm.mk_binop @{cterm "op ==>"} o Thm.cprop_of) thms ct |
221 fold_rev (Thm.mk_binop @{cterm "op ==>"} o Thm.cprop_of) thms ct |
250 |> f |
222 |> f |
251 |> fold (fn prem => fn th => Thm.implies_elim th prem) thms |
223 |> fold (fn prem => fn th => Thm.implies_elim th prem) thms |
252 |
224 |
253 in |
225 in |
254 |
226 |
255 fun by_abstraction ctxt thms prove = with_prems thms (fn ct => |
227 fun by_abstraction mode ctxt thms prove = with_prems thms (fn ct => |
256 let val (cu, cx) = abstract (true, true) ct (abs_context ctxt) |
228 let val (cu, cx) = abstract mode ct (abs_context ctxt) |
257 in abs_instantiate cx (prove (context_of cx) cu) end) |
229 in abs_instantiate cx (prove (context_of cx) cu) end) |
258 |
230 |
259 end |
231 end |
260 |
232 |
261 |
233 |
338 find_first (eq_prop (HOLogic.mk_not (less $ s $ r))) prems |
310 find_first (eq_prop (HOLogic.mk_not (less $ s $ r))) prems |
339 |> Option.map (fn thm => thm RS antisym_less2) |
311 |> Option.map (fn thm => thm RS antisym_less2) |
340 | SOME thm => SOME (thm RS antisym_le2)) |
312 | SOME thm => SOME (thm RS antisym_le2)) |
341 end |
313 end |
342 handle THM _ => NONE |
314 handle THM _ => NONE |
|
315 |
|
316 val basic_simpset = HOL_ss addsimps @{thms field_simps} |
|
317 addsimps [@{thm times_divide_eq_right}, @{thm times_divide_eq_left}] |
|
318 addsimps @{thms arith_special} addsimps @{thms less_bin_simps} |
|
319 addsimps @{thms le_bin_simps} addsimps @{thms eq_bin_simps} |
|
320 addsimps @{thms add_bin_simps} addsimps @{thms succ_bin_simps} |
|
321 addsimps @{thms minus_bin_simps} addsimps @{thms pred_bin_simps} |
|
322 addsimps @{thms mult_bin_simps} addsimps @{thms iszero_simps} |
|
323 addsimps @{thms array_rules} |
|
324 addsimprocs [ |
|
325 Simplifier.simproc @{theory} "fast_int_arith" [ |
|
326 "(m::int) < n", "(m::int) <= n", "(m::int) = n"] (K Lin_Arith.simproc), |
|
327 Simplifier.simproc @{theory} "antisym_le" ["(x::'a::order) <= y"] |
|
328 (K prove_antisym_le), |
|
329 Simplifier.simproc @{theory} "antisym_less" ["~ (x::'a::linorder) < y"] |
|
330 (K prove_antisym_less)] |
|
331 |
|
332 structure Simpset = Generic_Data |
|
333 ( |
|
334 type T = simpset |
|
335 val empty = basic_simpset |
|
336 val extend = I |
|
337 val merge = Simplifier.merge_ss |
|
338 ) |
343 in |
339 in |
344 |
340 |
345 fun make_simpset ctxt rules = Simplifier.context ctxt (HOL_ss |
341 fun add_simproc simproc = Simpset.map (fn ss => ss addsimprocs [simproc]) |
346 addsimps @{thms field_simps} |
342 |
347 addsimps [@{thm times_divide_eq_right}, @{thm times_divide_eq_left}] |
343 fun make_simpset ctxt rules = |
348 addsimps @{thms arith_special} addsimps @{thms less_bin_simps} |
344 Simplifier.context ctxt (Simpset.get (Context.Proof ctxt)) addsimps rules |
349 addsimps @{thms le_bin_simps} addsimps @{thms eq_bin_simps} |
345 |
350 addsimps @{thms add_bin_simps} addsimps @{thms succ_bin_simps} |
346 end |
351 addsimps @{thms minus_bin_simps} addsimps @{thms pred_bin_simps} |
347 |
352 addsimps @{thms mult_bin_simps} addsimps @{thms iszero_simps} |
348 end |
353 addsimps @{thms array_rules} |
|
354 addsimprocs [ |
|
355 Simplifier.simproc @{theory} "fast_int_arith" [ |
|
356 "(m::int) < n", "(m::int) <= n", "(m::int) = n"] (K Lin_Arith.simproc), |
|
357 Simplifier.simproc @{theory} "fast_real_arith" [ |
|
358 "(m::real) < n", "(m::real) <= n", "(m::real) = n"] |
|
359 (K Lin_Arith.simproc), |
|
360 Simplifier.simproc @{theory} "antisym_le" ["(x::'a::order) <= y"] |
|
361 (K prove_antisym_le), |
|
362 Simplifier.simproc @{theory} "antisym_less" ["~ (x::'a::linorder) < y"] |
|
363 (K prove_antisym_less)] |
|
364 addsimps rules) |
|
365 |
|
366 end |
|
367 |
|
368 end |
|