18 xxfold_thmss: thm list list, |
18 xxfold_thmss: thm list list, |
19 xxrec_thmss: thm list list}; |
19 xxrec_thmss: thm list list}; |
20 |
20 |
21 val fp_sugar_of: local_theory -> string -> fp_sugar option |
21 val fp_sugar_of: local_theory -> string -> fp_sugar option |
22 |
22 |
23 val build_maps: local_theory -> typ list -> (int -> typ * typ -> term) -> typ * typ -> term |
23 val build_map: local_theory -> typ list -> (int -> typ * typ -> term) -> typ * typ -> term |
24 |
24 |
25 val mk_fp_iter_fun_types: term -> typ list |
25 val mk_fp_iter_fun_types: term -> typ list |
26 val mk_fun_arg_typess: int -> int list -> typ -> typ list list |
26 val mk_fun_arg_typess: int -> int list -> typ -> typ list list |
27 val unzip_recT: typ list -> typ -> typ list * typ list |
27 val unzip_recT: typ list -> typ -> typ list * typ list |
28 val mk_fold_fun_typess: typ list list list -> typ list list -> typ list list |
28 val mk_fold_fun_typess: typ list list list -> typ list list -> typ list list |
368 val live = live_of_bnf bnf; |
368 val live = live_of_bnf bnf; |
369 val mapx = mk_map live Ts Us (map_of_bnf bnf); |
369 val mapx = mk_map live Ts Us (map_of_bnf bnf); |
370 val TUs' = map dest_funT (fst (strip_typeN live (fastype_of mapx))); |
370 val TUs' = map dest_funT (fst (strip_typeN live (fastype_of mapx))); |
371 in Term.list_comb (mapx, map build_arg TUs') end; |
371 in Term.list_comb (mapx, map build_arg TUs') end; |
372 |
372 |
373 fun build_maps lthy Ts build_simple = |
373 fun build_map lthy Ts build_simple = |
374 let |
374 let |
375 fun build (TU as (T, U)) = |
375 fun build (TU as (T, U)) = |
376 if T = U then |
376 if T = U then |
377 id_const T |
377 id_const T |
378 else |
378 else |
379 (case find_index (curry (op =) T) Ts of |
379 (case find_index (curry (op =) T) Ts of |
380 ~1 => build_map_step lthy build TU |
380 ~1 => build_map_step lthy build TU |
381 | kk => build_simple kk TU); |
381 | kk => build_simple kk TU); |
|
382 in build end; |
|
383 |
|
384 fun build_map' lthy build_simple = |
|
385 let |
|
386 fun build (TU as (T, U)) = |
|
387 if T = U then |
|
388 id_const T |
|
389 else |
|
390 (case TU of |
|
391 (Type (s, _), Type (s', _)) => |
|
392 if s = s' then build_map_step lthy build TU else build_simple TU |
|
393 | _ => build_simple TU); |
382 in build end; |
394 in build end; |
383 |
395 |
384 fun build_rel_step lthy build_arg (Type (s, Ts)) = |
396 fun build_rel_step lthy build_arg (Type (s, Ts)) = |
385 let |
397 let |
386 val bnf = the (bnf_of lthy s); |
398 val bnf = the (bnf_of lthy s); |
516 |
528 |
517 val mk_U = typ_subst_nonatomic (map2 pair fpTs Cs); |
529 val mk_U = typ_subst_nonatomic (map2 pair fpTs Cs); |
518 |
530 |
519 fun unzip_iters fiters combine (x as Free (_, T)) = |
531 fun unzip_iters fiters combine (x as Free (_, T)) = |
520 if exists_subtype_in fpTs T then |
532 if exists_subtype_in fpTs T then |
521 combine (x, build_maps lthy fpTs (K o nth fiters) (T, mk_U T) $ x) |
533 combine (x, build_map lthy fpTs (K o nth fiters) (T, mk_U T) $ x) |
522 else |
534 else |
523 ([x], []); |
535 ([x], []); |
524 |
536 |
525 val gxsss = map (map (flat_rec (unzip_iters gfolds (fn (_, t) => ([t], []))))) xsss; |
537 val gxsss = map (map (flat_rec (unzip_iters gfolds (fn (_, t) => ([t], []))))) xsss; |
526 val hxsss = map (map (flat_rec (unzip_iters hrecs (pairself single)))) xsss; |
538 val hxsss = map (map (flat_rec (unzip_iters hrecs (pairself single)))) xsss; |
684 |
696 |
685 val mk_U = typ_subst_nonatomic (map2 pair Cs fpTs); |
697 val mk_U = typ_subst_nonatomic (map2 pair Cs fpTs); |
686 |
698 |
687 fun intr_coiters fcoiters [] [cf] = |
699 fun intr_coiters fcoiters [] [cf] = |
688 let val T = fastype_of cf in |
700 let val T = fastype_of cf in |
689 if exists_subtype_in Cs T then build_maps lthy Cs (K o nth fcoiters) (T, mk_U T) $ cf |
701 if exists_subtype_in Cs T then build_map lthy Cs (K o nth fcoiters) (T, mk_U T) $ cf |
690 else cf |
702 else cf |
691 end |
703 end |
692 | intr_coiters fcoiters [cq] [cf, cf'] = |
704 | intr_coiters fcoiters [cq] [cf, cf'] = |
693 mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']); |
705 mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']); |
694 |
706 |
1171 |
1183 |
1172 fun define_fold_rec no_defs_lthy = |
1184 fun define_fold_rec no_defs_lthy = |
1173 let |
1185 let |
1174 val fpT_to_C = fpT --> C; |
1186 val fpT_to_C = fpT --> C; |
1175 |
1187 |
1176 fun build_prod_proj mk_proj (TU as (T, U)) = |
1188 fun build_prod_proj mk_proj = build_map' lthy (mk_proj o fst); |
1177 if T = U then |
|
1178 id_const T |
|
1179 else |
|
1180 (case TU of |
|
1181 (Type (s, _), Type (s', _)) => |
|
1182 if s = s' then build_map_step lthy (build_prod_proj mk_proj) TU else mk_proj T |
|
1183 | _ => mk_proj T); |
|
1184 |
1189 |
1185 (* TODO: Avoid these complications; cf. corec case *) |
1190 (* TODO: Avoid these complications; cf. corec case *) |
1186 fun mk_U proj (Type (s as @{type_name prod}, Ts as [T', U])) = |
1191 fun mk_U proj (Type (s as @{type_name prod}, Ts as [T', U])) = |
1187 if member (op =) fpTs T' then proj (T', U) else Type (s, map (mk_U proj) Ts) |
1192 if member (op =) fpTs T' then proj (T', U) else Type (s, map (mk_U proj) Ts) |
1188 | mk_U proj (Type (s, Ts)) = Type (s, map (mk_U proj) Ts) |
1193 | mk_U proj (Type (s, Ts)) = Type (s, map (mk_U proj) Ts) |
1231 |
1236 |
1232 fun define_unfold_corec no_defs_lthy = |
1237 fun define_unfold_corec no_defs_lthy = |
1233 let |
1238 let |
1234 val B_to_fpT = C --> fpT; |
1239 val B_to_fpT = C --> fpT; |
1235 |
1240 |
1236 fun build_sum_inj mk_inj (TU as (T, U)) = |
1241 fun build_sum_inj mk_inj = build_map' lthy (uncurry mk_inj o dest_sumT o snd); |
1237 if T = U then |
|
1238 id_const T |
|
1239 else |
|
1240 (case TU of |
|
1241 (Type (s, _), Type (s', _)) => |
|
1242 if s = s' then build_map_step lthy (build_sum_inj mk_inj) TU |
|
1243 else uncurry mk_inj (dest_sumT U) |
|
1244 | _ => uncurry mk_inj (dest_sumT U)); |
|
1245 |
1242 |
1246 fun build_dtor_coiter_arg _ [] [cf] = cf |
1243 fun build_dtor_coiter_arg _ [] [cf] = cf |
1247 | build_dtor_coiter_arg T [cq] [cf, cf'] = |
1244 | build_dtor_coiter_arg T [cq] [cf, cf'] = |
1248 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf) |
1245 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf) |
1249 (build_sum_inj Inr_const (fastype_of cf', T) $ cf') |
1246 (build_sum_inj Inr_const (fastype_of cf', T) $ cf') |