253 end |
253 end |
254 |
254 |
255 fun NDT ctxt s tac thm = tac thm |
255 fun NDT ctxt s tac thm = tac thm |
256 *} |
256 *} |
257 |
257 |
|
258 section {* Matching of terms and types *} |
|
259 |
|
260 ML {* |
|
261 fun matches_typ (ty, ty') = |
|
262 case (ty, ty') of |
|
263 (_, TVar _) => true |
|
264 | (TFree x, TFree x') => x = x' |
|
265 | (Type (s, tys), Type (s', tys')) => |
|
266 s = s' andalso |
|
267 if (length tys = length tys') |
|
268 then (List.all matches_typ (tys ~~ tys')) |
|
269 else false |
|
270 | _ => false |
|
271 *} |
|
272 ML {* |
|
273 fun matches_term (trm, trm') = |
|
274 case (trm, trm') of |
|
275 (_, Var _) => true |
|
276 | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') |
|
277 | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') |
|
278 | (Bound i, Bound j) => i = j |
|
279 | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') |
|
280 | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') |
|
281 | _ => false |
|
282 *} |
258 |
283 |
259 section {* Infrastructure for collecting theorems for starting the lifting *} |
284 section {* Infrastructure for collecting theorems for starting the lifting *} |
260 |
285 |
261 ML {* |
286 ML {* |
262 fun lookup_quot_data lthy qty = |
287 fun lookup_quot_data lthy qty = |
342 (* FIXME: check that the types correspond to each other? *) |
367 (* FIXME: check that the types correspond to each other? *) |
343 end |
368 end |
344 *} |
369 *} |
345 |
370 |
346 ML {* |
371 ML {* |
347 fun matches_typ (ty, ty') = |
|
348 case (ty, ty') of |
|
349 (_, TVar _) => true |
|
350 | (TFree x, TFree x') => x = x' |
|
351 | (Type (s, tys), Type (s', tys')) => |
|
352 s = s' andalso |
|
353 if (length tys = length tys') |
|
354 then (List.all matches_typ (tys ~~ tys')) |
|
355 else false |
|
356 | _ => false |
|
357 *} |
|
358 ML {* |
|
359 fun matches_term (trm, trm') = |
|
360 case (trm, trm') of |
|
361 (_, Var _) => true |
|
362 | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') |
|
363 | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') |
|
364 | (Bound i, Bound j) => i = j |
|
365 | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') |
|
366 | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') |
|
367 | _ => false |
|
368 *} |
|
369 |
|
370 ML {* |
|
371 val mk_babs = Const (@{const_name Babs}, dummyT) |
372 val mk_babs = Const (@{const_name Babs}, dummyT) |
372 val mk_ball = Const (@{const_name Ball}, dummyT) |
373 val mk_ball = Const (@{const_name Ball}, dummyT) |
373 val mk_bex = Const (@{const_name Bex}, dummyT) |
374 val mk_bex = Const (@{const_name Bex}, dummyT) |
374 val mk_resp = Const (@{const_name Respects}, dummyT) |
375 val mk_resp = Const (@{const_name Respects}, dummyT) |
375 *} |
376 *} |
755 | _ => raise (LIFT_MATCH "injection") |
756 | _ => raise (LIFT_MATCH "injection") |
756 *} |
757 *} |
757 |
758 |
758 section {* RepAbs Injection Tactic *} |
759 section {* RepAbs Injection Tactic *} |
759 |
760 |
760 (* Not used anymore *) |
|
761 (* FIXME/TODO: do not handle everything *) |
|
762 ML {* |
|
763 fun instantiate_tac thm = |
|
764 Subgoal.FOCUS (fn {concl, ...} => |
|
765 let |
|
766 val pat = Drule.strip_imp_concl (cprop_of thm) |
|
767 val insts = Thm.first_order_match (pat, concl) |
|
768 in |
|
769 rtac (Drule.instantiate insts thm) 1 |
|
770 end |
|
771 handle _ => no_tac) |
|
772 *} |
|
773 |
|
774 ML {* |
761 ML {* |
775 fun quotient_tac ctxt = |
762 fun quotient_tac ctxt = |
776 REPEAT_ALL_NEW (FIRST' |
763 REPEAT_ALL_NEW (FIRST' |
777 [rtac @{thm identity_quotient}, |
764 [rtac @{thm identity_quotient}, |
778 resolve_tac (quotient_rules_get ctxt)]) |
765 resolve_tac (quotient_rules_get ctxt)]) |
780 |
767 |
781 (* solver for the simplifier *) |
768 (* solver for the simplifier *) |
782 ML {* |
769 ML {* |
783 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
770 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
784 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
771 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
|
772 *} |
|
773 |
|
774 ML {* |
|
775 fun solve_quotient_assums ctxt thm = |
|
776 let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in |
|
777 thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)] |
|
778 end |
|
779 handle _ => error "solve_quotient_assums" |
|
780 *} |
|
781 |
|
782 (* It proves the Quotient assumptions by calling quotient_tac *) |
|
783 ML {* |
|
784 fun solve_quotient_assum i ctxt thm = |
|
785 let |
|
786 val tac = |
|
787 (compose_tac (false, thm, i)) THEN_ALL_NEW |
|
788 (quotient_tac ctxt); |
|
789 val gc = Drule.strip_imp_concl (cprop_of thm); |
|
790 in |
|
791 Goal.prove_internal [] gc (fn _ => tac 1) |
|
792 end |
|
793 handle _ => error "solve_quotient_assum" |
785 *} |
794 *} |
786 |
795 |
787 definition |
796 definition |
788 "QUOT_TRUE x \<equiv> True" |
797 "QUOT_TRUE x \<equiv> True" |
789 |
798 |
800 | SOME _ => error "find_qt_asm: no pair" |
809 | SOME _ => error "find_qt_asm: no pair" |
801 | NONE => error "find_qt_asm: no assumption" |
810 | NONE => error "find_qt_asm: no assumption" |
802 end |
811 end |
803 *} |
812 *} |
804 |
813 |
805 (* It proves the Quotient assumptions by calling quotient_tac *) |
814 (* |
806 ML {* |
815 To prove that the regularised theorem implies the abs/rep injected, |
807 fun solve_quotient_assum i ctxt thm = |
816 we try: |
808 let |
817 |
809 val tac = |
818 1) theorems 'trans2' from the appropriate QUOT_TYPE |
810 (compose_tac (false, thm, i)) THEN_ALL_NEW |
819 2) remove lambdas from both sides: lambda_rsp_tac |
811 (quotient_tac ctxt); |
820 3) remove Ball/Bex from the right hand side |
812 val gc = Drule.strip_imp_concl (cprop_of thm); |
821 4) use user-supplied RSP theorems |
813 in |
822 5) remove rep_abs from the right side |
814 Goal.prove_internal [] gc (fn _ => tac 1) |
823 6) reflexivity of equality |
815 end |
824 7) split applications of lifted type (apply_rsp) |
816 handle _ => error "solve_quotient_assum" |
825 8) split applications of non-lifted type (cong_tac) |
817 *} |
826 9) apply extentionality |
818 |
827 A) reflexivity of the relation |
819 ML {* |
828 B) assumption |
820 fun solve_quotient_assums ctxt thm = |
829 (Lambdas under respects may have left us some assumptions) |
821 let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in |
830 C) proving obvious higher order equalities by simplifying fun_rel |
822 thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)] |
831 (not sure if it is still needed?) |
823 end |
832 D) unfolding lambda on one side |
824 handle _ => error "solve_quotient_assums" |
833 E) simplifying (= ===> =) for simpler respectfulness |
|
834 |
|
835 *) |
|
836 |
|
837 lemma quot_true_dests: |
|
838 shows QT_all: "QUOT_TRUE (All P) \<Longrightarrow> QUOT_TRUE P" |
|
839 and QT_ex: "QUOT_TRUE (Ex P) \<Longrightarrow> QUOT_TRUE P" |
|
840 and QT_lam: "QUOT_TRUE (\<lambda>x. P x) \<Longrightarrow> (\<And>x. QUOT_TRUE (P x))" |
|
841 and QT_ext: "(\<And>x. QUOT_TRUE (a x) \<Longrightarrow> f x = g x) \<Longrightarrow> (QUOT_TRUE a \<Longrightarrow> f = g)" |
|
842 apply(simp_all add: QUOT_TRUE_def ext) |
|
843 done |
|
844 |
|
845 lemma QUOT_TRUE_i: "(QUOT_TRUE (a :: bool) \<Longrightarrow> P) \<Longrightarrow> P" |
|
846 by (simp add: QUOT_TRUE_def) |
|
847 |
|
848 lemma QUOT_TRUE_imp: "QUOT_TRUE a \<equiv> QUOT_TRUE b" |
|
849 by (simp add: QUOT_TRUE_def) |
|
850 |
|
851 ML {* |
|
852 fun quot_true_conv1 ctxt fnctn ctrm = |
|
853 case (term_of ctrm) of |
|
854 (Const (@{const_name QUOT_TRUE}, _) $ x) => |
|
855 let |
|
856 val fx = fnctn x; |
|
857 val thy = ProofContext.theory_of ctxt; |
|
858 val cx = cterm_of thy x; |
|
859 val cfx = cterm_of thy fx; |
|
860 val cxt = ctyp_of thy (fastype_of x); |
|
861 val cfxt = ctyp_of thy (fastype_of fx); |
|
862 val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp} |
|
863 in |
|
864 Conv.rewr_conv thm ctrm |
|
865 end |
|
866 *} |
|
867 |
|
868 ML {* |
|
869 fun quot_true_conv ctxt fnctn ctrm = |
|
870 case (term_of ctrm) of |
|
871 (Const (@{const_name QUOT_TRUE}, _) $ _) => |
|
872 quot_true_conv1 ctxt fnctn ctrm |
|
873 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
|
874 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
|
875 | _ => Conv.all_conv ctrm |
|
876 *} |
|
877 |
|
878 ML {* |
|
879 fun quot_true_tac ctxt fnctn = CONVERSION |
|
880 ((Conv.params_conv ~1 (fn ctxt => |
|
881 (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) |
|
882 *} |
|
883 |
|
884 ML {* fun dest_comb (f $ a) = (f, a) *} |
|
885 ML {* fun dest_bcomb ((_ $ l) $ r) = (l, r) *} |
|
886 (* TODO: Can this be done easier? *) |
|
887 ML {* |
|
888 fun unlam t = |
|
889 case t of |
|
890 (Abs a) => snd (Term.dest_abs a) |
|
891 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) |
|
892 *} |
|
893 |
|
894 ML {* |
|
895 fun dest_fun_type (Type("fun", [T, S])) = (T, S) |
|
896 | dest_fun_type _ = error "dest_fun_type" |
|
897 *} |
|
898 |
|
899 ML {* |
|
900 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
825 *} |
901 *} |
826 |
902 |
827 ML {* |
903 ML {* |
828 val apply_rsp_tac = |
904 val apply_rsp_tac = |
829 Subgoal.FOCUS (fn {concl, asms, context,...} => |
905 Subgoal.FOCUS (fn {concl, asms, context,...} => |
847 end |
923 end |
848 end |
924 end |
849 handle ERROR "find_qt_asm: no pair" => no_tac) |
925 handle ERROR "find_qt_asm: no pair" => no_tac) |
850 | _ => no_tac) |
926 | _ => no_tac) |
851 *} |
927 *} |
852 |
|
853 ML {* |
928 ML {* |
854 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) |
929 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) |
855 *} |
|
856 |
|
857 (* |
|
858 To prove that the regularised theorem implies the abs/rep injected, |
|
859 we try: |
|
860 |
|
861 1) theorems 'trans2' from the appropriate QUOT_TYPE |
|
862 2) remove lambdas from both sides: lambda_rsp_tac |
|
863 3) remove Ball/Bex from the right hand side |
|
864 4) use user-supplied RSP theorems |
|
865 5) remove rep_abs from the right side |
|
866 6) reflexivity of equality |
|
867 7) split applications of lifted type (apply_rsp) |
|
868 8) split applications of non-lifted type (cong_tac) |
|
869 9) apply extentionality |
|
870 A) reflexivity of the relation |
|
871 B) assumption |
|
872 (Lambdas under respects may have left us some assumptions) |
|
873 C) proving obvious higher order equalities by simplifying fun_rel |
|
874 (not sure if it is still needed?) |
|
875 D) unfolding lambda on one side |
|
876 E) simplifying (= ===> =) for simpler respectfulness |
|
877 |
|
878 *) |
|
879 |
|
880 lemma quot_true_dests: |
|
881 shows QT_all: "QUOT_TRUE (All P) \<Longrightarrow> QUOT_TRUE P" |
|
882 and QT_ex: "QUOT_TRUE (Ex P) \<Longrightarrow> QUOT_TRUE P" |
|
883 and QT_lam: "QUOT_TRUE (\<lambda>x. P x) \<Longrightarrow> (\<And>x. QUOT_TRUE (P x))" |
|
884 and QT_ext: "(\<And>x. QUOT_TRUE (a x) \<Longrightarrow> f x = g x) \<Longrightarrow> (QUOT_TRUE a \<Longrightarrow> f = g)" |
|
885 apply(simp_all add: QUOT_TRUE_def ext) |
|
886 done |
|
887 |
|
888 lemma QUOT_TRUE_i: "(QUOT_TRUE (a :: bool) \<Longrightarrow> P) \<Longrightarrow> P" |
|
889 by (simp add: QUOT_TRUE_def) |
|
890 |
|
891 lemma QUOT_TRUE_imp: "QUOT_TRUE a \<equiv> QUOT_TRUE b" |
|
892 by (simp add: QUOT_TRUE_def) |
|
893 |
|
894 ML {* |
|
895 fun quot_true_conv1 ctxt fnctn ctrm = |
|
896 case (term_of ctrm) of |
|
897 (Const (@{const_name QUOT_TRUE}, _) $ x) => |
|
898 let |
|
899 val fx = fnctn x; |
|
900 val thy = ProofContext.theory_of ctxt; |
|
901 val cx = cterm_of thy x; |
|
902 val cfx = cterm_of thy fx; |
|
903 val cxt = ctyp_of thy (fastype_of x); |
|
904 val cfxt = ctyp_of thy (fastype_of fx); |
|
905 val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp} |
|
906 in |
|
907 Conv.rewr_conv thm ctrm |
|
908 end |
|
909 *} |
|
910 |
|
911 ML {* |
|
912 fun quot_true_conv ctxt fnctn ctrm = |
|
913 case (term_of ctrm) of |
|
914 (Const (@{const_name QUOT_TRUE}, _) $ _) => |
|
915 quot_true_conv1 ctxt fnctn ctrm |
|
916 | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |
|
917 | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |
|
918 | _ => Conv.all_conv ctrm |
|
919 *} |
|
920 |
|
921 ML {* |
|
922 fun quot_true_tac ctxt fnctn = CONVERSION |
|
923 ((Conv.params_conv ~1 (fn ctxt => |
|
924 (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) |
|
925 *} |
|
926 |
|
927 ML {* fun dest_comb (f $ a) = (f, a) *} |
|
928 ML {* fun dest_bcomb ((_ $ l) $ r) = (l, r) *} |
|
929 (* TODO: Can this be done easier? *) |
|
930 ML {* |
|
931 fun unlam t = |
|
932 case t of |
|
933 (Abs a) => snd (Term.dest_abs a) |
|
934 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) |
|
935 *} |
|
936 |
|
937 ML {* |
|
938 fun dest_fun_type (Type("fun", [T, S])) = (T, S) |
|
939 | dest_fun_type _ = error "dest_fun_type" |
|
940 *} |
|
941 |
|
942 ML {* |
|
943 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |
|
944 *} |
930 *} |
945 |
931 |
946 ML {* |
932 ML {* |
947 fun rep_abs_rsp_tac ctxt = |
933 fun rep_abs_rsp_tac ctxt = |
948 SUBGOAL (fn (goal, i) => |
934 SUBGOAL (fn (goal, i) => |