100 |
100 |
101 ball_reg_eqv_range and bex_reg_eqv_range |
101 ball_reg_eqv_range and bex_reg_eqv_range |
102 |
102 |
103 Since the left-hand-side contains a non-pattern '?P (f ?x)' |
103 Since the left-hand-side contains a non-pattern '?P (f ?x)' |
104 we rely on unification/instantiation to check whether the |
104 we rely on unification/instantiation to check whether the |
105 theorem applies and return NONE if it doesn't. |
105 theorem applies and return NONE if it doesn't. |
106 *) |
106 *) |
107 fun calculate_inst ctxt ball_bex_thm redex R1 R2 = |
107 fun calculate_inst ctxt ball_bex_thm redex R1 R2 = |
108 let |
108 let |
109 val thy = ProofContext.theory_of ctxt |
109 val thy = ProofContext.theory_of ctxt |
110 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
110 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
120 end |
120 end |
121 |
121 |
122 fun ball_bex_range_simproc ss redex = |
122 fun ball_bex_range_simproc ss redex = |
123 let |
123 let |
124 val ctxt = Simplifier.the_context ss |
124 val ctxt = Simplifier.the_context ss |
125 in |
125 in |
126 case redex of |
126 case redex of |
127 (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ |
127 (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ |
128 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
128 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
129 calculate_inst ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
129 calculate_inst ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
130 |
130 |
131 | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ |
131 | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ |
132 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
132 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
133 calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
133 calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
134 |
134 |
135 | _ => NONE |
135 | _ => NONE |
136 end |
136 end |
137 |
137 |
149 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel' |
149 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel' |
150 to avoid loops |
150 to avoid loops |
151 |
151 |
152 5. then simplification like 0 |
152 5. then simplification like 0 |
153 |
153 |
154 finally jump back to 1 |
154 finally jump back to 1 |
155 *) |
155 *) |
156 fun regularize_tac ctxt = |
156 fun regularize_tac ctxt = |
157 let |
157 let |
158 val thy = ProofContext.theory_of ctxt |
158 val thy = ProofContext.theory_of ctxt |
159 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
159 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
160 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
160 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
161 val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc)) |
161 val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc)) |
162 val simpset = (mk_minimal_ss ctxt) |
162 val simpset = (mk_minimal_ss ctxt) |
163 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp} |
163 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp} |
164 addsimprocs [simproc] |
164 addsimprocs [simproc] |
165 addSolver equiv_solver addSolver quotient_solver |
165 addSolver equiv_solver addSolver quotient_solver |
166 val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt) |
166 val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt) |
167 in |
167 in |
168 simp_tac simpset THEN' |
168 simp_tac simpset THEN' |
169 REPEAT_ALL_NEW (CHANGED o FIRST' |
169 REPEAT_ALL_NEW (CHANGED o FIRST' |
170 [resolve_tac @{thms ball_reg_right bex_reg_left bex1_bexeq_reg}, |
170 [resolve_tac @{thms ball_reg_right bex_reg_left bex1_bexeq_reg}, |
171 resolve_tac (Inductive.get_monos ctxt), |
171 resolve_tac (Inductive.get_monos ctxt), |
172 resolve_tac @{thms ball_all_comm bex_ex_comm}, |
172 resolve_tac @{thms ball_all_comm bex_ex_comm}, |
173 resolve_tac eq_eqvs, |
173 resolve_tac eq_eqvs, |
174 simp_tac simpset]) |
174 simp_tac simpset]) |
175 end |
175 end |
176 |
176 |
177 |
177 |
178 |
178 |
179 (*** Injection Tactic ***) |
179 (*** Injection Tactic ***) |
180 |
180 |
181 (* Looks for Quot_True assumptions, and in case its parameter |
181 (* Looks for Quot_True assumptions, and in case its parameter |
182 is an application, it returns the function and the argument. |
182 is an application, it returns the function and the argument. |
183 *) |
183 *) |
184 fun find_qt_asm asms = |
184 fun find_qt_asm asms = |
185 let |
185 let |
186 fun find_fun trm = |
186 fun find_fun trm = |
187 case trm of |
187 case trm of |
214 quot_true_simple_conv ctxt fnctn ctrm |
214 quot_true_simple_conv ctxt fnctn ctrm |
215 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
215 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
216 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
216 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
217 | _ => Conv.all_conv ctrm |
217 | _ => Conv.all_conv ctrm |
218 |
218 |
219 fun quot_true_tac ctxt fnctn = |
219 fun quot_true_tac ctxt fnctn = |
220 CONVERSION |
220 CONVERSION |
221 ((Conv.params_conv ~1 (fn ctxt => |
221 ((Conv.params_conv ~1 (fn ctxt => |
222 (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) |
222 (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) |
223 |
223 |
224 fun dest_comb (f $ a) = (f, a) |
224 fun dest_comb (f $ a) = (f, a) |
225 fun dest_bcomb ((_ $ l) $ r) = (l, r) |
225 fun dest_bcomb ((_ $ l) $ r) = (l, r) |
226 |
226 |
227 fun unlam t = |
227 fun unlam t = |
228 case t of |
228 case t of |
229 (Abs a) => snd (Term.dest_abs a) |
229 (Abs a) => snd (Term.dest_abs a) |
230 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) |
230 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) |
234 |
234 |
235 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
235 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
236 |
236 |
237 (* We apply apply_rsp only in case if the type needs lifting. |
237 (* We apply apply_rsp only in case if the type needs lifting. |
238 This is the case if the type of the data in the Quot_True |
238 This is the case if the type of the data in the Quot_True |
239 assumption is different from the corresponding type in the goal. |
239 assumption is different from the corresponding type in the goal. |
240 *) |
240 *) |
241 val apply_rsp_tac = |
241 val apply_rsp_tac = |
242 Subgoal.FOCUS (fn {concl, asms, context,...} => |
242 Subgoal.FOCUS (fn {concl, asms, context,...} => |
243 let |
243 let |
244 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
244 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
302 end |
302 end |
303 | _ => no_tac) |
303 | _ => no_tac) |
304 |
304 |
305 |
305 |
306 |
306 |
307 (* Injection means to prove that the regularised theorem implies |
307 (* Injection means to prove that the regularised theorem implies |
308 the abs/rep injected one. |
308 the abs/rep injected one. |
309 |
309 |
310 The deterministic part: |
310 The deterministic part: |
311 - remove lambdas from both sides |
311 - remove lambdas from both sides |
312 - prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp |
312 - prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp |
315 - prove equality of relations using equals_rsp |
315 - prove equality of relations using equals_rsp |
316 - use user-supplied RSP theorems |
316 - use user-supplied RSP theorems |
317 - solve 'relation of relations' goals using quot_rel_rsp |
317 - solve 'relation of relations' goals using quot_rel_rsp |
318 - remove rep_abs from the right side |
318 - remove rep_abs from the right side |
319 (Lambdas under respects may have left us some assumptions) |
319 (Lambdas under respects may have left us some assumptions) |
320 |
320 |
321 Then in order: |
321 Then in order: |
322 - split applications of lifted type (apply_rsp) |
322 - split applications of lifted type (apply_rsp) |
323 - split applications of non-lifted type (cong_tac) |
323 - split applications of non-lifted type (cong_tac) |
324 - apply extentionality |
324 - apply extentionality |
325 - assumption |
325 - assumption |
362 | (_ $ |
362 | (_ $ |
363 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _) $ |
363 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _) $ |
364 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _)) |
364 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _)) |
365 => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt] |
365 => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt] |
366 |
366 |
367 | Const (@{const_name "op ="},_) $ (R $ _ $ _) $ (_ $ _ $ _) => |
367 | Const (@{const_name "op ="},_) $ (R $ _ $ _) $ (_ $ _ $ _) => |
368 (rtac @{thm refl} ORELSE' |
368 (rtac @{thm refl} ORELSE' |
369 (equals_rsp_tac R ctxt THEN' RANGE [ |
369 (equals_rsp_tac R ctxt THEN' RANGE [ |
370 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)])) |
370 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)])) |
371 |
371 |
372 (* reflexivity of operators arising from Cong_tac *) |
372 (* reflexivity of operators arising from Cong_tac *) |
426 fun fun_map_simple_conv xs ctrm = |
426 fun fun_map_simple_conv xs ctrm = |
427 case (term_of ctrm) of |
427 case (term_of ctrm) of |
428 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
428 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
429 if member (op=) xs h |
429 if member (op=) xs h |
430 then Conv.all_conv ctrm |
430 then Conv.all_conv ctrm |
431 else Conv.rewr_conv @{thm fun_map_def[THEN eq_reflection]} ctrm |
431 else Conv.rewr_conv @{thm fun_map_def[THEN eq_reflection]} ctrm |
432 | _ => Conv.all_conv ctrm |
432 | _ => Conv.all_conv ctrm |
433 |
433 |
434 fun fun_map_conv xs ctxt ctrm = |
434 fun fun_map_conv xs ctxt ctrm = |
435 case (term_of ctrm) of |
435 case (term_of ctrm) of |
436 _ $ _ => (Conv.comb_conv (fun_map_conv xs ctxt) then_conv |
436 _ $ _ => (Conv.comb_conv (fun_map_conv xs ctxt) then_conv |
468 (* Simplifies a redex using the 'lambda_prs' theorem. |
468 (* Simplifies a redex using the 'lambda_prs' theorem. |
469 First instantiates the types and known subterms. |
469 First instantiates the types and known subterms. |
470 Then solves the quotient assumptions to get Rep2 and Abs1 |
470 Then solves the quotient assumptions to get Rep2 and Abs1 |
471 Finally instantiates the function f using make_inst |
471 Finally instantiates the function f using make_inst |
472 If Rep2 is an identity then the pattern is simpler and |
472 If Rep2 is an identity then the pattern is simpler and |
473 make_inst_id is used |
473 make_inst_id is used |
474 *) |
474 *) |
475 fun lambda_prs_simple_conv ctxt ctrm = |
475 fun lambda_prs_simple_conv ctxt ctrm = |
476 case (term_of ctrm) of |
476 case (term_of ctrm) of |
477 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
477 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
478 let |
478 let |
499 |
499 |
500 |
500 |
501 (* Cleaning consists of: |
501 (* Cleaning consists of: |
502 |
502 |
503 1. unfolding of ---> in front of everything, except |
503 1. unfolding of ---> in front of everything, except |
504 bound variables (this prevents lambda_prs from |
504 bound variables (this prevents lambda_prs from |
505 becoming stuck) |
505 becoming stuck) |
506 |
506 |
507 2. simplification with lambda_prs |
507 2. simplification with lambda_prs |
508 |
508 |
509 3. simplification with: |
509 3. simplification with: |
510 |
510 |
511 - Quotient_abs_rep Quotient_rel_rep |
511 - Quotient_abs_rep Quotient_rel_rep |
512 babs_prs all_prs ex_prs ex1_prs |
512 babs_prs all_prs ex_prs ex1_prs |
513 |
513 |
514 - id_simps and preservation lemmas and |
514 - id_simps and preservation lemmas and |
515 |
515 |
516 - symmetric versions of the definitions |
516 - symmetric versions of the definitions |
517 (that is definitions of quotient constants |
517 (that is definitions of quotient constants |
518 are folded) |
518 are folded) |
519 |
519 |
520 4. test for refl |
520 4. test for refl |
521 *) |
521 *) |
522 fun clean_tac lthy = |
522 fun clean_tac lthy = |
543 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
543 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
544 |
544 |
545 fun inst_spec_tac ctrms = |
545 fun inst_spec_tac ctrms = |
546 EVERY' (map (dtac o inst_spec) ctrms) |
546 EVERY' (map (dtac o inst_spec) ctrms) |
547 |
547 |
548 fun all_list xs trm = |
548 fun all_list xs trm = |
549 fold (fn (x, T) => fn t' => HOLogic.mk_all (x, T, t')) xs trm |
549 fold (fn (x, T) => fn t' => HOLogic.mk_all (x, T, t')) xs trm |
550 |
550 |
551 fun apply_under_Trueprop f = |
551 fun apply_under_Trueprop f = |
552 HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop |
552 HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop |
553 |
553 |
554 fun gen_frees_tac ctxt = |
554 fun gen_frees_tac ctxt = |
555 SUBGOAL (fn (concl, i) => |
555 SUBGOAL (fn (concl, i) => |
556 let |
556 let |
575 |
575 |
576 - 1st prem is the regularization step |
576 - 1st prem is the regularization step |
577 - 2nd prem is the rep/abs injection step |
577 - 2nd prem is the rep/abs injection step |
578 - 3rd prem is the cleaning part |
578 - 3rd prem is the cleaning part |
579 |
579 |
580 the Quot_True premise in 2nd records the lifted theorem |
580 the Quot_True premise in 2nd records the lifted theorem |
581 *) |
581 *) |
582 val lifting_procedure_thm = |
582 val lifting_procedure_thm = |
583 @{lemma "[|A; |
583 @{lemma "[|A; |
584 A --> B; |
584 A --> B; |
585 Quot_True D ==> B = C; |
585 Quot_True D ==> B = C; |
588 |
588 |
589 fun lift_match_error ctxt msg rtrm qtrm = |
589 fun lift_match_error ctxt msg rtrm qtrm = |
590 let |
590 let |
591 val rtrm_str = Syntax.string_of_term ctxt rtrm |
591 val rtrm_str = Syntax.string_of_term ctxt rtrm |
592 val qtrm_str = Syntax.string_of_term ctxt qtrm |
592 val qtrm_str = Syntax.string_of_term ctxt qtrm |
593 val msg = cat_lines [enclose "[" "]" msg, "The quotient theorem", qtrm_str, |
593 val msg = cat_lines [enclose "[" "]" msg, "The quotient theorem", qtrm_str, |
594 "", "does not match with original theorem", rtrm_str] |
594 "", "does not match with original theorem", rtrm_str] |
595 in |
595 in |
596 error msg |
596 error msg |
597 end |
597 end |
598 |
598 |
627 |
627 |
628 |
628 |
629 (* Automatic Proofs *) |
629 (* Automatic Proofs *) |
630 |
630 |
631 val msg1 = "The regularize proof failed." |
631 val msg1 = "The regularize proof failed." |
632 val msg2 = cat_lines ["The injection proof failed.", |
632 val msg2 = cat_lines ["The injection proof failed.", |
633 "This is probably due to missing respects lemmas.", |
633 "This is probably due to missing respects lemmas.", |
634 "Try invoking the injection method manually to see", |
634 "Try invoking the injection method manually to see", |
635 "which lemmas are missing."] |
635 "which lemmas are missing."] |
636 val msg3 = "The cleaning proof failed." |
636 val msg3 = "The cleaning proof failed." |
637 |
637 |
638 fun lift_tac ctxt rthms = |
638 fun lift_tac ctxt rthms = |
639 let |
639 let |
640 fun mk_tac rthm = |
640 fun mk_tac rthm = |
641 procedure_tac ctxt rthm |
641 procedure_tac ctxt rthm |
642 THEN' RANGE_WARN |
642 THEN' RANGE_WARN |
643 [(regularize_tac ctxt, msg1), |
643 [(regularize_tac ctxt, msg1), |
644 (all_injection_tac ctxt, msg2), |
644 (all_injection_tac ctxt, msg2), |
645 (clean_tac ctxt, msg3)] |
645 (clean_tac ctxt, msg3)] |
646 in |
646 in |
647 simp_tac (mk_minimal_ss ctxt) (* unfolding multiple &&& *) |
647 simp_tac (mk_minimal_ss ctxt) (* unfolding multiple &&& *) |
648 THEN' RANGE (map mk_tac rthms) |
648 THEN' RANGE (map mk_tac rthms) |
649 end |
649 end |
650 |
650 |
651 (* An Attribute which automatically constructs the qthm *) |
651 (* An Attribute which automatically constructs the qthm *) |
652 fun lifted_attrib_aux context thm = |
652 fun lifted_attrib_aux context thm = |