95 in |
95 in |
96 (map (prep_ty thy) tyenv, map (prep_trm thy) tenv) |
96 (map (prep_ty thy) tyenv, map (prep_trm thy) tenv) |
97 end |
97 end |
98 |
98 |
99 (* Calculates the instantiations for the lemmas: |
99 (* Calculates the instantiations for the lemmas: |
|
100 |
100 ball_reg_eqv_range and bex_reg_eqv_range |
101 ball_reg_eqv_range and bex_reg_eqv_range |
|
102 |
101 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)' |
102 we rely on unification/instantiation to check whether the |
104 we rely on unification/instantiation to check whether the |
103 theorem applies and return NONE if it doesn't. *) |
105 theorem applies and return NONE if it doesn't. |
|
106 *) |
104 fun calculate_inst ctxt ball_bex_thm redex R1 R2 = |
107 fun calculate_inst ctxt ball_bex_thm redex R1 R2 = |
105 let |
108 let |
106 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
109 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
107 val thy = ProofContext.theory_of ctxt |
110 val thy = ProofContext.theory_of ctxt |
108 val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)] |
111 val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)] |
109 val trm_inst1 = map (SOME o cterm_of thy) [R2, R1] |
112 val trm_inst1 = map (SOME o cterm_of thy) [R2, R1] |
110 in |
113 in |
111 (case try (Drule.instantiate' typ_inst1 trm_inst1) ball_bex_thm of |
114 case try (Drule.instantiate' typ_inst1 trm_inst1) ball_bex_thm of |
112 NONE => NONE |
115 NONE => NONE |
113 | SOME thm' => |
116 | SOME thm' => |
114 (case try (get_match_inst thy (get_lhs thm')) redex of |
117 (case try (get_match_inst thy (get_lhs thm')) redex of |
115 NONE => NONE |
118 NONE => NONE |
116 | SOME inst2 => try (Drule.instantiate inst2) thm') |
119 | SOME inst2 => try (Drule.instantiate inst2) thm') |
117 ) |
|
118 end |
120 end |
119 |
121 |
120 fun ball_bex_range_simproc ss redex = |
122 fun ball_bex_range_simproc ss redex = |
121 let |
123 let |
122 val ctxt = Simplifier.the_context ss |
124 val ctxt = Simplifier.the_context ss |
131 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 |
132 |
134 |
133 | _ => NONE |
135 | _ => NONE |
134 end |
136 end |
135 |
137 |
136 (* |
138 (* Regularize works as follows: |
137 0. preliminary simplification step according to |
139 |
138 ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range |
140 0. preliminary simplification step according to |
139 |
141 ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range |
140 1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left) |
142 |
141 |
143 1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left) |
142 2. monos |
144 |
143 |
145 2. monos |
144 3. commutation rules for ball and bex (ball_all_comm bex_ex_comm) |
146 |
145 |
147 3. commutation rules for ball and bex (ball_all_comm bex_ex_comm) |
146 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel' |
148 |
147 to avoid loops |
149 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel' |
148 |
150 to avoid loops |
149 5. then simplification like 0 |
151 |
150 |
152 5. then simplification like 0 |
151 finally jump back to 1 *) |
153 |
|
154 finally jump back to 1 |
|
155 *) |
152 fun regularize_tac ctxt = |
156 fun regularize_tac ctxt = |
153 let |
157 let |
154 val thy = ProofContext.theory_of ctxt |
158 val thy = ProofContext.theory_of ctxt |
155 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
159 val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"} |
156 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
160 val bex_pat = @{term "Bex (Respects (R1 ===> R2)) P"} |
173 |
177 |
174 |
178 |
175 (*** Injection Tactic ***) |
179 (*** Injection Tactic ***) |
176 |
180 |
177 (* Looks for Quot_True assumtions, and in case its parameter |
181 (* Looks for Quot_True assumtions, and in case its parameter |
178 is an application, it returns the function and the argument. *) |
182 is an application, it returns the function and the argument. |
|
183 *) |
179 fun find_qt_asm asms = |
184 fun find_qt_asm asms = |
180 let |
185 let |
181 fun find_fun trm = |
186 fun find_fun trm = |
182 case trm of |
187 case trm of |
183 (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true |
188 (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true |
229 |
234 |
230 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
235 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
231 |
236 |
232 (* 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. |
233 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 |
234 assumption is different from the corresponding type in the goal. *) |
239 assumption is different from the corresponding type in the goal. |
|
240 *) |
235 val apply_rsp_tac = |
241 val apply_rsp_tac = |
236 Subgoal.FOCUS (fn {concl, asms, context,...} => |
242 Subgoal.FOCUS (fn {concl, asms, context,...} => |
237 let |
243 let |
238 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
244 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
239 val qt_asm = find_qt_asm (map term_of asms) |
245 val qt_asm = find_qt_asm (map term_of asms) |
257 end |
263 end |
258 | _ => no_tac |
264 | _ => no_tac |
259 end) |
265 end) |
260 |
266 |
261 (* Instantiates and applies 'equals_rsp'. Since the theorem is |
267 (* Instantiates and applies 'equals_rsp'. Since the theorem is |
262 complex we rely on instantiation to tell us if it applies *) |
268 complex we rely on instantiation to tell us if it applies |
|
269 *) |
263 fun equals_rsp_tac R ctxt = |
270 fun equals_rsp_tac R ctxt = |
264 let |
271 let |
265 val thy = ProofContext.theory_of ctxt |
272 val thy = ProofContext.theory_of ctxt |
266 in |
273 in |
267 case try (cterm_of thy) R of (* There can be loose bounds in R *) |
274 case try (cterm_of thy) R of (* There can be loose bounds in R *) |
296 | NONE => no_tac |
303 | NONE => no_tac |
297 end |
304 end |
298 | _ => no_tac) |
305 | _ => no_tac) |
299 |
306 |
300 |
307 |
301 (* |
308 |
302 To prove that the regularised theorem implies the abs/rep injected, |
309 (* Injection means to prove that the regularised theorem implies |
303 we try: |
310 the abs/rep injected one. |
304 |
311 |
305 The deterministic part: |
312 The deterministic part: |
306 -) remove lambdas from both sides |
313 - remove lambdas from both sides |
307 -) prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp |
314 - prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp |
308 -) prove Ball/Bex relations unfolding fun_rel_id |
315 - prove Ball/Bex relations unfolding fun_rel_id |
309 -) reflexivity of equality |
316 - reflexivity of equality |
310 -) prove equality of relations using equals_rsp |
317 - prove equality of relations using equals_rsp |
311 -) use user-supplied RSP theorems |
318 - use user-supplied RSP theorems |
312 -) solve 'relation of relations' goals using quot_rel_rsp |
319 - solve 'relation of relations' goals using quot_rel_rsp |
313 -) remove rep_abs from the right side |
320 - remove rep_abs from the right side |
314 (Lambdas under respects may have left us some assumptions) |
321 (Lambdas under respects may have left us some assumptions) |
315 Then in order: |
322 |
316 -) split applications of lifted type (apply_rsp) |
323 Then in order: |
317 -) split applications of non-lifted type (cong_tac) |
324 - split applications of lifted type (apply_rsp) |
318 -) apply extentionality |
325 - split applications of non-lifted type (cong_tac) |
319 -) assumption |
326 - apply extentionality |
320 -) reflexivity of the relation |
327 - assumption |
321 *) |
328 - reflexivity of the relation |
322 |
329 *) |
323 |
|
324 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) => |
330 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) => |
325 (case (bare_concl goal) of |
331 (case (bare_concl goal) of |
326 (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *) |
332 (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *) |
327 (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _) |
333 (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _) |
328 => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam |
334 => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam |
410 fun all_injection_tac ctxt = |
416 fun all_injection_tac ctxt = |
411 REPEAT_ALL_NEW (injection_tac ctxt) |
417 REPEAT_ALL_NEW (injection_tac ctxt) |
412 |
418 |
413 |
419 |
414 |
420 |
415 (** Cleaning of the Theorem **) |
421 (*** Cleaning of the Theorem ***) |
416 |
422 |
417 (* expands all fun_maps, except in front of the bound variables listed in xs *) |
423 (* expands all fun_maps, except in front of the bound variables listed in xs *) |
418 fun fun_map_simple_conv xs ctrm = |
424 fun fun_map_simple_conv xs ctrm = |
419 case (term_of ctrm) of |
425 case (term_of ctrm) of |
420 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
426 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
460 (* Simplifies a redex using the 'lambda_prs' theorem. |
466 (* Simplifies a redex using the 'lambda_prs' theorem. |
461 First instantiates the types and known subterms. |
467 First instantiates the types and known subterms. |
462 Then solves the quotient assumptions to get Rep2 and Abs1 |
468 Then solves the quotient assumptions to get Rep2 and Abs1 |
463 Finally instantiates the function f using make_inst |
469 Finally instantiates the function f using make_inst |
464 If Rep2 is an identity then the pattern is simpler and |
470 If Rep2 is an identity then the pattern is simpler and |
465 make_inst_id is used *) |
471 make_inst_id is used |
|
472 *) |
466 fun lambda_prs_simple_conv ctxt ctrm = |
473 fun lambda_prs_simple_conv ctxt ctrm = |
467 case (term_of ctrm) of |
474 case (term_of ctrm) of |
468 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
475 (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) => |
469 let |
476 let |
470 val thy = ProofContext.theory_of ctxt |
477 val thy = ProofContext.theory_of ctxt |
488 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
495 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
489 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
496 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
490 |
497 |
491 |
498 |
492 (* Cleaning consists of: |
499 (* Cleaning consists of: |
493 1. folding of definitions and preservation lemmas; |
500 |
494 and simplification with babs_prs all_prs ex_prs |
501 1. folding of definitions and preservation lemmas; |
495 |
502 and simplification with babs_prs all_prs ex_prs |
496 2. unfolding of ---> in front of everything, except |
503 |
497 bound variables |
504 2. unfolding of ---> in front of everything, except |
498 (this prevents lambda_prs from becoming stuck) |
505 bound variables |
499 |
506 (this prevents lambda_prs from becoming stuck) |
500 3. simplification with lambda_prs |
507 |
501 |
508 3. simplification with lambda_prs |
502 4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps |
509 |
503 |
510 4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps |
504 5. test for refl *) |
511 |
|
512 5. test for refl |
|
513 *) |
505 fun clean_tac lthy = |
514 fun clean_tac lthy = |
506 let |
515 let |
507 (* FIXME/TODO produce defs with lthy, like prs and ids *) |
516 (* FIXME/TODO produce defs with lthy, like prs and ids *) |
508 val thy = ProofContext.theory_of lthy; |
517 val thy = ProofContext.theory_of lthy; |
509 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
518 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
554 end) |
562 end) |
555 |
563 |
556 |
564 |
557 (** The General Shape of the Lifting Procedure **) |
565 (** The General Shape of the Lifting Procedure **) |
558 |
566 |
559 |
|
560 (* - A is the original raw theorem |
567 (* - A is the original raw theorem |
561 - B is the regularized theorem |
568 - B is the regularized theorem |
562 - C is the rep/abs injected version of B |
569 - C is the rep/abs injected version of B |
563 - D is the lifted theorem |
570 - D is the lifted theorem |
564 |
571 |
565 - 1st prem is the regularization step |
572 - 1st prem is the regularization step |
566 - 2nd prem is the rep/abs injection step |
573 - 2nd prem is the rep/abs injection step |
567 - 3rd prem is the cleaning part |
574 - 3rd prem is the cleaning part |
568 |
575 |
569 the Quot_True premise in 2nd records the lifted theorem *) |
576 the Quot_True premise in 2nd records the lifted theorem |
|
577 *) |
570 val lifting_procedure_thm = |
578 val lifting_procedure_thm = |
571 @{lemma "[|A; |
579 @{lemma "[|A; |
572 A --> B; |
580 A --> B; |
573 Quot_True D ==> B = C; |
581 Quot_True D ==> B = C; |
574 C = D|] ==> D" |
582 C = D|] ==> D" |