142 (* the auxiliary data for the quotient types *) |
142 (* the auxiliary data for the quotient types *) |
143 use "quotient_info.ML" |
143 use "quotient_info.ML" |
144 |
144 |
145 declare [[map * = (prod_fun, prod_rel)]] |
145 declare [[map * = (prod_fun, prod_rel)]] |
146 declare [[map "fun" = (fun_map, fun_rel)]] |
146 declare [[map "fun" = (fun_map, fun_rel)]] |
147 (* FIXME: This should throw an exception: |
147 |
148 declare [[map "option" = (bla, blu)]] |
148 (* Throws now an exception: *) |
149 *) |
149 (* declare [[map "option" = (bla, blu)]] *) |
150 |
150 |
151 (* identity quotient is not here as it has to be applied first *) |
|
152 lemmas [quotient_thm] = |
151 lemmas [quotient_thm] = |
153 fun_quotient prod_quotient |
152 fun_quotient prod_quotient |
154 |
153 |
155 lemmas [quotient_rsp] = |
154 lemmas [quotient_rsp] = |
156 quot_rel_rsp pair_rsp |
155 quot_rel_rsp pair_rsp |
158 (* fun_map is not here since equivp is not true *) |
157 (* fun_map is not here since equivp is not true *) |
159 (* TODO: option, ... *) |
158 (* TODO: option, ... *) |
160 lemmas [quotient_equiv] = |
159 lemmas [quotient_equiv] = |
161 identity_equivp prod_equivp |
160 identity_equivp prod_equivp |
162 |
161 |
163 ML {* maps_lookup @{theory} "*" *} |
|
164 ML {* maps_lookup @{theory} "fun" *} |
|
165 |
|
166 |
|
167 (* definition of the quotient types *) |
162 (* definition of the quotient types *) |
168 (* FIXME: should be called quotient_typ.ML *) |
163 (* FIXME: should be called quotient_typ.ML *) |
169 use "quotient.ML" |
164 use "quotient.ML" |
170 |
165 |
171 |
|
172 (* lifting of constants *) |
166 (* lifting of constants *) |
173 use "quotient_def.ML" |
167 use "quotient_def.ML" |
174 |
168 |
175 section {* Simset setup *} |
169 section {* Simset setup *} |
176 |
170 |
177 (* since HOL_basic_ss is too "big", we need to set up *) |
171 (* Since HOL_basic_ss is too "big" for us, *) |
178 (* our own minimal simpset *) |
172 (* we set up our own minimal simpset. *) |
179 ML {* |
173 ML {* |
180 fun mk_minimal_ss ctxt = |
174 fun mk_minimal_ss ctxt = |
181 Simplifier.context ctxt empty_ss |
175 Simplifier.context ctxt empty_ss |
182 setsubgoaler asm_simp_tac |
176 setsubgoaler asm_simp_tac |
183 setmksimps (mksimps []) |
177 setmksimps (mksimps []) |
184 *} |
178 *} |
185 |
179 |
186 ML {* |
180 ML {* |
187 (* TODO/FIXME not needed anymore? *) |
181 fun OF1 thm1 thm2 = thm2 RS thm1 |
188 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) |
182 *} |
189 *} |
183 |
190 |
184 section {* Atomize Infrastructure *} |
191 section {* atomize *} |
|
192 |
185 |
193 lemma atomize_eqv[atomize]: |
186 lemma atomize_eqv[atomize]: |
194 shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)" |
187 shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)" |
195 proof |
188 proof |
196 assume "A \<equiv> B" |
189 assume "A \<equiv> B" |
218 in |
211 in |
219 @{thm equal_elim_rule1} OF [thm'', thm'] |
212 @{thm equal_elim_rule1} OF [thm'', thm'] |
220 end |
213 end |
221 *} |
214 *} |
222 |
215 |
223 section {* infrastructure about id *} |
216 section {* Infrastructure about id *} |
|
217 |
|
218 print_attributes |
224 |
219 |
225 (* TODO: think where should this be *) |
220 (* TODO: think where should this be *) |
226 lemma prod_fun_id: "prod_fun id id \<equiv> id" |
221 lemma prod_fun_id: "prod_fun id id \<equiv> id" |
227 by (rule eq_reflection) (simp add: prod_fun_def) |
222 by (rule eq_reflection) (simp add: prod_fun_def) |
228 |
223 |
229 (* FIXME: make it a list and add map_id to it *) |
224 lemmas [id_simps] = |
230 lemmas id_simps = |
|
231 fun_map_id[THEN eq_reflection] |
225 fun_map_id[THEN eq_reflection] |
232 id_apply[THEN eq_reflection] |
226 id_apply[THEN eq_reflection] |
233 id_def[THEN eq_reflection,symmetric] |
227 id_def[THEN eq_reflection,symmetric] |
234 prod_fun_id |
228 prod_fun_id |
235 |
|
236 ML {* |
|
237 fun simp_ids thm = |
|
238 MetaSimplifier.rewrite_rule @{thms id_simps} thm |
|
239 *} |
|
240 |
229 |
241 section {* Debugging infrastructure for testing tactics *} |
230 section {* Debugging infrastructure for testing tactics *} |
242 |
231 |
243 ML {* |
232 ML {* |
244 fun my_print_tac ctxt s i thm = |
233 fun my_print_tac ctxt s i thm = |
276 s = s' andalso |
265 s = s' andalso |
277 if (length tys = length tys') |
266 if (length tys = length tys') |
278 then (List.all matches_typ (tys ~~ tys')) |
267 then (List.all matches_typ (tys ~~ tys')) |
279 else false |
268 else false |
280 | _ => false |
269 | _ => false |
281 *} |
270 |
282 |
|
283 ML {* |
|
284 fun matches_term (trm, trm') = |
271 fun matches_term (trm, trm') = |
285 case (trm, trm') of |
272 case (trm, trm') of |
286 (_, Var _) => true |
273 (_, Var _) => true |
287 | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') |
274 | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') |
288 | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') |
275 | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') |
290 | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') |
277 | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') |
291 | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') |
278 | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') |
292 | _ => false |
279 | _ => false |
293 *} |
280 *} |
294 |
281 |
295 section {* Infrastructure for collecting theorems for starting the lifting *} |
282 section {* Computation of the Regularize Goal *} |
296 |
|
297 ML {* |
|
298 fun lookup_quot_data lthy qty = |
|
299 let |
|
300 val qty_name = fst (dest_Type qty) |
|
301 val SOME quotdata = quotdata_lookup lthy qty_name |
|
302 (* TODO: Should no longer be needed *) |
|
303 val rty = Logic.unvarifyT (#rtyp quotdata) |
|
304 val rel = #rel quotdata |
|
305 val rel_eqv = #equiv_thm quotdata |
|
306 val rel_refl = @{thm equivp_reflp} OF [rel_eqv] |
|
307 in |
|
308 (rty, rel, rel_refl, rel_eqv) |
|
309 end |
|
310 *} |
|
311 |
|
312 ML {* |
|
313 fun lookup_quot_thms lthy qty_name = |
|
314 let |
|
315 val thy = ProofContext.theory_of lthy; |
|
316 val trans2 = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".R_trans2") |
|
317 val reps_same = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".REPS_same") |
|
318 val absrep = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".thm10") |
|
319 val quot = PureThy.get_thm thy ("Quotient_" ^ qty_name) |
|
320 in |
|
321 (trans2, reps_same, absrep, quot) |
|
322 end |
|
323 *} |
|
324 |
|
325 section {* Regularization *} |
|
326 |
283 |
327 (* |
284 (* |
328 Regularizing an rtrm means: |
285 Regularizing an rtrm means: |
329 - quantifiers over a type that needs lifting are replaced by |
286 - quantifiers over a type that needs lifting are replaced by |
330 bounded quantifiers, for example: |
287 bounded quantifiers, for example: |
558 |
515 |
559 lemma eq_imp_rel: |
516 lemma eq_imp_rel: |
560 shows "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b" |
517 shows "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b" |
561 by (simp add: equivp_reflp) |
518 by (simp add: equivp_reflp) |
562 |
519 |
563 (* FIXME/TODO: How does regularizing work? *) |
520 |
564 (* FIXME/TODO: needs to be adapted |
521 (* Regularize Tactic *) |
565 |
522 |
566 To prove that the raw theorem implies the regularised one, |
523 (* 0. preliminary simplification step according to *) |
567 we try in order: |
524 thm ball_reg_eqv bex_reg_eqv babs_reg_eqv (* the latter of no use *) |
568 |
525 ball_reg_eqv_range bex_reg_eqv_range |
569 - Reflexivity of the relation |
526 (* 1. eliminating simple Ball/Bex instances*) |
570 - Assumption |
527 thm ball_reg_right bex_reg_left |
571 - Elimnating quantifiers on both sides of toplevel implication |
528 (* 2. monos *) |
572 - Simplifying implications on both sides of toplevel implication |
529 (* 3. commutation rules for ball and bex *) |
573 - Ball (Respects ?E) ?P = All ?P |
530 thm ball_all_comm bex_ex_comm |
574 - (\<And>x. ?R x \<Longrightarrow> ?P x \<longrightarrow> ?Q x) \<Longrightarrow> All ?P \<longrightarrow> Ball ?R ?Q |
531 (* 4. then rel-equality (which need to be instantiated to avoid loops *) |
575 |
532 thm eq_imp_rel |
576 *) |
533 (* 5. then simplification like 0 *) |
|
534 (* finally jump back to 1 *) |
|
535 |
|
536 |
577 ML {* |
537 ML {* |
578 fun regularize_tac ctxt = |
538 fun regularize_tac ctxt = |
579 let |
539 let |
580 val thy = ProofContext.theory_of ctxt |
540 val thy = ProofContext.theory_of ctxt |
581 val pat_ball = @{term "Ball (Respects (R1 ===> R2)) P"} |
541 val pat_ball = @{term "Ball (Respects (R1 ===> R2)) P"} |
584 val simpset = (mk_minimal_ss ctxt) |
544 val simpset = (mk_minimal_ss ctxt) |
585 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv} |
545 addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv} |
586 addsimprocs [simproc] addSolver equiv_solver |
546 addsimprocs [simproc] addSolver equiv_solver |
587 (* TODO: Make sure that there are no list_rel, pair_rel etc involved *) |
547 (* TODO: Make sure that there are no list_rel, pair_rel etc involved *) |
588 (* can this cause loops in equiv_tac ? *) |
548 (* can this cause loops in equiv_tac ? *) |
589 val eq_eqvs = map (fn x => @{thm eq_imp_rel} OF [x]) (equiv_rules_get ctxt) |
549 val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt) |
590 in |
550 in |
591 simp_tac simpset THEN' |
551 simp_tac simpset THEN' |
592 REPEAT_ALL_NEW (CHANGED o FIRST' [ |
552 REPEAT_ALL_NEW (CHANGED o FIRST' [ |
593 rtac @{thm ball_reg_right}, |
553 resolve_tac @{thms ball_reg_right bex_reg_left}, |
594 rtac @{thm bex_reg_left}, |
|
595 resolve_tac (Inductive.get_monos ctxt), |
554 resolve_tac (Inductive.get_monos ctxt), |
596 rtac @{thm ball_all_comm}, |
555 resolve_tac @{thms ball_all_comm bex_ex_comm}, |
597 rtac @{thm bex_ex_comm}, |
|
598 resolve_tac eq_eqvs, |
556 resolve_tac eq_eqvs, |
599 (* should be equivalent to the above, but causes loops: *) |
|
600 (* rtac @{thm eq_imp_rel} THEN' SOLVES' (equiv_tac ctxt), *) |
|
601 (* the culprit is aslread rtac @{thm eq_imp_rel} *) |
|
602 simp_tac simpset]) |
557 simp_tac simpset]) |
603 end |
558 end |
604 *} |
559 *} |
605 |
560 |
606 section {* Injections of rep and abses *} |
561 section {* Calculation of the Injected Goal *} |
607 |
562 |
608 (* |
563 (* |
609 Injecting repabs means: |
564 Injecting repabs means: |
610 |
565 |
611 For abstractions: |
566 For abstractions: |
656 val (y, s) = Term.dest_abs (x, T, t) |
611 val (y, s) = Term.dest_abs (x, T, t) |
657 val (_, s') = Term.dest_abs (x', T', t') |
612 val (_, s') = Term.dest_abs (x', T', t') |
658 val yvar = Free (y, T) |
613 val yvar = Free (y, T) |
659 val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s')) |
614 val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s')) |
660 in |
615 in |
661 if rty = qty |
616 if rty = qty then result |
662 then result |
|
663 else mk_repabs lthy (rty, qty) result |
617 else mk_repabs lthy (rty, qty) result |
664 end |
618 end |
665 |
619 |
666 | (t $ s, t' $ s') => |
620 | (t $ s, t' $ s') => |
667 (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s')) |
621 (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s')) |
668 |
622 |
669 | (Free (_, T), Free (_, T')) => |
623 | (Free (_, T), Free (_, T')) => |
670 if T = T' |
624 if T = T' then rtrm |
671 then rtrm |
|
672 else mk_repabs lthy (T, T') rtrm |
625 else mk_repabs lthy (T, T') rtrm |
673 |
626 |
674 | (_, Const (@{const_name "op ="}, _)) => rtrm |
627 | (_, Const (@{const_name "op ="}, _)) => rtrm |
675 |
628 |
676 (* FIXME: check here that rtrm is the corresponding definition for the const *) |
629 (* FIXME: check here that rtrm is the corresponding definition for the const *) |
677 | (_, Const (_, T')) => |
630 | (_, Const (_, T')) => |
678 let |
631 let |
679 val rty = fastype_of rtrm |
632 val rty = fastype_of rtrm |
680 in |
633 in |
681 if rty = T' |
634 if rty = T' then rtrm |
682 then rtrm |
|
683 else mk_repabs lthy (rty, T') rtrm |
635 else mk_repabs lthy (rty, T') rtrm |
684 end |
636 end |
685 |
637 |
686 | _ => raise (LIFT_MATCH "injection") |
638 | _ => raise (LIFT_MATCH "injection") |
687 *} |
639 *} |
688 |
640 |
689 section {* RepAbs Injection Tactic *} |
641 section {* Injection Tactic *} |
690 |
642 |
691 ML {* |
643 ML {* |
692 fun quotient_tac ctxt = |
644 fun quotient_tac ctxt = |
693 REPEAT_ALL_NEW (FIRST' |
645 REPEAT_ALL_NEW (FIRST' |
694 [rtac @{thm identity_quotient}, |
646 [rtac @{thm identity_quotient}, |
695 resolve_tac (quotient_rules_get ctxt)]) |
647 resolve_tac (quotient_rules_get ctxt)]) |
696 *} |
648 |
697 |
|
698 (* solver for the simplifier *) |
|
699 ML {* |
|
700 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
649 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
701 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
650 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
702 *} |
651 *} |
703 |
652 |
704 ML {* |
653 ML {* |
705 fun solve_quotient_assums ctxt thm = |
654 fun solve_quotient_assums ctxt thm = |
706 let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in |
655 let |
707 thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)] |
656 val goal = hd (Drule.strip_imp_prems (cprop_of thm)) |
708 end |
657 in |
709 handle _ => error "solve_quotient_assums failed. Maybe a quotient_thm is missing" |
658 thm OF [Goal.prove_internal [] goal (fn _ => quotient_tac ctxt 1)] |
|
659 end |
|
660 handle _ => error "solve_quotient_assums failed. Maybe a quotient_thm is missing" |
710 *} |
661 *} |
711 |
662 |
712 (* Not used *) |
663 (* Not used *) |
713 (* It proves the Quotient assumptions by calling quotient_tac *) |
664 (* It proves the Quotient assumptions by calling quotient_tac *) |
714 ML {* |
665 ML {* |
912 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _)) |
863 (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _)) |
913 => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt] |
864 => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt] |
914 |
865 |
915 (* reflexivity of operators arising from Cong_tac *) |
866 (* reflexivity of operators arising from Cong_tac *) |
916 | Const (@{const_name "op ="},_) $ _ $ _ |
867 | Const (@{const_name "op ="},_) $ _ $ _ |
917 => rtac @{thm refl} ORELSE' |
868 => rtac @{thm refl} (*ORELSE' |
918 (resolve_tac trans2 THEN' RANGE [ |
869 (resolve_tac trans2 THEN' RANGE [ |
919 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)]) |
870 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)])*) |
920 |
871 |
921 (* TODO: These patterns should should be somehow combined and generalized... *) |
872 (* TODO: These patterns should should be somehow combined and generalized... *) |
922 | (Const (@{const_name fun_rel}, _) $ _ $ _) $ |
873 | (Const (@{const_name fun_rel}, _) $ _ $ _) $ |
923 (Const (@{const_name fun_rel}, _) $ _ $ _) $ |
874 (Const (@{const_name fun_rel}, _) $ _ $ _) $ |
924 (Const (@{const_name fun_rel}, _) $ _ $ _) |
875 (Const (@{const_name fun_rel}, _) $ _ $ _) |
941 | _ => error "inj_repabs_tac not a relation" |
892 | _ => error "inj_repabs_tac not a relation" |
942 ) i) |
893 ) i) |
943 *} |
894 *} |
944 |
895 |
945 ML {* |
896 ML {* |
946 fun inj_repabs_tac ctxt rel_refl trans2 = |
897 fun inj_repabs_step_tac ctxt rel_refl trans2 = |
947 (FIRST' [ |
898 (FIRST' [ |
948 inj_repabs_tac_match ctxt trans2, |
899 NDT ctxt "0" (inj_repabs_tac_match ctxt trans2), |
949 (* R (t $ \<dots>) (t' $ \<dots>) ----> apply_rsp provided type of t needs lifting *) |
900 (* R (t $ \<dots>) (t' $ \<dots>) ----> apply_rsp provided type of t needs lifting *) |
|
901 |
950 NDT ctxt "A" (apply_rsp_tac ctxt THEN' |
902 NDT ctxt "A" (apply_rsp_tac ctxt THEN' |
951 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])), |
903 RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)]), |
|
904 |
|
905 (* TODO/FIXME: I had to move this after the apply_rsp_tac - is this right *) |
|
906 NDT ctxt "B" (resolve_tac trans2 THEN' |
|
907 RANGE [quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)]), |
|
908 |
952 (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong provided type of t does not need lifting *) |
909 (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong provided type of t does not need lifting *) |
953 (* merge with previous tactic *) |
910 (* merge with previous tactic *) |
954 NDT ctxt "B" (Cong_Tac.cong_tac @{thm cong} THEN' |
911 NDT ctxt "C" (Cong_Tac.cong_tac @{thm cong} THEN' |
955 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])), |
912 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])), |
|
913 |
956 (* (op =) (\<lambda>x\<dots>) (\<lambda>x\<dots>) ----> (op =) (\<dots>) (\<dots>) *) |
914 (* (op =) (\<lambda>x\<dots>) (\<lambda>x\<dots>) ----> (op =) (\<dots>) (\<dots>) *) |
957 NDT ctxt "C" (rtac @{thm ext} THEN' quot_true_tac ctxt unlam), |
915 NDT ctxt "D" (rtac @{thm ext} THEN' quot_true_tac ctxt unlam), |
|
916 |
958 (* resolving with R x y assumptions *) |
917 (* resolving with R x y assumptions *) |
959 NDT ctxt "E" (atac), |
918 NDT ctxt "E" (atac), |
|
919 |
960 (* reflexivity of the basic relations *) |
920 (* reflexivity of the basic relations *) |
961 (* R \<dots> \<dots> *) |
921 (* R \<dots> \<dots> *) |
962 NDT ctxt "D" (resolve_tac rel_refl) |
922 NDT ctxt "F" (resolve_tac rel_refl) |
963 ]) |
923 ]) |
964 *} |
924 *} |
965 |
925 |
966 ML {* |
926 ML {* |
967 fun all_inj_repabs_tac ctxt rel_refl trans2 = |
927 fun inj_repabs_tac ctxt = |
968 REPEAT_ALL_NEW (inj_repabs_tac ctxt rel_refl trans2) |
928 let |
969 *} |
929 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
970 |
930 val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt) |
971 section {* Cleaning of the theorem *} |
931 in |
|
932 inj_repabs_step_tac ctxt rel_refl trans2 |
|
933 end |
|
934 |
|
935 fun all_inj_repabs_tac ctxt = |
|
936 REPEAT_ALL_NEW (inj_repabs_tac ctxt) |
|
937 *} |
|
938 |
|
939 section {* Cleaning of the Theorem *} |
972 |
940 |
973 ML {* |
941 ML {* |
974 fun make_inst lhs t = |
942 fun make_inst lhs t = |
975 let |
943 let |
976 val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; |
944 val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; |
1015 val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs} |
983 val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs} |
1016 val te = @{thm eq_reflection} OF [solve_quotient_assums ctxt (solve_quotient_assums ctxt lpi)] |
984 val te = @{thm eq_reflection} OF [solve_quotient_assums ctxt (solve_quotient_assums ctxt lpi)] |
1017 val _ = tracing ("te rule:\n" ^ (Syntax.string_of_term ctxt (prop_of te))); |
985 val _ = tracing ("te rule:\n" ^ (Syntax.string_of_term ctxt (prop_of te))); |
1018 val ti = |
986 val ti = |
1019 (let |
987 (let |
1020 val ts = MetaSimplifier.rewrite_rule @{thms id_simps} te |
988 val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te |
1021 val (insp, inst) = make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
989 val (insp, inst) = make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
1022 in |
990 in |
1023 Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
991 Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
1024 end handle _ => (* TODO handle only Bind | Error "make_inst" *) |
992 end handle _ => (* TODO handle only Bind | Error "make_inst" *) |
1025 let |
993 let |
1026 val (insp, inst) = make_inst2 (term_of (Thm.lhs_of te)) (term_of ctrm) |
994 val (insp, inst) = make_inst2 (term_of (Thm.lhs_of te)) (term_of ctrm) |
1027 val td = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) te |
995 val td = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) te |
1028 in |
996 in |
1029 MetaSimplifier.rewrite_rule @{thms id_simps} td |
997 MetaSimplifier.rewrite_rule (id_simps_get ctxt) td |
1030 end); |
998 end); |
1031 val _ = if not (Term.is_Const a2 andalso fst (dest_Const a2) = @{const_name "id"}) then |
999 val _ = if not (Term.is_Const a2 andalso fst (dest_Const a2) = @{const_name "id"}) then |
1032 (tracing "lambda_prs"; |
1000 (tracing "lambda_prs"; |
1033 tracing ("redex:\n" ^ (Syntax.string_of_term ctxt (term_of ctrm))); |
1001 tracing ("redex:\n" ^ (Syntax.string_of_term ctxt (term_of ctrm))); |
1034 tracing ("lpi rule:\n" ^ (Syntax.string_of_term ctxt (prop_of lpi))); |
1002 tracing ("lpi rule:\n" ^ (Syntax.string_of_term ctxt (prop_of lpi))); |
1047 More_Conv.top_conv lambda_prs_simple_conv |
1015 More_Conv.top_conv lambda_prs_simple_conv |
1048 |
1016 |
1049 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
1017 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
1050 *} |
1018 *} |
1051 |
1019 |
1052 (* |
1020 (* 1. conversion (is not a pattern) *) |
1053 Cleaning the theorem consists of three rewriting steps. |
1021 thm lambda_prs |
1054 The first two need to be done before fun_map is unfolded |
1022 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *) |
1055 |
1023 (* and simplification with *) |
1056 1) lambda_prs: |
1024 thm all_prs ex_prs |
1057 (Rep1 ---> Abs2) (\<lambda>x. Rep2 (f (Abs1 x))) ----> f |
1025 (* 3. simplification with *) |
1058 |
1026 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep id_simps |
1059 Implemented as conversion since it is not a pattern. |
1027 (* 4. Test for refl *) |
1060 |
|
1061 2) all_prs (the same for exists): |
|
1062 Ball (Respects R) ((abs ---> id) f) ----> All f |
|
1063 |
|
1064 Rewriting with definitions from the argument defs |
|
1065 (rep ---> abs) oldConst ----> newconst |
|
1066 |
|
1067 3) Quotient_rel_rep: |
|
1068 Rel (Rep x) (Rep y) ----> x = y |
|
1069 |
|
1070 Quotient_abs_rep: |
|
1071 Abs (Rep x) ----> x |
|
1072 |
|
1073 id_simps; fun_map.simps |
|
1074 *) |
|
1075 |
1028 |
1076 ML {* |
1029 ML {* |
1077 fun clean_tac lthy = |
1030 fun clean_tac lthy = |
1078 let |
1031 let |
1079 val thy = ProofContext.theory_of lthy; |
1032 val thy = ProofContext.theory_of lthy; |
1080 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
1033 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
1081 (* FIXME: shouldn't the definitions already be varified? *) |
1034 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
1082 val thms1 = @{thms all_prs ex_prs} @ defs |
1035 val thms1 = @{thms all_prs ex_prs} @ defs |
1083 val thms2 = @{thms eq_reflection[OF fun_map.simps]} |
1036 val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy) |
1084 @ @{thms id_simps Quotient_abs_rep Quotient_rel_rep} |
1037 @ @{thms Quotient_abs_rep Quotient_rel_rep} |
1085 fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
1038 fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
1086 in |
1039 in |
1087 EVERY' [lambda_prs_tac lthy, |
1040 EVERY' [lambda_prs_tac lthy, |
1088 simp_tac (simps thms1), |
1041 simp_tac (simps thms1), |
1089 simp_tac (simps thms2), |
1042 simp_tac (simps thms2), |
1090 TRY o rtac refl] |
1043 TRY o rtac refl] |
1091 end |
1044 end |
1092 *} |
1045 *} |
1093 |
1046 |
1094 section {* Genralisation of free variables in a goal *} |
1047 section {* Tactic for genralisation of free variables in a goal *} |
1095 |
1048 |
1096 ML {* |
1049 ML {* |
1097 fun inst_spec ctrm = |
1050 fun inst_spec ctrm = |
1098 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
1051 Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec} |
1099 |
1052 |
1160 val rtrm' = HOLogic.dest_Trueprop rtrm |
1113 val rtrm' = HOLogic.dest_Trueprop rtrm |
1161 val qtrm' = HOLogic.dest_Trueprop qtrm |
1114 val qtrm' = HOLogic.dest_Trueprop qtrm |
1162 val reg_goal = |
1115 val reg_goal = |
1163 Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm') |
1116 Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm') |
1164 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
1117 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
1165 val _ = warning "Regularization done." |
|
1166 val inj_goal = |
1118 val inj_goal = |
1167 Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm')) |
1119 Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm')) |
1168 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
1120 handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm |
1169 val _ = warning "RepAbs Injection done." |
|
1170 in |
1121 in |
1171 Drule.instantiate' [] |
1122 Drule.instantiate' [] |
1172 [SOME (cterm_of thy rtrm'), |
1123 [SOME (cterm_of thy rtrm'), |
1173 SOME (cterm_of thy reg_goal), |
1124 SOME (cterm_of thy reg_goal), |
1174 SOME (cterm_of thy inj_goal)] @{thm lifting_procedure} |
1125 SOME (cterm_of thy inj_goal)] @{thm lifting_procedure} |
1175 end |
1126 end |
1176 *} |
1127 *} |
1177 |
1128 |
1178 (* Left for debugging *) |
1129 ML {* |
1179 ML {* |
1130 (* the tactic leaves three subgoals to be proved *) |
1180 fun procedure_tac ctxt rthm = |
1131 fun procedure_tac ctxt rthm = |
1181 ObjectLogic.full_atomize_tac |
1132 ObjectLogic.full_atomize_tac |
1182 THEN' gen_frees_tac ctxt |
1133 THEN' gen_frees_tac ctxt |
1183 THEN' CSUBGOAL (fn (gl, i) => |
1134 THEN' CSUBGOAL (fn (goal, i) => |
1184 let |
1135 let |
1185 val rthm' = atomize_thm rthm |
1136 val rthm' = atomize_thm rthm |
1186 val rule = procedure_inst ctxt (prop_of rthm') (term_of gl) |
1137 val rule = procedure_inst ctxt (prop_of rthm') (term_of goal) |
1187 val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i} |
1138 val bare_goal = snd (Thm.dest_comb goal) |
|
1139 val quot_weak = Drule.instantiate' [] [SOME bare_goal] @{thm QUOT_TRUE_i} |
1188 in |
1140 in |
1189 (rtac rule THEN' RANGE [rtac rthm', (fn _ => all_tac), rtac thm]) i |
1141 (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i |
1190 end) |
1142 end) |
1191 *} |
1143 *} |
1192 |
1144 |
1193 ML {* |
1145 (* automatic proofs *) |
1194 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *) |
1146 ML {* |
1195 |
1147 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac) |
|
1148 |
|
1149 fun WARN (tac, msg) i st = |
|
1150 case Seq.pull ((SOLVES' tac) i st) of |
|
1151 NONE => (warning msg; Seq.single st) |
|
1152 | seqcell => Seq.make (fn () => seqcell) |
|
1153 |
|
1154 fun RANGE_WARN xs = RANGE (map WARN xs) |
|
1155 *} |
|
1156 |
|
1157 ML {* |
1196 fun lift_tac ctxt rthm = |
1158 fun lift_tac ctxt rthm = |
1197 ObjectLogic.full_atomize_tac |
1159 procedure_tac ctxt rthm |
1198 THEN' gen_frees_tac ctxt |
1160 THEN' RANGE_WARN [(regularize_tac ctxt, "Regularize proof failed."), |
1199 THEN' CSUBGOAL (fn (gl, i) => |
1161 (all_inj_repabs_tac ctxt, "Injection proof failed."), |
1200 let |
1162 (clean_tac ctxt, "Cleaning proof failed.")] |
1201 val rthm' = atomize_thm rthm |
1163 *} |
1202 val rule = procedure_inst ctxt (prop_of rthm') (term_of gl) |
1164 |
1203 val rel_refl = map (fn x => @{thm equivp_reflp} OF [x]) (equiv_rules_get ctxt) |
1165 end |
1204 val quotients = quotient_rules_get ctxt |
1166 |
1205 val trans2 = map (fn x => @{thm equals_rsp} OF [x]) quotients |
|
1206 val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i} |
|
1207 in |
|
1208 (rtac rule THEN' |
|
1209 RANGE [rtac rthm', |
|
1210 regularize_tac ctxt, |
|
1211 rtac thm THEN' all_inj_repabs_tac ctxt rel_refl trans2, |
|
1212 clean_tac ctxt]) i |
|
1213 end) |
|
1214 *} |
|
1215 |
|
1216 end |
|
1217 |
|