QuotMain.thy
changeset 506 91c374abde06
parent 505 6cdba30c6d66
child 507 f7569f994195
child 508 fac6069d8e80
equal deleted inserted replaced
505:6cdba30c6d66 506:91c374abde06
   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),
  1215 *}
  1216 *}
  1216 
  1217 
  1217 ML {*
  1218 ML {*
  1218 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *)
  1219 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *)
  1219 
  1220 
  1220 fun lift_tac lthy rthm rel_eqv quot =
  1221 fun lift_tac lthy rthm rel_eqv =
  1221   ObjectLogic.full_atomize_tac
  1222   ObjectLogic.full_atomize_tac
  1222   THEN' gen_frees_tac lthy
  1223   THEN' gen_frees_tac lthy
  1223   THEN' Subgoal.FOCUS (fn {context, concl, ...} =>
  1224   THEN' Subgoal.FOCUS (fn {context, concl, ...} =>
  1224     let
  1225     let
  1225       val rthm' = atomize_thm rthm
  1226       val rthm' = atomize_thm rthm
  1230     in
  1231     in
  1231       EVERY1
  1232       EVERY1
  1232        [rtac rule,
  1233        [rtac rule,
  1233         RANGE [rtac rthm',
  1234         RANGE [rtac rthm',
  1234                regularize_tac lthy rel_eqv,
  1235                regularize_tac lthy rel_eqv,
  1235                rtac thm THEN' all_inj_repabs_tac lthy quot rel_refl trans2,
  1236                rtac thm THEN' all_inj_repabs_tac lthy rel_refl trans2,
  1236                clean_tac lthy quot]]
  1237                clean_tac lthy]]
  1237     end) lthy
  1238     end) lthy
  1238 *}
  1239 *}
  1239 
  1240 
  1240 end
  1241 end
  1241 
  1242