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 all_inj_repabs_tac: Proof.context -> int -> tactic |
4 val all_injection_tac: Proof.context -> int -> tactic |
5 val clean_tac: Proof.context -> int -> tactic |
5 val clean_tac: Proof.context -> int -> tactic |
6 val procedure_tac: Proof.context -> thm -> int -> tactic |
6 val procedure_tac: Proof.context -> thm -> int -> tactic |
7 val lift_tac: Proof.context ->thm -> int -> tactic |
7 val lift_tac: Proof.context -> thm -> int -> tactic |
8 val quotient_tac: Proof.context -> int -> tactic |
8 val quotient_tac: Proof.context -> int -> tactic |
9 end; |
9 end; |
10 |
10 |
11 structure Quotient_Tacs: QUOTIENT_TACS = |
11 structure Quotient_Tacs: QUOTIENT_TACS = |
12 struct |
12 struct |
46 in |
46 in |
47 @{thm equal_elim_rule1} OF [thm'', thm'] |
47 @{thm equal_elim_rule1} OF [thm'', thm'] |
48 end |
48 end |
49 |
49 |
50 |
50 |
|
51 (*********************) |
51 (* Regularize Tactic *) |
52 (* Regularize Tactic *) |
52 |
53 (*********************) |
|
54 |
|
55 (* solvers for equivp and quotient assumptions *) |
53 fun equiv_tac ctxt = |
56 fun equiv_tac ctxt = |
54 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
57 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
55 |
58 |
56 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
59 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
57 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
60 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
|
61 |
|
62 (* test whether DETERM makes any difference *) |
|
63 fun quotient_tac ctxt = SOLVES' |
|
64 (REPEAT_ALL_NEW (FIRST' |
|
65 [rtac @{thm identity_quotient}, |
|
66 resolve_tac (quotient_rules_get ctxt)])) |
|
67 |
|
68 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
|
69 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
|
70 |
|
71 fun solve_quotient_assm ctxt thm = |
|
72 case Seq.pull (quotient_tac ctxt 1 thm) of |
|
73 SOME (t, _) => t |
|
74 | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing" |
|
75 |
58 |
76 |
59 fun prep_trm thy (x, (T, t)) = |
77 fun prep_trm thy (x, (T, t)) = |
60 (cterm_of thy (Var (x, T)), cterm_of thy t) |
78 (cterm_of thy (Var (x, T)), cterm_of thy t) |
61 |
79 |
62 fun prep_ty thy (x, (S, ty)) = |
80 fun prep_ty thy (x, (S, ty)) = |
72 (map (prep_ty thy) tyenv, map (prep_trm thy) tenv) |
90 (map (prep_ty thy) tyenv, map (prep_trm thy) tenv) |
73 end |
91 end |
74 |
92 |
75 (* calculates the instantiations for te lemmas *) |
93 (* calculates the instantiations for te lemmas *) |
76 (* ball_reg_eqv_range and bex_reg_eqv_range *) |
94 (* ball_reg_eqv_range and bex_reg_eqv_range *) |
77 fun calculate_instance ctxt ball_bex_thm redex R1 R2 = |
95 fun calculate_inst ctxt ball_bex_thm redex R1 R2 = |
78 let |
96 let |
79 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
97 fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm)) |
80 val thy = ProofContext.theory_of ctxt |
98 val thy = ProofContext.theory_of ctxt |
81 val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)] |
99 val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)] |
82 val trm_inst1 = map (SOME o cterm_of thy) [R2, R1] |
100 val trm_inst1 = map (SOME o cterm_of thy) [R2, R1] |
91 (* FIXME/TODO: What is the place where the exception is raised, *) |
109 (* FIXME/TODO: What is the place where the exception is raised, *) |
92 (* FIXME/TODO: and which exception is it? *) |
110 (* FIXME/TODO: and which exception is it? *) |
93 (* FIXME/TODO: Can one not find out from the types of R1 or R2, *) |
111 (* FIXME/TODO: Can one not find out from the types of R1 or R2, *) |
94 (* FIXME/TODO: or from their form, when NONE should be returned? *) |
112 (* FIXME/TODO: or from their form, when NONE should be returned? *) |
95 |
113 |
96 |
|
97 fun ball_bex_range_simproc ss redex = |
114 fun ball_bex_range_simproc ss redex = |
98 let |
115 let |
99 val ctxt = Simplifier.the_context ss |
116 val ctxt = Simplifier.the_context ss |
100 in |
117 in |
101 case redex of |
118 case redex of |
102 (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ |
119 (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ |
103 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
120 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
104 calculate_instance ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
121 calculate_inst ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
105 |
122 |
106 | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ |
123 | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ |
107 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
124 (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) => |
108 calculate_instance ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
125 calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2 |
|
126 |
109 | _ => NONE |
127 | _ => NONE |
110 end |
128 end |
111 |
|
112 (* test whether DETERM makes any difference *) |
|
113 fun quotient_tac ctxt = SOLVES' |
|
114 (REPEAT_ALL_NEW (FIRST' |
|
115 [rtac @{thm identity_quotient}, |
|
116 resolve_tac (quotient_rules_get ctxt)])) |
|
117 |
|
118 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
|
119 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
|
120 |
|
121 fun solve_quotient_assm ctxt thm = |
|
122 case Seq.pull (quotient_tac ctxt 1 thm) of |
|
123 SOME (t, _) => t |
|
124 | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing" |
|
125 |
|
126 |
129 |
127 (* 0. preliminary simplification step according to *) |
130 (* 0. preliminary simplification step according to *) |
128 (* thm ball_reg_eqv bex_reg_eqv babs_reg_eqv *) |
131 (* thm ball_reg_eqv bex_reg_eqv babs_reg_eqv *) |
129 (* ball_reg_eqv_range bex_reg_eqv_range *) |
132 (* ball_reg_eqv_range bex_reg_eqv_range *) |
130 (* *) |
133 (* *) |
131 (* 1. eliminating simple Ball/Bex instances *) |
134 (* 1. eliminating simple Ball/Bex instances *) |
132 (* thm ball_reg_right bex_reg_left *) |
135 (* thm ball_reg_right bex_reg_left *) |
133 (* *) |
136 (* *) |
134 (* 2. monos *) |
137 (* 2. monos *) |
|
138 (* *) |
135 (* 3. commutation rules for ball and bex *) |
139 (* 3. commutation rules for ball and bex *) |
136 (* thm ball_all_comm bex_ex_comm *) |
140 (* thm ball_all_comm bex_ex_comm *) |
137 (* *) |
141 (* *) |
138 (* 4. then rel-equality (which need to be *) |
142 (* 4. then rel-equalities, which need to be *) |
139 (* instantiated to avoid loops) *) |
143 (* instantiated with the followig theorem *) |
|
144 (* to avoid loops: *) |
140 (* thm eq_imp_rel *) |
145 (* thm eq_imp_rel *) |
141 (* *) |
146 (* *) |
142 (* 5. then simplification like 0 *) |
147 (* 5. then simplification like 0 *) |
143 (* *) |
148 (* *) |
144 (* finally jump back to 1 *) |
149 (* finally jump back to 1 *) |
154 addsimprocs [simproc] |
159 addsimprocs [simproc] |
155 addSolver equiv_solver addSolver quotient_solver |
160 addSolver equiv_solver addSolver quotient_solver |
156 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) |
157 in |
162 in |
158 simp_tac simpset THEN' |
163 simp_tac simpset THEN' |
159 REPEAT_ALL_NEW (CHANGED o FIRST' [ |
164 REPEAT_ALL_NEW (CHANGED o FIRST' |
160 resolve_tac @{thms ball_reg_right bex_reg_left}, |
165 [resolve_tac @{thms ball_reg_right bex_reg_left}, |
161 resolve_tac (Inductive.get_monos ctxt), |
166 resolve_tac (Inductive.get_monos ctxt), |
162 resolve_tac @{thms ball_all_comm bex_ex_comm}, |
167 resolve_tac @{thms ball_all_comm bex_ex_comm}, |
163 resolve_tac eq_eqvs, |
168 resolve_tac eq_eqvs, |
164 simp_tac simpset]) |
169 simp_tac simpset]) |
165 end |
170 end |
166 |
171 |
167 |
172 |
168 |
173 (********************) |
169 (* Injection Tactic *) |
174 (* Injection Tactic *) |
170 |
175 (********************) |
171 (* looks for QUOT_TRUE assumtions, and in case its parameter *) |
176 |
172 (* is an application, it returns the function and the argument *) |
177 (* Looks for Quot_True assumtions, and in case its parameter *) |
|
178 (* is an application, it returns the function and the argument. *) |
173 fun find_qt_asm asms = |
179 fun find_qt_asm asms = |
174 let |
180 let |
175 fun find_fun trm = |
181 fun find_fun trm = |
176 case trm of |
182 case trm of |
177 (Const(@{const_name Trueprop}, _) $ (Const (@{const_name QUOT_TRUE}, _) $ _)) => true |
183 (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true |
178 | _ => false |
184 | _ => false |
179 in |
185 in |
180 case find_first find_fun asms of |
186 case find_first find_fun asms of |
181 SOME (_ $ (_ $ (f $ a))) => SOME (f, a) |
187 SOME (_ $ (_ $ (f $ a))) => SOME (f, a) |
182 | _ => NONE |
188 | _ => NONE |
183 end |
189 end |
184 |
190 |
185 fun quot_true_simple_conv ctxt fnctn ctrm = |
191 fun quot_true_simple_conv ctxt fnctn ctrm = |
186 case (term_of ctrm) of |
192 case (term_of ctrm) of |
187 (Const (@{const_name QUOT_TRUE}, _) $ x) => |
193 (Const (@{const_name Quot_True}, _) $ x) => |
188 let |
194 let |
189 val fx = fnctn x; |
195 val fx = fnctn x; |
190 val thy = ProofContext.theory_of ctxt; |
196 val thy = ProofContext.theory_of ctxt; |
191 val cx = cterm_of thy x; |
197 val cx = cterm_of thy x; |
192 val cfx = cterm_of thy fx; |
198 val cfx = cterm_of thy fx; |
193 val cxt = ctyp_of thy (fastype_of x); |
199 val cxt = ctyp_of thy (fastype_of x); |
194 val cfxt = ctyp_of thy (fastype_of fx); |
200 val cfxt = ctyp_of thy (fastype_of fx); |
195 val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp} |
201 val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QT_imp} |
196 in |
202 in |
197 Conv.rewr_conv thm ctrm |
203 Conv.rewr_conv thm ctrm |
198 end |
204 end |
199 |
205 |
200 fun quot_true_conv ctxt fnctn ctrm = |
206 fun quot_true_conv ctxt fnctn ctrm = |
201 case (term_of ctrm) of |
207 case (term_of ctrm) of |
202 (Const (@{const_name QUOT_TRUE}, _) $ _) => |
208 (Const (@{const_name Quot_True}, _) $ _) => |
203 quot_true_simple_conv ctxt fnctn ctrm |
209 quot_true_simple_conv ctxt fnctn ctrm |
204 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
210 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
205 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
211 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
206 | _ => Conv.all_conv ctrm |
212 | _ => Conv.all_conv ctrm |
207 |
213 |
223 | dest_fun_type _ = error "dest_fun_type" |
229 | dest_fun_type _ = error "dest_fun_type" |
224 |
230 |
225 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
231 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
226 |
232 |
227 |
233 |
228 (* we apply apply_rsp only in case if the type needs lifting, *) |
234 (* We apply apply_rsp only in case if the type needs lifting. *) |
229 (* which is the case if the type of the data in the QUOT_TRUE *) |
235 (* This is the case if the type of the data in the Quot_True *) |
230 (* assumption is different from the corresponding type in the goal *) |
236 (* assumption is different from the corresponding type in the goal *) |
231 val apply_rsp_tac = |
237 val apply_rsp_tac = |
232 Subgoal.FOCUS (fn {concl, asms, context,...} => |
238 Subgoal.FOCUS (fn {concl, asms, context,...} => |
233 let |
239 let |
234 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
240 val bare_concl = HOLogic.dest_Trueprop (term_of concl) |
307 D) unfolding lambda on one side |
313 D) unfolding lambda on one side |
308 E) simplifying (= ===> =) for simpler respectfulness |
314 E) simplifying (= ===> =) for simpler respectfulness |
309 *) |
315 *) |
310 |
316 |
311 |
317 |
312 fun inj_repabs_tac_match ctxt = SUBGOAL (fn (goal, i) => |
318 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) => |
313 (case (bare_concl goal) of |
319 (case (bare_concl goal) of |
314 (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *) |
320 (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *) |
315 (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _) |
321 (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _) |
316 => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam |
322 => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam |
317 |
323 |
363 ORELSE' rep_abs_rsp_tac ctxt |
369 ORELSE' rep_abs_rsp_tac ctxt |
364 |
370 |
365 | _ => K no_tac |
371 | _ => K no_tac |
366 ) i) |
372 ) i) |
367 |
373 |
368 fun inj_repabs_step_tac ctxt rel_refl = |
374 fun injection_step_tac ctxt rel_refl = |
369 FIRST' [ |
375 FIRST' [ |
370 inj_repabs_tac_match ctxt, |
376 injection_match_tac ctxt, |
371 (* R (t $ ...) (t' $ ...) ----> apply_rsp provided type of t needs lifting *) |
377 |
372 |
378 (* R (t $ ...) (t' $ ...) ----> apply_rsp provided type of t needs lifting *) |
373 apply_rsp_tac ctxt THEN' |
379 apply_rsp_tac ctxt THEN' |
374 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
380 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)], |
375 |
381 |
376 (* (op =) (t $ ...) (t' $ ...) ----> Cong provided type of t does not need lifting *) |
382 (* (op =) (t $ ...) (t' $ ...) ----> Cong provided type of t does not need lifting *) |
377 (* merge with previous tactic *) |
383 (* merge with previous tactic *) |
386 |
392 |
387 (* reflexivity of the basic relations *) |
393 (* reflexivity of the basic relations *) |
388 (* R ... ... *) |
394 (* R ... ... *) |
389 resolve_tac rel_refl] |
395 resolve_tac rel_refl] |
390 |
396 |
391 fun inj_repabs_tac ctxt = |
397 fun injection_tac ctxt = |
392 let |
398 let |
393 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
399 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
394 in |
400 in |
395 simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) |
401 simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) |
396 THEN' inj_repabs_step_tac ctxt rel_refl |
402 THEN' injection_step_tac ctxt rel_refl |
397 end |
403 end |
398 |
404 |
399 fun all_inj_repabs_tac ctxt = |
405 fun all_injection_tac ctxt = |
400 REPEAT_ALL_NEW (inj_repabs_tac ctxt) |
406 REPEAT_ALL_NEW (injection_tac ctxt) |
401 |
407 |
402 |
408 |
|
409 (***************************) |
403 (* Cleaning of the Theorem *) |
410 (* Cleaning of the Theorem *) |
404 |
411 (***************************) |
405 |
412 |
406 (* expands all fun_maps, except in front of bound variables *) |
413 (* expands all fun_maps, except in front of bound variables *) |
407 fun fun_map_simple_conv xs ctrm = |
414 fun fun_map_simple_conv xs ctrm = |
408 case (term_of ctrm) of |
415 case (term_of ctrm) of |
409 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
416 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
470 Conv.rewr_conv ti ctrm |
477 Conv.rewr_conv ti ctrm |
471 end |
478 end |
472 handle _ => Conv.all_conv ctrm) |
479 handle _ => Conv.all_conv ctrm) |
473 | _ => Conv.all_conv ctrm |
480 | _ => Conv.all_conv ctrm |
474 |
481 |
475 val lambda_prs_conv = |
482 |
476 More_Conv.top_conv lambda_prs_simple_conv |
483 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
477 |
|
478 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
484 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
479 |
485 |
480 |
486 |
481 (* 1. folding of definitions and preservation lemmas; *) |
487 (* 1. folding of definitions and preservation lemmas; *) |
482 (* and simplification with *) |
488 (* and simplification with *) |
483 (* thm babs_prs all_prs ex_prs *) |
489 (* thm babs_prs all_prs ex_prs *) |
484 (* *) |
490 (* *) |
485 (* 2. unfolding of ---> in front of everything, except *) |
491 (* 2. unfolding of ---> in front of everything, except *) |
486 (* bound variables (this prevents lambda_prs from *) |
492 (* bound variables (this prevents lambda_prs from *) |
487 (* becoming stuck *) |
493 (* becoming stuck) *) |
488 (* thm fun_map.simps *) |
494 (* thm fun_map.simps *) |
489 (* *) |
495 (* *) |
490 (* 3. simplification with *) |
496 (* 3. simplification with *) |
491 (* thm lambda_prs *) |
497 (* thm lambda_prs *) |
492 (* *) |
498 (* *) |
493 (* 4. simplification with *) |
499 (* 4. simplification with *) |
494 (* thm Quotient_abs_rep Quotient_rel_rep id_simps *) |
500 (* thm Quotient_abs_rep Quotient_rel_rep id_simps *) |
495 (* *) |
501 (* *) |
496 (* 5. Test for refl *) |
502 (* 5. test for refl *) |
497 |
503 |
498 fun clean_tac_aux lthy = |
504 fun clean_tac_aux lthy = |
499 let |
505 let |
500 val thy = ProofContext.theory_of lthy; |
506 val thy = ProofContext.theory_of lthy; |
501 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
507 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
540 (K (EVERY1 [inst_spec_tac (rev cvrs), atac])) |
549 (K (EVERY1 [inst_spec_tac (rev cvrs), atac])) |
541 in |
550 in |
542 rtac rule i |
551 rtac rule i |
543 end) |
552 end) |
544 |
553 |
545 |
554 (**********************************************) |
546 (* The General Shape of the Lifting Procedure *) |
555 (* The General Shape of the Lifting Procedure *) |
|
556 (**********************************************) |
547 |
557 |
548 (* - A is the original raw theorem *) |
558 (* - A is the original raw theorem *) |
549 (* - B is the regularized theorem *) |
559 (* - B is the regularized theorem *) |
550 (* - C is the rep/abs injected version of B *) |
560 (* - C is the rep/abs injected version of B *) |
551 (* - D is the lifted theorem *) |
561 (* - D is the lifted theorem *) |
552 (* *) |
562 (* *) |
553 (* - 1st prem is the regularization step *) |
563 (* - 1st prem is the regularization step *) |
554 (* - 2nd prem is the rep/abs injection step *) |
564 (* - 2nd prem is the rep/abs injection step *) |
555 (* - 3rd prem is the cleaning part *) |
565 (* - 3rd prem is the cleaning part *) |
556 (* *) |
566 (* *) |
557 (* the QUOT_TRUE premise in 2 records the lifted theorem *) |
567 (* the Quot_True premise in 2 records the lifted theorem *) |
558 |
568 |
559 val lifting_procedure = |
569 val lifting_procedure = |
560 @{lemma "[|A; |
570 @{lemma "[|A; |
561 A --> B; |
571 A --> B; |
562 QUOT_TRUE D ==> B = C; |
572 Quot_True D ==> B = C; |
563 C = D|] ==> D" |
573 C = D|] ==> D" |
564 by (simp add: QUOT_TRUE_def)} |
574 by (simp add: Quot_True_def)} |
565 |
575 |
566 fun lift_match_error ctxt fun_str rtrm qtrm = |
576 fun lift_match_error ctxt str rtrm qtrm = |
567 let |
577 let |
568 val rtrm_str = Syntax.string_of_term ctxt rtrm |
578 val rtrm_str = Syntax.string_of_term ctxt rtrm |
569 val qtrm_str = Syntax.string_of_term ctxt qtrm |
579 val qtrm_str = Syntax.string_of_term ctxt qtrm |
570 val msg = cat_lines [enclose "[" "]" fun_str, "The quotient theorem", qtrm_str, |
580 val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, |
571 "", "does not match with original theorem", rtrm_str] |
581 "", "does not match with original theorem", rtrm_str] |
572 in |
582 in |
573 error msg |
583 error msg |
574 end |
584 end |
575 |
585 |
578 val thy = ProofContext.theory_of ctxt |
588 val thy = ProofContext.theory_of ctxt |
579 val rtrm' = HOLogic.dest_Trueprop rtrm |
589 val rtrm' = HOLogic.dest_Trueprop rtrm |
580 val qtrm' = HOLogic.dest_Trueprop qtrm |
590 val qtrm' = HOLogic.dest_Trueprop qtrm |
581 val reg_goal = |
591 val reg_goal = |
582 Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm') |
592 Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm') |
583 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
593 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
584 val inj_goal = |
594 val inj_goal = |
585 Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm')) |
595 Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm')) |
586 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
596 handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm |
587 in |
597 in |
588 Drule.instantiate' [] |
598 Drule.instantiate' [] |
589 [SOME (cterm_of thy rtrm'), |
599 [SOME (cterm_of thy rtrm'), |
590 SOME (cterm_of thy reg_goal), |
600 SOME (cterm_of thy reg_goal), |
591 NONE, |
601 NONE, |