200 Regularizing a theorem means: |
200 Regularizing a theorem means: |
201 - Quantifiers over a type that needs lifting are replaced by |
201 - Quantifiers over a type that needs lifting are replaced by |
202 bounded quantifiers, for example: |
202 bounded quantifiers, for example: |
203 \<forall>x. P \<Longrightarrow> \<forall>x\<in>(Respects R). P |
203 \<forall>x. P \<Longrightarrow> \<forall>x\<in>(Respects R). P |
204 - Abstractions over a type that needs lifting are replaced |
204 - Abstractions over a type that needs lifting are replaced |
205 by bounded abstactions: |
205 by bounded abstractions: |
206 \<lambda>x. P \<Longrightarrow> Ball (Respects R) (\<lambda>x. P) |
206 \<lambda>x. P \<Longrightarrow> Ball (Respects R) (\<lambda>x. P) |
207 |
207 |
208 - Equalities over the type being lifted are replaced by |
208 - Equalities over the type being lifted are replaced by |
209 appropriate relations: |
209 appropriate relations: |
210 A = B \<Longrightarrow> A \<approx> B |
210 A = B \<Longrightarrow> A \<approx> B |
239 val tys_rel = map (fn ty => ty --> ty --> @{typ bool}) tys; |
239 val tys_rel = map (fn ty => ty --> ty --> @{typ bool}) tys; |
240 val ty_out = ty --> ty --> @{typ bool}; |
240 val ty_out = ty --> ty --> @{typ bool}; |
241 val tys_out = tys_rel ---> ty_out; |
241 val tys_out = tys_rel ---> ty_out; |
242 in |
242 in |
243 (case (maps_lookup (ProofContext.theory_of lthy) s) of |
243 (case (maps_lookup (ProofContext.theory_of lthy) s) of |
244 SOME (info) => list_comb (Const (#relfun info, tys_out), map (fn ty => tyRel ty rty rel lthy) tys) |
244 SOME (info) => list_comb (Const (#relfun info, tys_out), |
|
245 map (fn ty => tyRel ty rty rel lthy) tys) |
245 | NONE => HOLogic.eq_const ty |
246 | NONE => HOLogic.eq_const ty |
246 ) |
247 ) |
247 end |
248 end |
248 | _ => HOLogic.eq_const ty) |
249 | _ => HOLogic.eq_const ty) |
249 *} |
250 *} |
339 (my_reg lthy (Const (n, dummyT)) (Logic.varifyT rty) trm) |
340 (my_reg lthy (Const (n, dummyT)) (Logic.varifyT rty) trm) |
340 *} |
341 *} |
341 |
342 |
342 (* |
343 (* |
343 ML {* |
344 ML {* |
344 text {*val r = term_of @{cpat "R::?'a list \<Rightarrow> ?'a list \<Rightarrow> bool"};*} |
|
345 val r = Free ("R", dummyT); |
345 val r = Free ("R", dummyT); |
346 val t = (my_reg @{context} r @{typ "'a list"} @{term "\<forall>(x::'b list). P x"}); |
346 val t = (my_reg_inst @{context} r @{typ "'a list"} @{term "\<forall>(x::'b list). P x"}); |
347 val t2 = Syntax.check_term @{context} t; |
347 val t2 = Syntax.check_term @{context} t; |
348 Toplevel.program (fn () => cterm_of @{theory} t2) |
348 cterm_of @{theory} t2 |
349 *}*) |
349 *} |
|
350 *) |
350 |
351 |
351 text {* Assumes that the given theorem is atomized *} |
352 text {* Assumes that the given theorem is atomized *} |
352 ML {* |
353 ML {* |
353 fun build_regularize_goal thm rty rel lthy = |
354 fun build_regularize_goal thm rty rel lthy = |
354 Logic.mk_implies |
355 Logic.mk_implies |
355 ((prop_of thm), |
356 ((prop_of thm), |
356 (my_reg_inst lthy rel rty (prop_of thm))) |
357 (my_reg_inst lthy rel rty (prop_of thm))) |
357 *} |
358 *} |
358 |
359 |
359 lemma universal_twice: |
360 lemma universal_twice: |
360 "(\<And>x. (P x \<longrightarrow> Q x)) \<Longrightarrow> ((\<forall>x. P x) \<longrightarrow> (\<forall>x. Q x))" |
361 assumes *: "\<And>x. (P x \<longrightarrow> Q x)" |
361 by auto |
362 shows "(\<forall>x. P x) \<longrightarrow> (\<forall>x. Q x)" |
362 |
363 using * by auto |
363 lemma implication_twice: |
364 |
364 "(c \<longrightarrow> a) \<Longrightarrow> (a \<Longrightarrow> b \<longrightarrow> d) \<Longrightarrow> (a \<longrightarrow> b) \<longrightarrow> (c \<longrightarrow> d)" |
365 lemma implication_twice: |
365 by auto |
366 assumes a: "c \<longrightarrow> a" |
366 |
367 assumes b: "a \<Longrightarrow> b \<longrightarrow> d" |
367 (*lemma equality_twice: |
368 shows "(a \<longrightarrow> b) \<longrightarrow> (c \<longrightarrow> d)" |
368 "a = c \<Longrightarrow> b = d \<Longrightarrow> (a = b \<longrightarrow> c = d)" |
369 using a b by auto |
369 by auto*) |
|
370 |
370 |
371 ML {* |
371 ML {* |
372 fun regularize thm rty rel rel_eqv rel_refl lthy = |
372 fun regularize thm rty rel rel_eqv rel_refl lthy = |
373 let |
373 let |
374 val goal = build_regularize_goal thm rty rel lthy; |
374 val goal = build_regularize_goal thm rty rel lthy; |
381 (rtac @{thm impI} THEN' atac), |
381 (rtac @{thm impI} THEN' atac), |
382 rtac @{thm implication_twice}, |
382 rtac @{thm implication_twice}, |
383 EqSubst.eqsubst_tac ctxt [0] |
383 EqSubst.eqsubst_tac ctxt [0] |
384 [(@{thm equiv_res_forall} OF [rel_eqv]), |
384 [(@{thm equiv_res_forall} OF [rel_eqv]), |
385 (@{thm equiv_res_exists} OF [rel_eqv])], |
385 (@{thm equiv_res_exists} OF [rel_eqv])], |
|
386 (* For a = b \<longrightarrow> a \<approx> b *) |
386 (rtac @{thm impI} THEN' (asm_full_simp_tac HOL_ss) THEN' rtac rel_refl), |
387 (rtac @{thm impI} THEN' (asm_full_simp_tac HOL_ss) THEN' rtac rel_refl), |
387 (rtac @{thm RIGHT_RES_FORALL_REGULAR}) |
388 (rtac @{thm RIGHT_RES_FORALL_REGULAR}) |
388 ]); |
389 ]); |
389 val cthm = Goal.prove lthy [] [] goal |
390 val cthm = Goal.prove lthy [] [] goal |
390 (fn {context, ...} => tac context 1); |
391 (fn {context, ...} => tac context 1); |
394 *} |
395 *} |
395 |
396 |
396 section {* RepAbs injection *} |
397 section {* RepAbs injection *} |
397 (* |
398 (* |
398 |
399 |
399 Injecting RepAbs means: |
400 RepAbs injection is done in the following phases: |
|
401 1) build_repabs_term inserts rep-abs pairs in the term |
|
402 2) we prove the equality between the original theorem and this one |
|
403 3) we use Pure.equal_elim_rule1 to get the new theorem. |
|
404 |
|
405 build_repabs_term does: |
400 |
406 |
401 For abstractions: |
407 For abstractions: |
402 * If the type of the abstraction doesn't need lifting we recurse. |
408 * If the type of the abstraction doesn't need lifting we recurse. |
403 * If it does we add RepAbs around the whole term and check if the |
409 * If it does we add RepAbs around the whole term and check if the |
404 variable needs lifting. |
410 variable needs lifting. |
405 * If it doesn't then we recurse |
411 * If it doesn't then we recurse |
406 * If it does we recurse and put 'RepAbs' around all occurences |
412 * If it does we recurse and put 'RepAbs' around all occurences |
407 of the variable in the obtained subterm. |
413 of the variable in the obtained subterm. This in combination |
|
414 with the RepAbs above will let us change the type of the |
|
415 abstraction with rewriting. |
408 For applications: |
416 For applications: |
409 * If the term is 'Respects' applied to anything we leave it unchanged |
417 * If the term is 'Respects' applied to anything we leave it unchanged |
410 * If the term needs lifting and the head is a constant that we know |
418 * If the term needs lifting and the head is a constant that we know |
411 how to lift, we put a RepAbs and recurse |
419 how to lift, we put a RepAbs and recurse |
412 * If the term needs lifting and the head is a free applied to subterms |
420 * If the term needs lifting and the head is a free applied to subterms |
413 (if it is not applied we treated it in Abs branch) then we |
421 (if it is not applied we treated it in Abs branch) then we |
414 put RepAbs and recurse |
422 put RepAbs and recurse |
415 * Otherwise just recurse. |
423 * Otherwise just recurse. |
416 |
424 |
417 The injection is done in the following phases: |
|
418 1) build_repabs_term inserts rep-abs pairs in the term |
|
419 2) we prove the equality between the original theorem and this one |
|
420 3) we use Pure.equal_elim_rule1 to get the new theorem. |
|
421 |
425 |
422 To prove that the old theorem implies the new one, we first |
426 To prove that the old theorem implies the new one, we first |
423 atomize it and then try: |
427 atomize it and then try: |
424 |
428 |
425 1) theorems 'trans2' from the QUOT_TYPE |
429 1) theorems 'trans2' from the appropriate QUOT_TYPE |
426 2) remove lambdas from both sides (LAMBDA_RES_TAC) |
430 2) remove lambdas from both sides (LAMBDA_RES_TAC) |
427 3) remove Ball/Bex |
431 3) remove Ball/Bex from the right hand side |
428 4) use RSP theorems |
432 4) use user-supplied RSP theorems |
429 5) remove rep_abs from right side |
433 5) remove rep_abs from the right side |
430 6) reflexivity |
434 6) reflexivity of equality |
431 7) split applications of lifted type (apply_rsp) |
435 7) split applications of lifted type (apply_rsp) |
432 8) split applications of non-lifted type (cong_tac) |
436 8) split applications of non-lifted type (cong_tac) |
433 9) apply extentionality |
437 9) apply extentionality |
434 10) relation reflexive |
438 10) reflexivity of the relation |
435 11) assumption |
439 11) assumption |
|
440 (Lambdas under respects may have left us some assumptions) |
436 12) proving obvious higher order equalities by simplifying fun_rel |
441 12) proving obvious higher order equalities by simplifying fun_rel |
437 (not sure if still needed?) |
442 (not sure if it is still needed?) |
438 13) unfolding lambda on one side |
443 13) unfolding lambda on one side |
439 14) simplifying (= ===> =) for simpler respectfullness |
444 14) simplifying (= ===> =) for simpler respectfullness |
440 |
445 |
441 *) |
446 *) |
442 |
447 |
630 |
635 |
631 (* Needed to have a meta-equality *) |
636 (* Needed to have a meta-equality *) |
632 lemma id_def_sym: "(\<lambda>x. x) \<equiv> id" |
637 lemma id_def_sym: "(\<lambda>x. x) \<equiv> id" |
633 by (simp add: id_def) |
638 by (simp add: id_def) |
634 |
639 |
|
640 (* TODO: can be also obtained with: *) |
|
641 ML {* symmetric (eq_reflection OF @{thms id_def}) *} |
|
642 |
635 ML {* |
643 ML {* |
636 fun build_repabs_term lthy thm consts rty qty = |
644 fun build_repabs_term lthy thm consts rty qty = |
637 let |
645 let |
|
646 (* TODO: The rty and qty stored in the quotient_info should |
|
647 be varified, so this will soon not be needed *) |
638 val rty = Logic.varifyT rty; |
648 val rty = Logic.varifyT rty; |
639 val qty = Logic.varifyT qty; |
649 val qty = Logic.varifyT qty; |
640 |
650 |
641 fun mk_abs tm = |
651 fun mk_abs tm = |
642 let |
652 let |
689 repeat_eqsubst_prop lthy @{thms id_def_sym} |
699 repeat_eqsubst_prop lthy @{thms id_def_sym} |
690 (build_aux lthy (Thm.prop_of thm)) |
700 (build_aux lthy (Thm.prop_of thm)) |
691 end |
701 end |
692 *} |
702 *} |
693 |
703 |
694 text {* Assumes that it is given a regularized theorem *} |
704 text {* Builds provable goals for regularized theorems *} |
695 ML {* |
705 ML {* |
696 fun build_repabs_goal ctxt thm cons rty qty = |
706 fun build_repabs_goal ctxt thm cons rty qty = |
697 Logic.mk_equals ((Thm.prop_of thm), (build_repabs_term ctxt thm cons rty qty)) |
707 Logic.mk_equals ((Thm.prop_of thm), (build_repabs_term ctxt thm cons rty qty)) |
698 *} |
708 *} |
699 |
709 |
700 ML {* |
710 ML {* |
701 fun instantiate_tac thm = Subgoal.FOCUS (fn {concl, ...} => |
711 fun instantiate_tac thm = Subgoal.FOCUS (fn {concl, ...} => |
702 let |
712 let |
703 val pat = Drule.strip_imp_concl (cprop_of thm) |
713 val pat = Drule.strip_imp_concl (cprop_of thm) |
704 val insts = Thm.match (pat, concl) |
714 val insts = Thm.match (pat, concl) |
705 in |
715 in |
706 rtac (Drule.instantiate insts thm) 1 |
716 rtac (Drule.instantiate insts thm) 1 |
707 end |
717 end |
708 handle _ => no_tac |
718 handle _ => no_tac) |
709 ) |
719 *} |
|
720 |
|
721 ML {* |
|
722 fun CHANGED' tac = (fn i => CHANGED (tac i)) |
710 *} |
723 *} |
711 |
724 |
712 ML {* |
725 ML {* |
713 fun quotient_tac quot_thm = |
726 fun quotient_tac quot_thm = |
714 REPEAT_ALL_NEW (FIRST' [ |
727 REPEAT_ALL_NEW (FIRST' [ |
715 rtac @{thm FUN_QUOTIENT}, |
728 rtac @{thm FUN_QUOTIENT}, |
716 rtac quot_thm, |
729 rtac quot_thm, |
717 rtac @{thm IDENTITY_QUOTIENT}, |
730 rtac @{thm IDENTITY_QUOTIENT}, |
718 ( |
731 (* For functional identity quotients, (op = ---> op =) *) |
719 fn i => CHANGED (simp_tac (HOL_ss addsimps @{thms FUN_MAP_I}) i) THEN |
732 CHANGED' ( |
720 rtac @{thm IDENTITY_QUOTIENT} i |
733 (simp_tac (HOL_ss addsimps @{thms FUN_MAP_I})) THEN' |
|
734 rtac @{thm IDENTITY_QUOTIENT} |
721 ) |
735 ) |
722 ]) |
736 ]) |
723 *} |
737 *} |
724 |
738 |
725 ML {* |
739 ML {* |
726 fun LAMBDA_RES_TAC ctxt i st = |
740 fun LAMBDA_RES_TAC ctxt i st = |
727 (case (term_of o #concl o fst) (Subgoal.focus ctxt i st) of |
741 (case (term_of o #concl o fst) (Subgoal.focus ctxt i st) of |
728 (_ $ (_ $ (Abs(_, _, _))$(Abs(_, _, _)))) => |
742 (_ $ (_ $ (Abs(_, _, _)) $ (Abs(_, _, _)))) => |
729 (EqSubst.eqsubst_tac ctxt [0] @{thms FUN_REL.simps}) THEN' |
743 (EqSubst.eqsubst_tac ctxt [0] @{thms FUN_REL.simps}) THEN' |
730 (rtac @{thm allI}) THEN' (rtac @{thm allI}) THEN' (rtac @{thm impI}) |
744 (rtac @{thm allI}) THEN' (rtac @{thm allI}) THEN' (rtac @{thm impI}) |
731 | _ => fn _ => no_tac) i st |
745 | _ => fn _ => no_tac) i st |
732 *} |
746 *} |
733 |
747 |
747 fun APPLY_RSP_TAC rty = Subgoal.FOCUS (fn {concl, ...} => |
761 fun APPLY_RSP_TAC rty = Subgoal.FOCUS (fn {concl, ...} => |
748 let |
762 let |
749 val (_ $ (R $ (f $ _) $ (_ $ _))) = term_of concl; |
763 val (_ $ (R $ (f $ _) $ (_ $ _))) = term_of concl; |
750 val pat = Drule.strip_imp_concl (cprop_of @{thm APPLY_RSP}); |
764 val pat = Drule.strip_imp_concl (cprop_of @{thm APPLY_RSP}); |
751 val insts = Thm.match (pat, concl) |
765 val insts = Thm.match (pat, concl) |
752 in |
766 in |
753 if needs_lift rty (type_of f) then |
767 if needs_lift rty (type_of f) then |
754 rtac (Drule.instantiate insts @{thm APPLY_RSP}) 1 |
768 rtac (Drule.instantiate insts @{thm APPLY_RSP}) 1 |
755 else no_tac |
769 else no_tac |
756 end |
770 end |
757 handle _ => no_tac) |
771 handle _ => no_tac) |
758 *} |
772 *} |
759 |
773 |
760 ML {* |
774 ML {* |
761 val ball_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} => |
775 val ball_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} => |
762 let |
776 let |
795 ball_rsp_tac ctxt, |
811 ball_rsp_tac ctxt, |
796 bex_rsp_tac ctxt, |
812 bex_rsp_tac ctxt, |
797 FIRST' (map rtac rsp_thms), |
813 FIRST' (map rtac rsp_thms), |
798 (instantiate_tac @{thm REP_ABS_RSP(1)} ctxt THEN' (RANGE [quotient_tac quot_thm])), |
814 (instantiate_tac @{thm REP_ABS_RSP(1)} ctxt THEN' (RANGE [quotient_tac quot_thm])), |
799 rtac refl, |
815 rtac refl, |
800 (* rtac @{thm arg_cong2[of _ _ _ _ "op ="]},*) |
|
801 (APPLY_RSP_TAC rty ctxt THEN' (RANGE [quotient_tac quot_thm, quotient_tac quot_thm])), |
816 (APPLY_RSP_TAC rty ctxt THEN' (RANGE [quotient_tac quot_thm, quotient_tac quot_thm])), |
802 Cong_Tac.cong_tac @{thm cong}, |
817 Cong_Tac.cong_tac @{thm cong}, |
803 rtac @{thm ext}, |
818 rtac @{thm ext}, |
804 rtac reflex_thm, |
819 rtac reflex_thm, |
805 atac, |
820 atac, |
806 ( |
821 SOLVES' (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps})), |
807 (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps})) |
|
808 THEN_ALL_NEW (fn _ => no_tac) |
|
809 ), |
|
810 WEAK_LAMBDA_RES_TAC ctxt, |
822 WEAK_LAMBDA_RES_TAC ctxt, |
811 (fn i => CHANGED (asm_full_simp_tac (HOL_ss addsimps @{thms FUN_REL_EQ}) i)) |
823 CHANGED' (asm_full_simp_tac (HOL_ss addsimps @{thms FUN_REL_EQ})) |
812 ]) |
824 ]) |
813 *} |
825 *} |
814 |
826 |
815 ML {* |
827 ML {* |
816 fun repabs lthy thm consts rty qty quot_thm reflex_thm trans_thm rsp_thms = |
828 fun repabs lthy thm consts rty qty quot_thm reflex_thm trans_thm rsp_thms = |
934 val (a1, e1) = findallex_all rty qty f; |
945 val (a1, e1) = findallex_all rty qty f; |
935 val (a2, e2) = findallex_all rty qty a; |
946 val (a2, e2) = findallex_all rty qty a; |
936 in (a1 @ a2, e1 @ e2) end |
947 in (a1 @ a2, e1 @ e2) end |
937 | _ => ([], []); |
948 | _ => ([], []); |
938 *} |
949 *} |
|
950 |
939 ML {* |
951 ML {* |
940 fun findallex lthy rty qty tm = |
952 fun findallex lthy rty qty tm = |
941 let |
953 let |
942 val (a, e) = findallex_all rty qty tm; |
954 val (a, e) = findallex_all rty qty tm; |
943 val (ad, ed) = (map domain_type a, map domain_type e); |
955 val (ad, ed) = (map domain_type a, map domain_type e); |
1003 singleton (ProofContext.export lthy' lthy) t_id |
1015 singleton (ProofContext.export lthy' lthy) t_id |
1004 end |
1016 end |
1005 *} |
1017 *} |
1006 |
1018 |
1007 ML {* |
1019 ML {* |
1008 fun matches (ty1, ty2) = |
|
1009 Type.raw_instance (ty1, Logic.varifyT ty2); |
|
1010 |
|
1011 fun lookup_quot_data lthy qty = |
1020 fun lookup_quot_data lthy qty = |
1012 let |
1021 let |
|
1022 fun matches (ty1, ty2) = |
|
1023 Type.raw_instance (ty1, Logic.varifyT ty2); |
1013 val SOME quotdata = find_first (fn x => matches ((#qtyp x), qty)) (quotdata_lookup lthy) |
1024 val SOME quotdata = find_first (fn x => matches ((#qtyp x), qty)) (quotdata_lookup lthy) |
|
1025 (* TODO: Should no longer be needed *) |
1014 val rty = Logic.unvarifyT (#rtyp quotdata) |
1026 val rty = Logic.unvarifyT (#rtyp quotdata) |
1015 val rel = #rel quotdata |
1027 val rel = #rel quotdata |
1016 val rel_eqv = #equiv_thm quotdata |
1028 val rel_eqv = #equiv_thm quotdata |
1017 val rel_refl_pre = @{thm EQUIV_REFL} OF [rel_eqv] |
1029 val rel_refl_pre = @{thm EQUIV_REFL} OF [rel_eqv] |
1018 val rel_refl = @{thm spec} OF [MetaSimplifier.rewrite_rule [@{thm REFL_def}] rel_refl_pre] |
1030 val rel_refl = @{thm spec} OF [MetaSimplifier.rewrite_rule [@{thm REFL_def}] rel_refl_pre] |