152 use "quotient_info.ML" |
152 use "quotient_info.ML" |
153 |
153 |
154 declare [[map list = (map, LIST_REL)]] |
154 declare [[map list = (map, LIST_REL)]] |
155 declare [[map * = (prod_fun, prod_rel)]] |
155 declare [[map * = (prod_fun, prod_rel)]] |
156 declare [[map "fun" = (fun_map, FUN_REL)]] |
156 declare [[map "fun" = (fun_map, FUN_REL)]] |
|
157 |
|
158 lemmas [quotient_thm] = |
|
159 FUN_QUOTIENT IDENTITY_QUOTIENT LIST_QUOTIENT |
157 |
160 |
158 ML {* maps_lookup @{theory} "List.list" *} |
161 ML {* maps_lookup @{theory} "List.list" *} |
159 ML {* maps_lookup @{theory} "*" *} |
162 ML {* maps_lookup @{theory} "*" *} |
160 ML {* maps_lookup @{theory} "fun" *} |
163 ML {* maps_lookup @{theory} "fun" *} |
161 |
164 |
728 end |
731 end |
729 handle _ => no_tac) |
732 handle _ => no_tac) |
730 *} |
733 *} |
731 |
734 |
732 ML {* |
735 ML {* |
733 fun quotient_tac ctxt quot_thms = |
736 fun quotient_tac ctxt = |
734 REPEAT_ALL_NEW (FIRST' |
737 REPEAT_ALL_NEW (FIRST' |
735 [rtac @{thm FUN_QUOTIENT}, |
738 [resolve_tac (quotient_rules_get ctxt), |
736 resolve_tac quot_thms, |
|
737 rtac @{thm IDENTITY_QUOTIENT}, |
|
738 rtac @{thm LIST_QUOTIENT}, |
|
739 (* For functional identity quotients, (op = ---> op =) *) |
739 (* For functional identity quotients, (op = ---> op =) *) |
740 (* TODO: think about the other way around, if we need to shorten the relation *) |
740 (* TODO: think about the other way around, if we need to shorten the relation *) |
741 CHANGED o (simp_tac ((Simplifier.context ctxt empty_ss) addsimps @{thms id_simps}))]) |
741 CHANGED o (simp_tac ((Simplifier.context ctxt empty_ss) addsimps @{thms id_simps}))]) |
742 *} |
742 *} |
743 |
743 |
899 (Abs a) => snd (Term.dest_abs a) |
899 (Abs a) => snd (Term.dest_abs a) |
900 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) *} |
900 | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) *} |
901 |
901 |
902 |
902 |
903 ML {* |
903 ML {* |
904 fun inj_repabs_tac ctxt quot_thms rel_refl trans2 = |
904 fun inj_repabs_tac ctxt rel_refl trans2 = |
905 (FIRST' [ |
905 (FIRST' [ |
906 (* "cong" rule of the of the relation / transitivity*) |
906 (* "cong" rule of the of the relation / transitivity*) |
907 (* (op =) (R a b) (R c d) ----> \<lbrakk>R a c; R b d\<rbrakk> *) |
907 (* (op =) (R a b) (R c d) ----> \<lbrakk>R a c; R b d\<rbrakk> *) |
908 NDT ctxt "1" (resolve_tac trans2 THEN' RANGE [ |
908 NDT ctxt "1" (resolve_tac trans2 THEN' RANGE [ |
909 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)]), |
909 quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)]), |
931 NDT ctxt "8" (rtac @{thm refl}), |
931 NDT ctxt "8" (rtac @{thm refl}), |
932 |
932 |
933 (* R (\<dots>) (Rep (Abs \<dots>)) ----> R (\<dots>) (\<dots>) *) |
933 (* R (\<dots>) (Rep (Abs \<dots>)) ----> R (\<dots>) (\<dots>) *) |
934 (* observe ---> *) |
934 (* observe ---> *) |
935 NDT ctxt "9" ((instantiate_tac @{thm REP_ABS_RSP} ctxt |
935 NDT ctxt "9" ((instantiate_tac @{thm REP_ABS_RSP} ctxt |
936 THEN' (RANGE [SOLVES' (quotient_tac ctxt quot_thms)]))), |
936 THEN' (RANGE [SOLVES' (quotient_tac ctxt)]))), |
937 |
937 |
938 (* R (t $ \<dots>) (t' $ \<dots>) ----> APPLY_RSP provided type of t needs lifting *) |
938 (* R (t $ \<dots>) (t' $ \<dots>) ----> APPLY_RSP provided type of t needs lifting *) |
939 NDT ctxt "A" (APPLY_RSP_TAC ctxt THEN' |
939 NDT ctxt "A" (APPLY_RSP_TAC ctxt THEN' |
940 (RANGE [SOLVES' (quotient_tac ctxt quot_thms), SOLVES' (quotient_tac ctxt quot_thms), |
940 (RANGE [SOLVES' (quotient_tac ctxt), SOLVES' (quotient_tac ctxt), |
941 quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])), |
941 quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])), |
942 |
942 |
943 (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong provided type of t does not need lifting *) |
943 (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong provided type of t does not need lifting *) |
944 (* merge with previous tactic *) |
944 (* merge with previous tactic *) |
945 NDT ctxt "B" (Cong_Tac.cong_tac @{thm cong} THEN' |
945 NDT ctxt "B" (Cong_Tac.cong_tac @{thm cong} THEN' |
959 (* global simplification *) |
959 (* global simplification *) |
960 NDT ctxt "H" (CHANGED o (asm_full_simp_tac ((Simplifier.context ctxt empty_ss) addsimps @{thms eq_reflection[OF FUN_REL_EQ]})))]) |
960 NDT ctxt "H" (CHANGED o (asm_full_simp_tac ((Simplifier.context ctxt empty_ss) addsimps @{thms eq_reflection[OF FUN_REL_EQ]})))]) |
961 *} |
961 *} |
962 |
962 |
963 ML {* |
963 ML {* |
964 fun all_inj_repabs_tac ctxt quot_thms rel_refl trans2 = |
964 fun all_inj_repabs_tac ctxt rel_refl trans2 = |
965 REPEAT_ALL_NEW (inj_repabs_tac ctxt quot_thms rel_refl trans2) |
965 REPEAT_ALL_NEW (inj_repabs_tac ctxt rel_refl trans2) |
966 *} |
966 *} |
967 |
967 |
968 section {* Cleaning of the theorem *} |
968 section {* Cleaning of the theorem *} |
969 |
969 |
970 |
970 |
971 (* TODO: This is slow *) |
971 (* TODO: This is slow *) |
972 ML {* |
972 ML {* |
973 fun allex_prs_tac ctxt quot = |
973 fun allex_prs_tac ctxt = |
974 (EqSubst.eqsubst_tac ctxt [0] @{thms all_prs ex_prs}) THEN' (quotient_tac ctxt quot) |
974 (EqSubst.eqsubst_tac ctxt [0] @{thms all_prs ex_prs}) THEN' (quotient_tac ctxt) |
975 *} |
975 *} |
976 |
976 |
977 ML {* |
977 ML {* |
978 fun make_inst lhs t = |
978 fun make_inst lhs t = |
979 let |
979 let |
989 in (f, Abs ("x", T, mk_abs 0 g)) end; |
989 in (f, Abs ("x", T, mk_abs 0 g)) end; |
990 *} |
990 *} |
991 |
991 |
992 (* It proves the QUOTIENT assumptions by calling quotient_tac *) |
992 (* It proves the QUOTIENT assumptions by calling quotient_tac *) |
993 ML {* |
993 ML {* |
994 fun solve_quotient_assum i quot_thms ctxt thm = |
994 fun solve_quotient_assum i ctxt thm = |
995 let |
995 let |
996 val tac = |
996 val tac = |
997 (compose_tac (false, thm, i)) THEN_ALL_NEW |
997 (compose_tac (false, thm, i)) THEN_ALL_NEW |
998 (quotient_tac ctxt quot_thms); |
998 (quotient_tac ctxt); |
999 val gc = Drule.strip_imp_concl (cprop_of thm); |
999 val gc = Drule.strip_imp_concl (cprop_of thm); |
1000 in |
1000 in |
1001 Goal.prove_internal [] gc (fn _ => tac 1) |
1001 Goal.prove_internal [] gc (fn _ => tac 1) |
1002 end |
1002 end |
1003 handle _ => error "solve_quotient_assum" |
1003 handle _ => error "solve_quotient_assum" |
1004 *} |
1004 *} |
1005 |
1005 |
1006 ML {* |
1006 ML {* |
1007 fun lambda_allex_prs_simple_conv quot_thms ctxt ctrm = |
1007 fun lambda_allex_prs_simple_conv ctxt ctrm = |
1008 case (term_of ctrm) of |
1008 case (term_of ctrm) of |
1009 ((Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _)) => |
1009 ((Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _)) => |
1010 let |
1010 let |
1011 val (_, [ty_b, ty_a]) = dest_Type (fastype_of r1); |
1011 val (_, [ty_b, ty_a]) = dest_Type (fastype_of r1); |
1012 val (_, [ty_c, ty_d]) = dest_Type (fastype_of a2); |
1012 val (_, [ty_c, ty_d]) = dest_Type (fastype_of a2); |
1013 val thy = ProofContext.theory_of ctxt; |
1013 val thy = ProofContext.theory_of ctxt; |
1014 val [cty_a, cty_b, cty_c, cty_d] = map (ctyp_of thy) [ty_a, ty_b, ty_c, ty_d] |
1014 val [cty_a, cty_b, cty_c, cty_d] = map (ctyp_of thy) [ty_a, ty_b, ty_c, ty_d] |
1015 val tyinst = [SOME cty_a, SOME cty_b, SOME cty_c, SOME cty_d]; |
1015 val tyinst = [SOME cty_a, SOME cty_b, SOME cty_c, SOME cty_d]; |
1016 val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)] |
1016 val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)] |
1017 val lpi = Drule.instantiate' tyinst tinst @{thm LAMBDA_PRS}; |
1017 val lpi = Drule.instantiate' tyinst tinst @{thm LAMBDA_PRS}; |
1018 val te = @{thm eq_reflection} OF [solve_quotient_assum 2 quot_thms ctxt lpi] |
1018 val te = @{thm eq_reflection} OF [solve_quotient_assum 2 ctxt lpi] |
1019 val ts = MetaSimplifier.rewrite_rule @{thms id_simps} te |
1019 val ts = MetaSimplifier.rewrite_rule @{thms id_simps} te |
1020 val tl = Thm.lhs_of ts; |
1020 val tl = Thm.lhs_of ts; |
1021 val (insp, inst) = make_inst (term_of tl) (term_of ctrm); |
1021 val (insp, inst) = make_inst (term_of tl) (term_of ctrm); |
1022 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts; |
1022 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts; |
1023 in |
1023 in |
1030 val thy = ProofContext.theory_of ctxt; |
1030 val thy = ProofContext.theory_of ctxt; |
1031 val (cty_a, cty_b) = (ctyp_of thy ty_a, ctyp_of thy ty_b); |
1031 val (cty_a, cty_b) = (ctyp_of thy ty_a, ctyp_of thy ty_b); |
1032 val tyinst = [SOME cty_a, SOME cty_b]; |
1032 val tyinst = [SOME cty_a, SOME cty_b]; |
1033 val tinst = [SOME (cterm_of thy R), SOME (cterm_of thy absf), NONE, SOME (cterm_of thy f)]; |
1033 val tinst = [SOME (cterm_of thy R), SOME (cterm_of thy absf), NONE, SOME (cterm_of thy f)]; |
1034 val thm = Drule.instantiate' tyinst tinst @{thm all_prs}; |
1034 val thm = Drule.instantiate' tyinst tinst @{thm all_prs}; |
1035 val ti = @{thm eq_reflection} OF [solve_quotient_assum 1 quot_thms ctxt thm]; |
1035 val ti = @{thm eq_reflection} OF [solve_quotient_assum 1 ctxt thm]; |
1036 in |
1036 in |
1037 Conv.rewr_conv ti ctrm |
1037 Conv.rewr_conv ti ctrm |
1038 end |
1038 end |
1039 | (Const (@{const_name Bex}, _) $ (Const (@{const_name Respects}, _) $ R) $ |
1039 | (Const (@{const_name Bex}, _) $ (Const (@{const_name Respects}, _) $ R) $ |
1040 (((Const (@{const_name fun_map}, _) $ absf $ (Const (@{const_name id}, _)))) $ f)) => |
1040 (((Const (@{const_name fun_map}, _) $ absf $ (Const (@{const_name id}, _)))) $ f)) => |
1043 val thy = ProofContext.theory_of ctxt; |
1043 val thy = ProofContext.theory_of ctxt; |
1044 val (cty_a, cty_b) = (ctyp_of thy ty_a, ctyp_of thy ty_b); |
1044 val (cty_a, cty_b) = (ctyp_of thy ty_a, ctyp_of thy ty_b); |
1045 val tyinst = [SOME cty_a, SOME cty_b]; |
1045 val tyinst = [SOME cty_a, SOME cty_b]; |
1046 val tinst = [SOME (cterm_of thy R), SOME (cterm_of thy absf), NONE, SOME (cterm_of thy f)]; |
1046 val tinst = [SOME (cterm_of thy R), SOME (cterm_of thy absf), NONE, SOME (cterm_of thy f)]; |
1047 val thm = Drule.instantiate' tyinst tinst @{thm ex_prs}; |
1047 val thm = Drule.instantiate' tyinst tinst @{thm ex_prs}; |
1048 val ti = @{thm eq_reflection} OF [solve_quotient_assum 1 quot_thms ctxt thm]; |
1048 val ti = @{thm eq_reflection} OF [solve_quotient_assum 1 ctxt thm]; |
1049 in |
1049 in |
1050 Conv.rewr_conv ti ctrm |
1050 Conv.rewr_conv ti ctrm |
1051 end |
1051 end |
1052 | _ => Conv.all_conv ctrm |
1052 | _ => Conv.all_conv ctrm |
1053 *} |
1053 *} |
1054 |
1054 |
1055 (* quot stands for the QUOTIENT theorems: *) |
1055 (* quot stands for the QUOTIENT theorems: *) |
1056 (* could be potentially all of them *) |
1056 (* could be potentially all of them *) |
1057 ML {* |
1057 ML {* |
1058 fun lambda_allex_prs_conv quot = |
1058 val lambda_allex_prs_conv = |
1059 More_Conv.top_conv (lambda_allex_prs_simple_conv quot) |
1059 More_Conv.top_conv lambda_allex_prs_simple_conv |
1060 *} |
1060 *} |
1061 |
1061 |
1062 ML {* |
1062 ML {* |
1063 fun lambda_allex_prs_tac quot ctxt = CONVERSION (lambda_allex_prs_conv quot ctxt) |
1063 fun lambda_allex_prs_tac ctxt = CONVERSION (lambda_allex_prs_conv ctxt) |
1064 *} |
1064 *} |
1065 |
1065 |
1066 (* |
1066 (* |
1067 Cleaning the theorem consists of 6 kinds of rewrites. |
1067 Cleaning the theorem consists of 6 kinds of rewrites. |
1068 The first two need to be done before fun_map is unfolded |
1068 The first two need to be done before fun_map is unfolded |
1088 The second one is an EqSubst (slow). |
1088 The second one is an EqSubst (slow). |
1089 The rest are a simp_tac and are fast. |
1089 The rest are a simp_tac and are fast. |
1090 *) |
1090 *) |
1091 |
1091 |
1092 ML {* |
1092 ML {* |
1093 fun clean_tac lthy quot = |
1093 fun clean_tac lthy = |
1094 let |
1094 let |
1095 val thy = ProofContext.theory_of lthy; |
1095 val thy = ProofContext.theory_of lthy; |
|
1096 val quotients = quotient_rules_get lthy |
1096 val defs = map (Thm.varifyT o #def) (qconsts_dest thy); |
1097 val defs = map (Thm.varifyT o #def) (qconsts_dest thy); |
1097 val absrep = map (fn x => @{thm QUOTIENT_ABS_REP} OF [x]) quot |
1098 val absrep = map (fn x => @{thm QUOTIENT_ABS_REP} OF [x]) quotients |
1098 val meta_absrep = map (fn x => @{thm eq_reflection} OF [x]) absrep; |
1099 val meta_absrep = map (fn x => @{thm eq_reflection} OF [x]) absrep; |
1099 val reps_same = map (fn x => @{thm QUOTIENT_REL_REP} OF [x]) quot |
1100 val reps_same = map (fn x => @{thm QUOTIENT_REL_REP} OF [x]) quotients |
1100 val meta_reps_same = map (fn x => @{thm eq_reflection} OF [x]) reps_same |
1101 val meta_reps_same = map (fn x => @{thm eq_reflection} OF [x]) reps_same |
1101 val simp_ctxt = (Simplifier.context lthy empty_ss) addsimps |
1102 val simp_ctxt = (Simplifier.context lthy empty_ss) addsimps |
1102 (@{thm eq_reflection[OF fun_map.simps]} :: @{thms id_simps} @ meta_absrep @ meta_reps_same @ defs) |
1103 (@{thm eq_reflection[OF fun_map.simps]} :: @{thms id_simps} @ meta_absrep @ meta_reps_same @ defs) |
1103 in |
1104 in |
1104 EVERY' [ |
1105 EVERY' [ |
1105 (* (Rep1 ---> Abs2) (\<lambda>x. Rep2 (f (Abs1 x))) ----> f *) |
1106 (* (Rep1 ---> Abs2) (\<lambda>x. Rep2 (f (Abs1 x))) ----> f *) |
1106 (* \<forall>x\<in>Respects R. (abs ---> id) f ----> \<forall>x. f *) |
1107 (* \<forall>x\<in>Respects R. (abs ---> id) f ----> \<forall>x. f *) |
1107 NDT lthy "a" (TRY o lambda_allex_prs_tac quot lthy), |
1108 NDT lthy "a" (TRY o lambda_allex_prs_tac lthy), |
1108 |
1109 |
1109 (* NewConst ----> (rep ---> abs) oldConst *) |
1110 (* NewConst ----> (rep ---> abs) oldConst *) |
1110 (* Abs (Rep x) ----> x *) |
1111 (* Abs (Rep x) ----> x *) |
1111 (* id_simps; fun_map.simps *) |
1112 (* id_simps; fun_map.simps *) |
1112 NDT lthy "c" (TRY o simp_tac simp_ctxt), |
1113 NDT lthy "c" (TRY o simp_tac simp_ctxt), |