466 val cqfsss = map3 (map3 (map3 build_dtor_coiter_arg)) f_Tsss cqssss cfssss; |
466 val cqfsss = map3 (map3 (map3 build_dtor_coiter_arg)) f_Tsss cqssss cfssss; |
467 in |
467 in |
468 Term.list_comb (dtor_coiter, map4 mk_preds_getterss_join cs cpss f_sum_prod_Ts cqfsss) |
468 Term.list_comb (dtor_coiter, map4 mk_preds_getterss_join cs cpss f_sum_prod_Ts cqfsss) |
469 end; |
469 end; |
470 |
470 |
471 fun define_iters iterNs iter_args_typess' mk_binding fpTs Cs ctor_iters lthy0 = |
471 fun define_co_iters fp fpT Cs binding_specs lthy0 = |
472 let |
472 let |
473 val thy = Proof_Context.theory_of lthy0; |
473 val thy = Proof_Context.theory_of lthy0; |
474 |
474 |
|
475 val ((csts, defs), (lthy', lthy)) = lthy0 |
|
476 |> apfst split_list o fold_map (fn (b, spec) => |
|
477 Specification.definition (SOME (b, NONE, NoSyn), ((Thm.def_binding b, []), spec)) |
|
478 #>> apsnd snd) binding_specs |
|
479 ||> `Local_Theory.restore; |
|
480 |
|
481 val phi = Proof_Context.export_morphism lthy lthy'; |
|
482 |
|
483 val csts' = map (mk_co_iter thy fp fpT Cs o Morphism.term phi) csts; |
|
484 val defs' = map (Morphism.thm phi) defs; |
|
485 in |
|
486 ((csts', defs'), lthy') |
|
487 end; |
|
488 |
|
489 fun define_iters iterNs iter_args_typess' mk_binding fpTs Cs ctor_iters lthy = |
|
490 let |
475 val nn = length fpTs; |
491 val nn = length fpTs; |
476 |
492 |
477 val fpT_to_C as Type (_, [fpT, _]) = snd (strip_typeN nn (fastype_of (hd ctor_iters))); |
493 val fpT_to_C as Type (_, [fpT, _]) = snd (strip_typeN nn (fastype_of (hd ctor_iters))); |
478 |
494 |
479 fun generate_iter suf (f_Tss, _, fss, xssss) ctor_iter = |
495 fun generate_iter suf (f_Tss, _, fss, xssss) ctor_iter = |
482 val b = mk_binding suf; |
498 val b = mk_binding suf; |
483 val spec = |
499 val spec = |
484 mk_Trueprop_eq (lists_bmoc fss (Free (Binding.name_of b, res_T)), |
500 mk_Trueprop_eq (lists_bmoc fss (Free (Binding.name_of b, res_T)), |
485 mk_iter_body ctor_iter fss xssss); |
501 mk_iter_body ctor_iter fss xssss); |
486 in (b, spec) end; |
502 in (b, spec) end; |
487 |
|
488 val binding_specs = map3 generate_iter iterNs iter_args_typess' ctor_iters; |
|
489 |
|
490 val ((csts, defs), (lthy', lthy)) = lthy0 |
|
491 |> apfst split_list o fold_map (fn (b, spec) => |
|
492 Specification.definition (SOME (b, NONE, NoSyn), ((Thm.def_binding b, []), spec)) |
|
493 #>> apsnd snd) binding_specs |
|
494 ||> `Local_Theory.restore; |
|
495 |
|
496 val phi = Proof_Context.export_morphism lthy lthy'; |
|
497 |
|
498 val iter_defs = map (Morphism.thm phi) defs; |
|
499 |
|
500 val iters = map (mk_co_iter thy Least_FP fpT Cs o Morphism.term phi) csts; |
|
501 in |
503 in |
502 ((iters, iter_defs), lthy') |
504 define_co_iters Least_FP fpT Cs (map3 generate_iter iterNs iter_args_typess' ctor_iters) lthy |
503 end; |
505 end; |
504 |
506 |
505 (* TODO: merge with above function? *) |
507 fun define_coiters coiterNs (cs, cpss, coiter_args_typess') mk_binding fpTs Cs dtor_coiters lthy = |
506 fun define_coiters coiterNs (cs, cpss, coiter_args_typess') mk_binding fpTs Cs dtor_coiters lthy0 = |
508 let |
507 let |
|
508 val thy = Proof_Context.theory_of lthy0; |
|
509 |
|
510 val nn = length fpTs; |
509 val nn = length fpTs; |
511 |
510 |
512 val C_to_fpT as Type (_, [_, fpT]) = snd (strip_typeN nn (fastype_of (hd dtor_coiters))); |
511 val C_to_fpT as Type (_, [_, fpT]) = snd (strip_typeN nn (fastype_of (hd dtor_coiters))); |
513 |
512 |
514 fun generate_coiter suf ((pfss, cqssss, cfssss), (f_sum_prod_Ts, f_Tsss, pf_Tss)) dtor_coiter = |
513 fun generate_coiter suf ((pfss, cqssss, cfssss), (f_sum_prod_Ts, f_Tsss, pf_Tss)) dtor_coiter = |
515 let |
514 let |
516 val res_T = fold_rev (curry (op --->)) pf_Tss C_to_fpT; |
515 val res_T = fold_rev (curry (op --->)) pf_Tss C_to_fpT; |
517 val b = mk_binding suf; |
516 val b = mk_binding suf; |
518 val spec = |
517 val spec = |
519 mk_Trueprop_eq (lists_bmoc pfss (Free (Binding.name_of b, res_T)), |
518 mk_Trueprop_eq (lists_bmoc pfss (Free (Binding.name_of b, res_T)), |
520 mk_coiter_body lthy0 cs cpss f_sum_prod_Ts f_Tsss cqssss cfssss dtor_coiter); |
519 mk_coiter_body lthy cs cpss f_sum_prod_Ts f_Tsss cqssss cfssss dtor_coiter); |
521 in (b, spec) end; |
520 in (b, spec) end; |
522 |
|
523 val binding_specs = map3 generate_coiter coiterNs coiter_args_typess' dtor_coiters; |
|
524 |
|
525 val ((csts, defs), (lthy', lthy)) = lthy0 |
|
526 |> apfst split_list o fold_map (fn (b, spec) => |
|
527 Specification.definition (SOME (b, NONE, NoSyn), ((Thm.def_binding b, []), spec)) |
|
528 #>> apsnd snd) binding_specs |
|
529 ||> `Local_Theory.restore; |
|
530 |
|
531 val phi = Proof_Context.export_morphism lthy lthy'; |
|
532 |
|
533 val coiter_defs = map (Morphism.thm phi) defs; |
|
534 |
|
535 val coiters = map (mk_co_iter thy Greatest_FP fpT Cs o Morphism.term phi) csts; |
|
536 in |
521 in |
537 ((coiters, coiter_defs), lthy') |
522 define_co_iters Greatest_FP fpT Cs |
|
523 (map3 generate_coiter coiterNs coiter_args_typess' dtor_coiters) lthy |
538 end; |
524 end; |
539 |
525 |
540 fun derive_induct_fold_rec_thms_for_types pre_bnfs [ctor_folds, ctor_recs] |
526 fun derive_induct_fold_rec_thms_for_types pre_bnfs [ctor_folds, ctor_recs] |
541 [fold_args_types, rec_args_types] ctor_induct [ctor_fold_thms, ctor_rec_thms] nesting_bnfs |
527 [fold_args_types, rec_args_types] ctor_induct [ctor_fold_thms, ctor_rec_thms] nesting_bnfs |
542 nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss [folds, recs] [fold_defs, rec_defs] lthy = |
528 nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss [folds, recs] [fold_defs, rec_defs] lthy = |