827 (disc_corec_iff_thmss, simp_attrs), |
827 (disc_corec_iff_thmss, simp_attrs), |
828 (sel_corec_thmsss, simp_attrs)) |
828 (sel_corec_thmsss, simp_attrs)) |
829 end; |
829 end; |
830 |
830 |
831 fun define_co_datatypes prepare_constraint prepare_typ prepare_term fp construct_fp |
831 fun define_co_datatypes prepare_constraint prepare_typ prepare_term fp construct_fp |
832 (wrap_opts as (no_discs_sels, _), specs) no_defs_lthy0 = |
832 ((discs_sels0, no_code), specs) no_defs_lthy0 = |
833 let |
833 let |
834 (* TODO: sanity checks on arguments *) |
834 (* TODO: sanity checks on arguments *) |
835 |
835 |
836 val _ = if fp = Greatest_FP andalso no_discs_sels then |
836 val discs_sels = discs_sels0 orelse fp = Greatest_FP; |
837 error "Cannot define codatatypes without discriminators and selectors" |
|
838 else |
|
839 (); |
|
840 |
837 |
841 val nn = length specs; |
838 val nn = length specs; |
842 val fp_bs = map type_binding_of_spec specs; |
839 val fp_bs = map type_binding_of_spec specs; |
843 val fp_b_names = map Binding.name_of fp_bs; |
840 val fp_b_names = map Binding.name_of fp_bs; |
844 val fp_common_name = mk_common_name fp_b_names; |
841 val fp_common_name = mk_common_name fp_b_names; |
1113 val sel_defaultss = map (map (apsnd (prepare_term lthy))) raw_sel_defaultss |
1110 val sel_defaultss = map (map (apsnd (prepare_term lthy))) raw_sel_defaultss |
1114 |
1111 |
1115 fun ctr_spec_of disc_b ctr0 sel_bs sel_defs = (((disc_b, ctr0), sel_bs), sel_defs); |
1112 fun ctr_spec_of disc_b ctr0 sel_bs sel_defs = (((disc_b, ctr0), sel_bs), sel_defs); |
1116 val ctr_specs = map4 ctr_spec_of disc_bindings ctrs0 sel_bindingss sel_defaultss; |
1113 val ctr_specs = map4 ctr_spec_of disc_bindings ctrs0 sel_bindingss sel_defaultss; |
1117 in |
1114 in |
1118 free_constructors tacss ((wrap_opts, standard_binding), ctr_specs) lthy |
1115 free_constructors tacss (((discs_sels, no_code), standard_binding), ctr_specs) lthy |
1119 end; |
1116 end; |
1120 |
1117 |
1121 fun derive_maps_sets_rels |
1118 fun derive_maps_sets_rels |
1122 (ctr_sugar as {case_cong, discs, selss, ctrs, exhaust, disc_thmss, sel_thmss, ...} : ctr_sugar, lthy) = |
1119 (ctr_sugar as {case_cong, discs, selss, ctrs, exhaust, disc_thmss, sel_thmss, ...} : ctr_sugar, lthy) = |
1123 if live = 0 then |
1120 if live = 0 then |
1191 val ((fs, ta), names_lthy) = names_lthy |
1188 val ((fs, ta), names_lthy) = names_lthy |
1192 |> mk_Frees "f" fTs |
1189 |> mk_Frees "f" fTs |
1193 ||>> yield_singleton (mk_Frees "a") TA; |
1190 ||>> yield_singleton (mk_Frees "a") TA; |
1194 val map_term = mk_map_of_bnf Ds As Bs fp_bnf; |
1191 val map_term = mk_map_of_bnf Ds As Bs fp_bnf; |
1195 val discsA = map (mk_disc_or_sel ADs) discs; |
1192 val discsA = map (mk_disc_or_sel ADs) discs; |
|
1193 |
1196 fun is_t_eq_t T t term = |
1194 fun is_t_eq_t T t term = |
1197 let |
1195 let |
1198 val (head, tail) = Term.strip_comb term; |
1196 val (head, tail) = Term.strip_comb term; |
1199 in |
1197 in |
1200 head aconv HOLogic.eq_const T andalso forall (fn u => u = t) tail |
1198 head aconv HOLogic.eq_const T andalso forall (fn u => u = t) tail |
1201 end; |
1199 end; |
|
1200 |
1202 val disc_map_iff_thms = |
1201 val disc_map_iff_thms = |
1203 let |
1202 let |
1204 val discsB = map (mk_disc_or_sel BDs) discs; |
1203 val discsB = map (mk_disc_or_sel BDs) discs; |
1205 val discsA_t = map (fn disc1 => Term.betapply (disc1, ta)) discsA; |
1204 val discsA_t = map (fn disc1 => Term.betapply (disc1, ta)) discsA; |
|
1205 |
1206 fun mk_goal (discA_t, discB) = |
1206 fun mk_goal (discA_t, discB) = |
1207 if head_of discA_t aconv @{const Not} orelse is_t_eq_t TA ta discA_t then |
1207 if head_of discA_t aconv @{const Not} orelse is_t_eq_t TA ta discA_t then |
1208 NONE |
1208 NONE |
1209 else |
1209 else |
1210 SOME (mk_Trueprop_eq |
1210 SOME (mk_Trueprop_eq |
1211 (betapply (discB, (Term.list_comb (map_term, fs) $ ta)), discA_t)); |
1211 (betapply (discB, (Term.list_comb (map_term, fs) $ ta)), discA_t)); |
|
1212 |
1212 val goals = map_filter mk_goal (discsA_t ~~ discsB); |
1213 val goals = map_filter mk_goal (discsA_t ~~ discsB); |
1213 in |
1214 in |
1214 if null goals then [] |
1215 if null goals then [] |
1215 else |
1216 else |
1216 Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced goals) |
1217 Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced goals) |
1218 mk_disc_map_iff_tac ctxt (certify ctxt ta) exhaust (flat disc_thmss) |
1219 mk_disc_map_iff_tac ctxt (certify ctxt ta) exhaust (flat disc_thmss) |
1219 map_thms) |
1220 map_thms) |
1220 |> Conjunction.elim_balanced (length goals) |
1221 |> Conjunction.elim_balanced (length goals) |
1221 |> Proof_Context.export names_lthy lthy |
1222 |> Proof_Context.export names_lthy lthy |
1222 end; |
1223 end; |
|
1224 |
1223 val sel_map_thms = |
1225 val sel_map_thms = |
1224 let |
1226 let |
1225 fun mk_sel_map_goal (discA, selA) = |
1227 fun mk_sel_map_goal (discA, selA) = |
1226 let |
1228 let |
1227 val premise = Term.betapply (discA, ta); |
1229 val premise = Term.betapply (discA, ta); |
1234 val rhs = (case map_rhs of |
1236 val rhs = (case map_rhs of |
1235 Const (@{const_name id}, _) => selA $ ta |
1237 Const (@{const_name id}, _) => selA $ ta |
1236 | _ => map_rhs $ (selA $ ta)); |
1238 | _ => map_rhs $ (selA $ ta)); |
1237 val conclusion = mk_Trueprop_eq (lhs, rhs); |
1239 val conclusion = mk_Trueprop_eq (lhs, rhs); |
1238 in |
1240 in |
1239 if is_t_eq_t TA ta premise then |
1241 if is_t_eq_t TA ta premise then conclusion |
1240 conclusion |
1242 else Logic.mk_implies (HOLogic.mk_Trueprop premise, conclusion) |
1241 else |
|
1242 Logic.mk_implies (HOLogic.mk_Trueprop premise, conclusion) |
|
1243 end; |
1243 end; |
|
1244 |
1244 val disc_sel_pairs = flat (map2 (fn disc => fn sels => map (pair disc) sels) |
1245 val disc_sel_pairs = flat (map2 (fn disc => fn sels => map (pair disc) sels) |
1245 discsA (map (map (mk_disc_or_sel ADs)) selss)); |
1246 discsA (map (map (mk_disc_or_sel ADs)) selss)); |
1246 val goals = map mk_sel_map_goal disc_sel_pairs; |
1247 val goals = map mk_sel_map_goal disc_sel_pairs; |
1247 in |
1248 in |
1248 if null goals then [] |
1249 if null goals then [] |
1256 end; |
1257 end; |
1257 in |
1258 in |
1258 (disc_map_iff_thms, sel_map_thms) |
1259 (disc_map_iff_thms, sel_map_thms) |
1259 end; |
1260 end; |
1260 |
1261 |
1261 val ctr_argT_namess = map ((fn Ts => fold Term.add_tfree_namesT Ts []) o |
1262 val set_empty_thms = |
1262 binder_types o fastype_of) ctrs; |
1263 let |
1263 val setTs = map (HOLogic.dest_setT o range_type o fastype_of) sets; |
1264 val ctr_argT_namess = map ((fn Ts => fold Term.add_tfree_namesT Ts []) o |
1264 val setT_names = map (fn T => the_single (Term.add_tfree_namesT T [])) setTs; |
1265 binder_types o fastype_of) ctrs; |
1265 fun mk_set_empty_goal disc set T = Logic.mk_implies (HOLogic.mk_Trueprop (disc $ u), |
1266 val setTs = map (HOLogic.dest_setT o range_type o fastype_of) sets; |
1266 mk_Trueprop_eq (set $ u, HOLogic.mk_set T [])); |
1267 val setT_names = map (fn T => the_single (Term.add_tfree_namesT T [])) setTs; |
1267 val goals = map_filter I (flat |
1268 |
1268 (map2 (fn names => fn disc => |
1269 fun mk_set_empty_goal disc set T = |
1269 map3 (fn name => fn setT => fn set => |
1270 Logic.mk_implies (HOLogic.mk_Trueprop (disc $ u), |
1270 if member (op =) names name then NONE |
1271 mk_Trueprop_eq (set $ u, HOLogic.mk_set T [])); |
1271 else SOME (mk_set_empty_goal disc set setT)) |
1272 |
1272 setT_names setTs sets) |
1273 val goals = |
1273 ctr_argT_namess discs)); |
1274 if null discs then |
1274 |
1275 [] |
1275 val set_empty_thms = if null goals then [] |
1276 else |
1276 else Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced goals) |
1277 map_filter I (flat |
1277 (fn {context = ctxt, prems = _} => |
1278 (map2 (fn names => fn disc => |
1278 mk_set_empty_tac ctxt (certify ctxt u) exhaust set_thms (flat disc_thmss)) |
1279 map3 (fn name => fn setT => fn set => |
1279 |> Conjunction.elim_balanced (length goals) |
1280 if member (op =) names name then NONE |
1280 |> Proof_Context.export names_lthy lthy; |
1281 else SOME (mk_set_empty_goal disc set setT)) |
|
1282 setT_names setTs sets) |
|
1283 ctr_argT_namess discs)); |
|
1284 in |
|
1285 if null goals then |
|
1286 [] |
|
1287 else |
|
1288 Goal.prove_sorry lthy [] [] (Logic.mk_conjunction_balanced goals) |
|
1289 (fn {context = ctxt, prems = _} => |
|
1290 mk_set_empty_tac ctxt (certify ctxt u) exhaust set_thms (flat disc_thmss)) |
|
1291 |> Conjunction.elim_balanced (length goals) |
|
1292 |> Proof_Context.export names_lthy lthy |
|
1293 end; |
1281 |
1294 |
1282 val rel_infos = (ctr_defs' ~~ cxIns, ctr_defs' ~~ cyIns); |
1295 val rel_infos = (ctr_defs' ~~ cxIns, ctr_defs' ~~ cyIns); |
1283 |
1296 |
1284 fun mk_rel_thm postproc ctr_defs' cxIn cyIn = |
1297 fun mk_rel_thm postproc ctr_defs' cxIn cyIn = |
1285 fold_thms lthy ctr_defs' |
1298 fold_thms lthy ctr_defs' |