1 signature QUOTIENT_TACS = |
1 signature QUOTIENT_TACS = |
2 sig |
2 sig |
3 val regularize_tac: Proof.context -> int -> tactic |
3 val regularize_tac: Proof.context -> int -> tactic |
4 val injection_tac: Proof.context -> int -> tactic |
4 val injection_tac: Proof.context -> int -> tactic |
5 val all_injection_tac: Proof.context -> int -> tactic |
5 val all_injection_tac: Proof.context -> int -> tactic |
6 val clean_tac: Proof.context -> int -> tactic |
6 val clean_tac: Proof.context -> int -> tactic |
7 val procedure_tac: Proof.context -> thm -> int -> tactic |
7 val procedure_tac: Proof.context -> thm -> int -> tactic |
8 val lift_tac: Proof.context -> thm -> int -> tactic |
8 val lift_tac: Proof.context -> thm -> int -> tactic |
9 val quotient_tac: Proof.context -> int -> tactic |
9 val quotient_tac: Proof.context -> int -> tactic |
10 val quot_true_tac: Proof.context -> (term -> term) -> int -> tactic |
10 val quot_true_tac: Proof.context -> (term -> term) -> int -> tactic |
11 end; |
11 end; |
12 |
12 |
13 structure Quotient_Tacs: QUOTIENT_TACS = |
13 structure Quotient_Tacs: QUOTIENT_TACS = |
14 struct |
14 struct |
15 |
15 |
16 open Quotient_Info; |
16 open Quotient_Info; |
17 open Quotient_Term; |
17 open Quotient_Term; |
18 |
18 |
19 (* various helper fuctions *) |
19 |
|
20 (** various helper fuctions **) |
20 |
21 |
21 (* Since HOL_basic_ss is too "big" for us, we *) |
22 (* Since HOL_basic_ss is too "big" for us, we *) |
22 (* need to set up our own minimal simpset. *) |
23 (* need to set up our own minimal simpset. *) |
23 fun mk_minimal_ss ctxt = |
24 fun mk_minimal_ss ctxt = |
24 Simplifier.context ctxt empty_ss |
25 Simplifier.context ctxt empty_ss |
46 in |
47 in |
47 @{thm equal_elim_rule1} OF [thm'', thm'] |
48 @{thm equal_elim_rule1} OF [thm'', thm'] |
48 end |
49 end |
49 |
50 |
50 |
51 |
51 (*********************) |
52 |
52 (* Regularize Tactic *) |
53 (*** Regularize Tactic ***) |
53 (*********************) |
54 |
54 |
55 (** solvers for equivp and quotient assumptions **) |
55 (* solvers for equivp and quotient assumptions *) |
56 |
56 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *) |
57 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *) |
57 (* FIXME / TODO: none of te examples break if added *) |
58 (* FIXME / TODO: none of te examples break if added *) |
58 fun equiv_tac ctxt = |
59 fun equiv_tac ctxt = |
59 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
60 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
60 |
61 |
61 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
62 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
62 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
63 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
63 |
64 |
64 (* FIXME / TODO: test whether DETERM makes any runtime-difference *) |
65 (* FIXME / TODO: test whether DETERM makes any runtime-difference *) |
65 (* FIXME / TODO: reason: the tactic might back-track over the two alternatives in FIRST' *) |
66 (* FIXME / TODO: reason: the tactic might back-track over the two alternatives in FIRST' *) |
66 fun quotient_tac ctxt = SOLVES' |
67 fun quotient_tac ctxt = SOLVES' |
67 (REPEAT_ALL_NEW (FIRST' |
68 (REPEAT_ALL_NEW (FIRST' |
68 [rtac @{thm identity_quotient}, |
69 [rtac @{thm identity_quotient}, |
69 resolve_tac (quotient_rules_get ctxt)])) |
70 resolve_tac (quotient_rules_get ctxt)])) |
70 |
71 |
71 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
72 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
72 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
73 val quotient_solver = |
|
74 Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
73 |
75 |
74 fun solve_quotient_assm ctxt thm = |
76 fun solve_quotient_assm ctxt thm = |
75 case Seq.pull (quotient_tac ctxt 1 thm) of |
77 case Seq.pull (quotient_tac ctxt 1 thm) of |
76 SOME (t, _) => t |
78 SOME (t, _) => t |
77 | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing." |
79 | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing." |
128 calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
130 calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
129 |
131 |
130 | _ => NONE |
132 | _ => NONE |
131 end |
133 end |
132 |
134 |
133 (* 0. preliminary simplification step according to *) |
135 (* |
134 (* thm ball_reg_eqv bex_reg_eqv babs_reg_eqv *) |
136 0. preliminary simplification step according to |
135 (* ball_reg_eqv_range bex_reg_eqv_range *) |
137 ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range |
136 (* *) |
138 |
137 (* 1. eliminating simple Ball/Bex instances *) |
139 1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left) |
138 (* thm ball_reg_right bex_reg_left *) |
140 |
139 (* *) |
141 2. monos |
140 (* 2. monos *) |
142 |
141 (* *) |
143 3. commutation rules for ball and bex (ball_all_comm bex_ex_comm) |
142 (* 3. commutation rules for ball and bex *) |
144 |
143 (* thm ball_all_comm bex_ex_comm *) |
145 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel' |
144 (* *) |
146 to avoid loops |
145 (* 4. then rel-equalities, which need to be *) |
147 |
146 (* instantiated with the followig theorem *) |
148 5. then simplification like 0 |
147 (* to avoid loops: *) |
149 |
148 (* thm eq_imp_rel *) |
150 finally jump back to 1 *) |
149 (* *) |
|
150 (* 5. then simplification like 0 *) |
|
151 (* *) |
|
152 (* finally jump back to 1 *) |
|
153 |
|
154 fun regularize_tac ctxt = |
151 fun regularize_tac ctxt = |
155 let |
152 let |
156 val thy = ProofContext.theory_of ctxt |
153 val thy = ProofContext.theory_of ctxt |
157 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
154 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
158 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
155 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
159 val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc)) |
156 val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc)) |
160 val simpset = (mk_minimal_ss ctxt) |
157 val simpset = (mk_minimal_ss ctxt) |
161 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp} @ (id_simps_get ctxt) |
158 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp} |
162 addsimprocs [simproc] |
159 addsimprocs [simproc] |
163 addSolver equiv_solver addSolver quotient_solver |
160 addSolver equiv_solver addSolver quotient_solver |
164 val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt) |
161 val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt) |
165 in |
162 in |
166 simp_tac simpset THEN' |
163 simp_tac simpset THEN' |
230 fun dest_fun_type (Type("fun", [T, S])) = (T, S) |
226 fun dest_fun_type (Type("fun", [T, S])) = (T, S) |
231 | dest_fun_type _ = error "dest_fun_type" |
227 | dest_fun_type _ = error "dest_fun_type" |
232 |
228 |
233 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
229 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
234 |
230 |
235 (* We apply apply_rsp only in case if the type needs lifting. *) |
231 (* We apply apply_rsp only in case if the type needs lifting. |
236 (* This is the case if the type of the data in the Quot_True *) |
232 This is the case if the type of the data in the Quot_True |
237 (* assumption is different from the corresponding type in the goal. *) |
233 assumption is different from the corresponding type in the goal. *) |
238 val apply_rsp_tac = |
234 val apply_rsp_tac = |
239 Subgoal.FOCUS (fn {concl, asms, context,...} => |
235 Subgoal.FOCUS (fn {concl, asms, context,...} => |
240 let |
236 let |
241 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
237 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
242 val qt_asm = find_qt_asm (map term_of asms) |
238 val qt_asm = find_qt_asm (map term_of asms) |
243 in |
239 in |
244 case (bare_concl, qt_asm) of |
240 case (bare_concl, qt_asm) of |
245 (R2 $ (f $ x) $ (g $ y), SOME (qt_fun, qt_arg)) => |
241 (R2 $ (f $ x) $ (g $ y), SOME (qt_fun, qt_arg)) => |
246 if (fastype_of qt_fun) = (fastype_of f) |
242 if (fastype_of qt_fun) = (fastype_of f) |
247 then no_tac |
243 then no_tac |
248 else |
244 else |
249 let |
245 let |
250 val ty_x = fastype_of x |
246 val ty_x = fastype_of x |
251 val ty_b = fastype_of qt_arg |
247 val ty_b = fastype_of qt_arg |
252 val ty_f = range_type (fastype_of f) |
248 val ty_f = range_type (fastype_of f) |
253 val thy = ProofContext.theory_of context |
249 val thy = ProofContext.theory_of context |
254 val ty_inst = map (SOME o (ctyp_of thy)) [ty_x, ty_b, ty_f] |
250 val ty_inst = map (SOME o (ctyp_of thy)) [ty_x, ty_b, ty_f] |
255 val t_inst = map (SOME o (cterm_of thy)) [R2, f, g, x, y]; |
251 val t_inst = map (SOME o (cterm_of thy)) [R2, f, g, x, y]; |
256 val inst_thm = Drule.instantiate' ty_inst ([NONE, NONE, NONE] @ t_inst) @{thm apply_rsp} |
252 val inst_thm = Drule.instantiate' ty_inst |
|
253 ([NONE, NONE, NONE] @ t_inst) @{thm apply_rsp} |
257 in |
254 in |
258 (rtac inst_thm THEN' quotient_tac context) 1 |
255 (rtac inst_thm THEN' quotient_tac context) 1 |
259 end |
256 end |
260 | _ => no_tac |
257 | _ => no_tac |
261 end) |
258 end) |
279 | _ => K no_tac |
276 | _ => K no_tac |
280 end |
277 end |
281 (* TODO: Again, can one specify more concretely *) |
278 (* TODO: Again, can one specify more concretely *) |
282 (* TODO: in terms of R when no_tac should be returned? *) |
279 (* TODO: in terms of R when no_tac should be returned? *) |
283 |
280 |
284 fun rep_abs_rsp_tac ctxt = |
281 fun rep_abs_rsp_tac ctxt = |
285 SUBGOAL (fn (goal, i) => |
282 SUBGOAL (fn (goal, i) => |
286 case (bare_concl goal) of |
283 case (try bare_concl goal) of |
287 (rel $ _ $ (rep $ (abs $ _))) => |
284 SOME (rel $ _ $ (rep $ (abs $ _))) => |
288 (let |
285 let |
289 val thy = ProofContext.theory_of ctxt; |
286 val thy = ProofContext.theory_of ctxt; |
290 val (ty_a, ty_b) = dest_fun_type (fastype_of abs); |
287 val (ty_a, ty_b) = dest_fun_type (fastype_of abs); |
291 val ty_inst = map (SOME o (ctyp_of thy)) [ty_a, ty_b]; |
288 val ty_inst = map (SOME o (ctyp_of thy)) [ty_a, ty_b]; |
292 val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep]; |
289 in |
293 val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp} |
290 case try (map (SOME o (cterm_of thy))) [rel, abs, rep] of |
294 in |
291 SOME t_inst => |
295 (rtac inst_thm THEN' quotient_tac ctxt) i |
292 (case try (Drule.instantiate' ty_inst t_inst) @{thm rep_abs_rsp} of |
296 end |
293 SOME inst_thm => (rtac inst_thm THEN' quotient_tac ctxt) i |
297 handle THM _ => no_tac | TYPE _ => no_tac) (* TODO: same here *) |
294 | NONE => no_tac) |
|
295 | NONE => no_tac |
|
296 end |
298 | _ => no_tac) |
297 | _ => no_tac) |
299 |
298 |
300 |
299 |
301 (* FIXME / TODO needs to be adapted *) |
|
302 (* |
300 (* |
303 To prove that the regularised theorem implies the abs/rep injected, |
301 To prove that the regularised theorem implies the abs/rep injected, |
304 we try: |
302 we try: |
305 |
303 |
306 1) theorems 'trans2' from the appropriate Quot_Type |
304 The deterministic part: |
307 2) remove lambdas from both sides: lambda_rsp_tac |
305 -) remove lambdas from both sides |
308 3) remove Ball/Bex from the right hand side |
306 -) prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp |
309 4) use user-supplied RSP theorems |
307 -) prove Ball/Bex relations unfolding fun_rel_id |
310 5) remove rep_abs from the right side |
308 -) reflexivity of equality |
311 6) reflexivity of equality |
309 -) prove equality of relations using equals_rsp |
312 7) split applications of lifted type (apply_rsp) |
310 -) use user-supplied RSP theorems |
313 8) split applications of non-lifted type (cong_tac) |
311 -) solve 'relation of relations' goals using quot_rel_rsp |
314 9) apply extentionality |
312 -) remove rep_abs from the right side |
315 A) reflexivity of the relation |
|
316 B) assumption |
|
317 (Lambdas under respects may have left us some assumptions) |
313 (Lambdas under respects may have left us some assumptions) |
318 C) proving obvious higher order equalities by simplifying fun_rel |
314 Then in order: |
319 (not sure if it is still needed?) |
315 -) split applications of lifted type (apply_rsp) |
320 D) unfolding lambda on one side |
316 -) split applications of non-lifted type (cong_tac) |
321 E) simplifying (= ===> =) for simpler respectfulness |
317 -) apply extentionality |
|
318 -) assumption |
|
319 -) reflexivity of the relation |
322 *) |
320 *) |
323 |
321 |
324 |
322 |
325 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) => |
323 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) => |
326 (case (bare_concl goal) of |
324 (case (bare_concl goal) of |
380 |
378 |
381 fun injection_step_tac ctxt rel_refl = |
379 fun injection_step_tac ctxt rel_refl = |
382 FIRST' [ |
380 FIRST' [ |
383 injection_match_tac ctxt, |
381 injection_match_tac ctxt, |
384 |
382 |
385 (* R (t $ ...) (t' $ ...) ----> apply_rsp provided type of t needs lifting *) |
383 (* R (t $ ...) (t' $ ...) ----> apply_rsp provided type of t needs lifting *) |
386 apply_rsp_tac ctxt THEN' |
384 apply_rsp_tac ctxt THEN' |
387 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
385 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
388 |
386 |
389 (* (op =) (t $ ...) (t' $ ...) ----> Cong provided type of t does not need lifting *) |
387 (* (op =) (t $ ...) (t' $ ...) ----> Cong provided type of t does not need lifting *) |
390 (* merge with previous tactic *) |
388 (* merge with previous tactic *) |
391 Cong_Tac.cong_tac @{thm cong} THEN' |
389 Cong_Tac.cong_tac @{thm cong} THEN' |
392 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
390 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
393 |
391 |
394 (* (op =) (%x...) (%y...) ----> (op =) (...) (...) *) |
392 (* (op =) (%x...) (%y...) ----> (op =) (...) (...) *) |
395 rtac @{thm ext} THEN' quot_true_tac ctxt unlam, |
393 rtac @{thm ext} THEN' quot_true_tac ctxt unlam, |
396 |
394 |
397 (* resolving with R x y assumptions *) |
395 (* resolving with R x y assumptions *) |
398 atac, |
396 atac, |
399 |
397 |
400 (* reflexivity of the basic relations *) |
398 (* reflexivity of the basic relations *) |
401 (* R ... ... *) |
399 (* R ... ... *) |
402 resolve_tac rel_refl] |
400 resolve_tac rel_refl] |
403 |
401 |
404 fun injection_tac ctxt = |
402 fun injection_tac ctxt = |
405 let |
403 let |
406 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
404 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
407 in |
405 in |
408 simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) |
406 injection_step_tac ctxt rel_refl |
409 THEN' injection_step_tac ctxt rel_refl |
|
410 end |
407 end |
411 |
408 |
412 fun all_injection_tac ctxt = |
409 fun all_injection_tac ctxt = |
413 REPEAT_ALL_NEW (injection_tac ctxt) |
410 REPEAT_ALL_NEW (injection_tac ctxt) |
414 |
411 |
415 |
412 |
416 (***************************) |
413 |
417 (* Cleaning of the Theorem *) |
414 (** Cleaning of the Theorem **) |
418 (***************************) |
415 |
419 |
416 (* expands all fun_maps, except in front of the bound variables listed in xs *) |
420 (* expands all fun_maps, except in front of the bound *) |
|
421 (* variables listed in xs *) |
|
422 fun fun_map_simple_conv xs ctrm = |
417 fun fun_map_simple_conv xs ctrm = |
423 case (term_of ctrm) of |
418 case (term_of ctrm) of |
424 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
419 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
425 if (member (op=) xs h) |
420 if (member (op=) xs h) |
426 then Conv.all_conv ctrm |
421 then Conv.all_conv ctrm |
427 else Conv.rewr_conv @{thm fun_map.simps[THEN eq_reflection]} ctrm |
422 else Conv.rewr_conv @{thm fun_map.simps[THEN eq_reflection]} ctrm |
428 | _ => Conv.all_conv ctrm |
423 | _ => Conv.all_conv ctrm |
429 |
424 |
430 fun fun_map_conv xs ctxt ctrm = |
425 fun fun_map_conv xs ctxt ctrm = |
459 val _ $ (Abs (_, _, g)) = t; |
454 val _ $ (Abs (_, _, g)) = t; |
460 in |
455 in |
461 (f, Abs ("x", T, mk_abs u 0 g)) |
456 (f, Abs ("x", T, mk_abs u 0 g)) |
462 end |
457 end |
463 |
458 |
464 (* Simplifies a redex using the 'lambda_prs' theorem. *) |
459 (* Simplifies a redex using the 'lambda_prs' theorem. |
465 (* First instantiates the types and known subterms. *) |
460 First instantiates the types and known subterms. |
466 (* Then solves the quotient assumptions to get Rep2 and Abs1 *) |
461 Then solves the quotient assumptions to get Rep2 and Abs1 |
467 (* Finally instantiates the function f using make_inst *) |
462 Finally instantiates the function f using make_inst |
468 (* If Rep2 is an identity then the pattern is simpler and *) |
463 If Rep2 is an identity then the pattern is simpler and |
469 (* make_inst_id is used *) |
464 make_inst_id is used *) |
470 fun lambda_prs_simple_conv ctxt ctrm = |
465 fun lambda_prs_simple_conv ctxt ctrm = |
471 case (term_of ctrm) of |
466 case (term_of ctrm) of |
472 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
467 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
473 (let |
468 let |
474 val thy = ProofContext.theory_of ctxt |
469 val thy = ProofContext.theory_of ctxt |
475 val (ty_b, ty_a) = dest_fun_type (fastype_of r1) |
470 val (ty_b, ty_a) = dest_fun_type (fastype_of r1) |
476 val (ty_c, ty_d) = dest_fun_type (fastype_of a2) |
471 val (ty_c, ty_d) = dest_fun_type (fastype_of a2) |
477 val tyinst = map (SOME o (ctyp_of thy)) [ty_a, ty_b, ty_c, ty_d] |
472 val tyinst = map (SOME o (ctyp_of thy)) [ty_a, ty_b, ty_c, ty_d] |
478 val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)] |
473 val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)] |
479 val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs[THEN eq_reflection]} |
474 val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs[THEN eq_reflection]} |
480 val te = solve_quotient_assm ctxt (solve_quotient_assm ctxt lpi) |
475 val te = solve_quotient_assm ctxt (solve_quotient_assm ctxt lpi) |
481 val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te |
476 val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te |
482 val (insp, inst) = |
477 val (insp, inst) = |
483 if ty_c = ty_d |
478 if ty_c = ty_d |
484 then make_inst_id (term_of (Thm.lhs_of ts)) (term_of ctrm) |
479 then make_inst_id (term_of (Thm.lhs_of ts)) (term_of ctrm) |
485 else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
480 else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
486 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
481 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
487 in |
482 in |
488 Conv.rewr_conv ti ctrm |
483 Conv.rewr_conv ti ctrm |
489 end |
484 end |
490 handle _ => Conv.all_conv ctrm) (* TODO: another catch all - can this be improved? *) |
|
491 | _ => Conv.all_conv ctrm |
485 | _ => Conv.all_conv ctrm |
492 |
|
493 |
486 |
494 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
487 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
495 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
488 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
496 |
489 |
497 |
490 |
498 (* 1. folding of definitions and preservation lemmas; *) |
491 (* Cleaning consists of: |
499 (* and simplification with *) |
492 1. folding of definitions and preservation lemmas; |
500 (* thm babs_prs all_prs ex_prs *) |
493 and simplification with babs_prs all_prs ex_prs |
501 (* *) |
494 |
502 (* 2. unfolding of ---> in front of everything, except *) |
495 2. unfolding of ---> in front of everything, except |
503 (* bound variables (this prevents lambda_prs from *) |
496 bound variables |
504 (* becoming stuck) *) |
497 (this prevents lambda_prs from becoming stuck) |
505 (* thm fun_map.simps *) |
498 |
506 (* *) |
499 3. simplification with lambda_prs |
507 (* 3. simplification with *) |
500 |
508 (* thm lambda_prs *) |
501 4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps |
509 (* *) |
502 |
510 (* 4. simplification with *) |
503 5. test for refl *) |
511 (* thm Quotient_abs_rep Quotient_rel_rep id_simps *) |
504 fun clean_tac lthy = |
512 (* *) |
|
513 (* 5. test for refl *) |
|
514 |
|
515 fun clean_tac_aux lthy = |
|
516 let |
505 let |
517 (* FIXME/TODO produce defs with lthy, like prs and ids *) |
506 (* FIXME/TODO produce defs with lthy, like prs and ids *) |
518 val thy = ProofContext.theory_of lthy; |
507 val thy = ProofContext.theory_of lthy; |
519 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
508 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
520 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
509 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
521 val prs = prs_rules_get lthy |
510 val prs = prs_rules_get lthy |
522 val ids = id_simps_get lthy |
511 val ids = id_simps_get lthy |
523 |
512 |
524 fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
513 fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
525 val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs}) |
514 val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs}) |
526 val ss2 = mk_simps (@{thms Quotient_abs_rep Quotient_rel_rep} @ ids) |
515 val ss2 = mk_simps (@{thms Quotient_abs_rep Quotient_rel_rep} @ ids) |
527 in |
516 in |
528 EVERY' [simp_tac ss1, |
517 EVERY' [simp_tac ss1, |
529 fun_map_tac lthy, |
518 fun_map_tac lthy, |
530 lambda_prs_tac lthy, |
519 lambda_prs_tac lthy, |
531 simp_tac ss2, |
520 simp_tac ss2, |
532 TRY o rtac refl] |
521 TRY o rtac refl] |
533 end |
522 end |
534 |
523 |
535 fun clean_tac lthy = REPEAT o CHANGED o (clean_tac_aux lthy) (* HACK?? *) |
524 |
536 |
525 |
537 |
526 (** Tactic for Generalising Free Variables in a Goal **) |
538 (****************************************************) |
527 |
539 (* Tactic for Generalising Free Variables in a Goal *) |
|
540 (****************************************************) |
|
541 |
528 |
542 fun inst_spec ctrm = |
529 fun inst_spec ctrm = |
543 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
530 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
544 |
531 |
545 fun inst_spec_tac ctrms = |
532 fun inst_spec_tac ctrms = |
550 |
537 |
551 fun apply_under_Trueprop f = |
538 fun apply_under_Trueprop f = |
552 HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop |
539 HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop |
553 |
540 |
554 fun gen_frees_tac ctxt = |
541 fun gen_frees_tac ctxt = |
555 SUBGOAL (fn (concl, i) => |
542 SUBGOAL (fn (concl, i) => |
556 let |
543 let |
557 val thy = ProofContext.theory_of ctxt |
544 val thy = ProofContext.theory_of ctxt |
558 val vrs = Term.add_frees concl [] |
545 val vrs = Term.add_frees concl [] |
559 val cvrs = map (cterm_of thy o Free) vrs |
546 val cvrs = map (cterm_of thy o Free) vrs |
560 val concl' = apply_under_Trueprop (all_list vrs) concl |
547 val concl' = apply_under_Trueprop (all_list vrs) concl |
561 val goal = Logic.mk_implies (concl', concl) |
548 val goal = Logic.mk_implies (concl', concl) |
562 val rule = Goal.prove ctxt [] [] goal |
549 val rule = Goal.prove ctxt [] [] goal |
563 (K (EVERY1 [inst_spec_tac (rev cvrs), atac])) |
550 (K (EVERY1 [inst_spec_tac (rev cvrs), atac])) |
564 in |
551 in |
565 rtac rule i |
552 rtac rule i |
566 end) |
553 end) |
567 |
554 |
568 (**********************************************) |
555 |
569 (* The General Shape of the Lifting Procedure *) |
556 (** The General Shape of the Lifting Procedure **) |
570 (**********************************************) |
557 |
571 |
558 |
572 (* - A is the original raw theorem *) |
559 (* - A is the original raw theorem |
573 (* - B is the regularized theorem *) |
560 - B is the regularized theorem |
574 (* - C is the rep/abs injected version of B *) |
561 - C is the rep/abs injected version of B |
575 (* - D is the lifted theorem *) |
562 - D is the lifted theorem |
576 (* *) |
563 |
577 (* - 1st prem is the regularization step *) |
564 - 1st prem is the regularization step |
578 (* - 2nd prem is the rep/abs injection step *) |
565 - 2nd prem is the rep/abs injection step |
579 (* - 3rd prem is the cleaning part *) |
566 - 3rd prem is the cleaning part |
580 (* *) |
567 |
581 (* the Quot_True premise in 2nd records the lifted theorem *) |
568 the Quot_True premise in 2nd records the lifted theorem *) |
582 |
569 val lifting_procedure_thm = |
583 val lifting_procedure_thm = |
570 @{lemma "[|A; |
584 @{lemma "[|A; |
571 A --> B; |
585 A --> B; |
572 Quot_True D ==> B = C; |
586 Quot_True D ==> B = C; |
573 C = D|] ==> D" |
587 C = D|] ==> D" |
|
588 by (simp add: Quot_True_def)} |
574 by (simp add: Quot_True_def)} |
589 |
575 |
590 fun lift_match_error ctxt str rtrm qtrm = |
576 fun lift_match_error ctxt str rtrm qtrm = |
591 let |
577 let |
592 val rtrm_str = Syntax.string_of_term ctxt rtrm |
578 val rtrm_str = Syntax.string_of_term ctxt rtrm |
593 val qtrm_str = Syntax.string_of_term ctxt qtrm |
579 val qtrm_str = Syntax.string_of_term ctxt qtrm |
594 val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, |
580 val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, |
595 "", "does not match with original theorem", rtrm_str] |
581 "", "does not match with original theorem", rtrm_str] |
596 in |
582 in |
597 error msg |
583 error msg |
598 end |
584 end |
599 |
585 |
600 fun procedure_inst ctxt rtrm qtrm = |
586 fun procedure_inst ctxt rtrm qtrm = |
601 let |
587 let |
602 val thy = ProofContext.theory_of ctxt |
588 val thy = ProofContext.theory_of ctxt |
603 val rtrm' = HOLogic.dest_Trueprop rtrm |
589 val rtrm' = HOLogic.dest_Trueprop rtrm |
604 val qtrm' = HOLogic.dest_Trueprop qtrm |
590 val qtrm' = HOLogic.dest_Trueprop qtrm |
605 val reg_goal = regularize_trm_chk ctxt (rtrm', qtrm') |
591 val reg_goal = regularize_trm_chk ctxt (rtrm', qtrm') |
606 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
592 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
607 val inj_goal = inj_repabs_trm_chk ctxt (reg_goal, qtrm') |
593 val inj_goal = inj_repabs_trm_chk ctxt (reg_goal, qtrm') |
608 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
594 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
609 in |
595 in |
610 Drule.instantiate' [] |
596 Drule.instantiate' [] |
611 [SOME (cterm_of thy rtrm'), |
597 [SOME (cterm_of thy rtrm'), |
612 SOME (cterm_of thy reg_goal), |
598 SOME (cterm_of thy reg_goal), |
613 NONE, |
599 NONE, |