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 |
147 (* Throws now an exception: *) |
148 (* Throws now an exception: *) |
148 (* declare [[map "option" = (bla, blu)]] *) |
149 (* declare [[map "option" = (bla, blu)]] *) |
149 |
150 |
150 lemmas [quotient_thm] = |
151 lemmas [quotient_thm] = |
151 fun_quotient prod_quotient |
152 fun_quotient prod_quotient |
264 s = s' andalso |
265 s = s' andalso |
265 if (length tys = length tys') |
266 if (length tys = length tys') |
266 then (List.all matches_typ (tys ~~ tys')) |
267 then (List.all matches_typ (tys ~~ tys')) |
267 else false |
268 else false |
268 | _ => false |
269 | _ => false |
269 *} |
270 |
270 |
|
271 ML {* |
|
272 fun matches_term (trm, trm') = |
271 fun matches_term (trm, trm') = |
273 case (trm, trm') of |
272 case (trm, trm') of |
274 (_, Var _) => true |
273 (_, Var _) => true |
275 | (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') |
276 | (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') |
614 val (y, s) = Term.dest_abs (x, T, t) |
611 val (y, s) = Term.dest_abs (x, T, t) |
615 val (_, s') = Term.dest_abs (x', T', t') |
612 val (_, s') = Term.dest_abs (x', T', t') |
616 val yvar = Free (y, T) |
613 val yvar = Free (y, T) |
617 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')) |
618 in |
615 in |
619 if rty = qty |
616 if rty = qty then result |
620 then result |
|
621 else mk_repabs lthy (rty, qty) result |
617 else mk_repabs lthy (rty, qty) result |
622 end |
618 end |
623 |
619 |
624 | (t $ s, t' $ s') => |
620 | (t $ s, t' $ s') => |
625 (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')) |
626 |
622 |
627 | (Free (_, T), Free (_, T')) => |
623 | (Free (_, T), Free (_, T')) => |
628 if T = T' |
624 if T = T' then rtrm |
629 then rtrm |
|
630 else mk_repabs lthy (T, T') rtrm |
625 else mk_repabs lthy (T, T') rtrm |
631 |
626 |
632 | (_, Const (@{const_name "op ="}, _)) => rtrm |
627 | (_, Const (@{const_name "op ="}, _)) => rtrm |
633 |
628 |
634 (* 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 *) |
635 | (_, Const (_, T')) => |
630 | (_, Const (_, T')) => |
636 let |
631 let |
637 val rty = fastype_of rtrm |
632 val rty = fastype_of rtrm |
638 in |
633 in |
639 if rty = T' |
634 if rty = T' then rtrm |
640 then rtrm |
|
641 else mk_repabs lthy (rty, T') rtrm |
635 else mk_repabs lthy (rty, T') rtrm |
642 end |
636 end |
643 |
637 |
644 | _ => raise (LIFT_MATCH "injection") |
638 | _ => raise (LIFT_MATCH "injection") |
645 *} |
639 *} |
649 ML {* |
643 ML {* |
650 fun quotient_tac ctxt = |
644 fun quotient_tac ctxt = |
651 REPEAT_ALL_NEW (FIRST' |
645 REPEAT_ALL_NEW (FIRST' |
652 [rtac @{thm identity_quotient}, |
646 [rtac @{thm identity_quotient}, |
653 resolve_tac (quotient_rules_get ctxt)]) |
647 resolve_tac (quotient_rules_get ctxt)]) |
654 *} |
648 |
655 |
|
656 (* solver for the simplifier *) |
|
657 ML {* |
|
658 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
649 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |
659 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 |
660 *} |
651 *} |
661 |
652 |
662 ML {* |
653 ML {* |
938 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
929 val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |
939 val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt) |
930 val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt) |
940 in |
931 in |
941 inj_repabs_step_tac ctxt rel_refl trans2 |
932 inj_repabs_step_tac ctxt rel_refl trans2 |
942 end |
933 end |
943 *} |
934 |
944 |
|
945 ML {* |
|
946 fun all_inj_repabs_tac ctxt = |
935 fun all_inj_repabs_tac ctxt = |
947 REPEAT_ALL_NEW (inj_repabs_tac ctxt) |
936 REPEAT_ALL_NEW (inj_repabs_tac ctxt) |
948 (* if this is too slow we can inline the code above *) |
937 *} |
949 *} |
938 |
950 |
939 section {* Cleaning of the Theorem *} |
951 section {* Cleaning of the theorem *} |
|
952 |
940 |
953 ML {* |
941 ML {* |
954 fun make_inst lhs t = |
942 fun make_inst lhs t = |
955 let |
943 let |
956 val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; |
944 val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; |
1032 (* 1. conversion (is not a pattern) *) |
1020 (* 1. conversion (is not a pattern) *) |
1033 thm lambda_prs |
1021 thm lambda_prs |
1034 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *) |
1022 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *) |
1035 (* and simplification with *) |
1023 (* and simplification with *) |
1036 thm all_prs ex_prs |
1024 thm all_prs ex_prs |
1037 (* 3. simplification with id_simps and *) |
1025 (* 3. simplification with *) |
1038 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep |
1026 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep id_simps |
1039 (* 4. Test for refl *) |
1027 (* 4. Test for refl *) |
1040 |
1028 |
1041 ML {* |
1029 ML {* |
1042 fun clean_tac lthy = |
1030 fun clean_tac lthy = |
1043 let |
1031 let |
1044 val thy = ProofContext.theory_of lthy; |
1032 val thy = ProofContext.theory_of lthy; |
1045 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) |
1046 (* FIXME: shouldn't the definitions already be varified? *) |
1034 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
1047 val thms1 = @{thms all_prs ex_prs} @ defs |
1035 val thms1 = @{thms all_prs ex_prs} @ defs |
1048 val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy) |
1036 val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy) |
1049 @ @{thms Quotient_abs_rep Quotient_rel_rep} |
1037 @ @{thms Quotient_abs_rep Quotient_rel_rep} |
1050 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 |
1051 in |
1039 in |
1153 (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i |
1141 (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i |
1154 end) |
1142 end) |
1155 *} |
1143 *} |
1156 |
1144 |
1157 ML {* |
1145 ML {* |
1158 (* automated tactics *) |
1146 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) |
|
1147 |
|
1148 fun WARN (tac, msg) i st = |
|
1149 case Seq.pull ((SOLVES' tac) i st) of |
|
1150 NONE => (warning msg; Seq.single st) |
|
1151 | seqcell => Seq.make (fn () => seqcell) |
|
1152 |
|
1153 fun RANGE_WARN xs = RANGE (map WARN xs) |
|
1154 *} |
|
1155 |
|
1156 ML {* |
1159 fun lift_tac ctxt rthm = |
1157 fun lift_tac ctxt rthm = |
1160 procedure_tac ctxt rthm |
1158 procedure_tac ctxt rthm |
1161 THEN' RANGE [regularize_tac ctxt, |
1159 THEN' RANGE_WARN [(regularize_tac ctxt, "Regularize proof failed."), |
1162 all_inj_repabs_tac ctxt, |
1160 (all_inj_repabs_tac ctxt, "Injection proof failed."), |
1163 clean_tac ctxt] |
1161 (clean_tac ctxt, "Cleaning proof failed.")] |
1164 *} |
1162 *} |
1165 |
1163 |
1166 end |
1164 end |
1167 |
1165 |