1(* Title: HOL/Tools/BNF/bnf_gfp_grec.ML 2 Author: Jasmin Blanchette, Inria, LORIA, MPII 3 Author: Aymeric Bouzy, Ecole polytechnique 4 Author: Dmitriy Traytel, ETH Z��rich 5 Copyright 2015, 2016 6 7Generalized corecursor construction. 8*) 9 10signature BNF_GFP_GREC = 11sig 12 val Tsubst: typ -> typ -> typ -> typ 13 val substT: typ -> typ -> term -> term 14 val freeze_types: Proof.context -> (indexname * sort) list -> typ list -> typ list 15 val dummify_atomic_types: term -> term 16 val define_const: bool -> binding -> int -> string -> term -> local_theory -> 17 (term * thm) * local_theory 18 19 type buffer = 20 {Oper: term, 21 VLeaf: term, 22 CLeaf: term, 23 ctr_wrapper: term, 24 friends: (typ * term) Symtab.table} 25 26 val map_buffer: (term -> term) -> buffer -> buffer 27 val specialize_buffer_types: buffer -> buffer 28 29 type dtor_coinduct_info = 30 {dtor_coinduct: thm, 31 cong_def: thm, 32 cong_locale: thm, 33 cong_base: thm, 34 cong_refl: thm, 35 cong_sym: thm, 36 cong_trans: thm, 37 cong_alg_intros: thm list} 38 39 type corec_info = 40 {fp_b: binding, 41 version: int, 42 fpT: typ, 43 Y: typ, 44 Z: typ, 45 friend_names: string list, 46 sig_fp_sugars: BNF_FP_Def_Sugar.fp_sugar list, 47 ssig_fp_sugar: BNF_FP_Def_Sugar.fp_sugar, 48 Lam: term, 49 proto_sctr: term, 50 flat: term, 51 eval_core: term, 52 eval: term, 53 algLam: term, 54 corecUU: term, 55 dtor_transfer: thm, 56 Lam_transfer: thm, 57 Lam_pointful_natural: thm, 58 proto_sctr_transfer: thm, 59 flat_simps: thm list, 60 eval_core_simps: thm list, 61 eval_thm: thm, 62 eval_simps: thm list, 63 all_algLam_algs: thm list, 64 algLam_thm: thm, 65 dtor_algLam: thm, 66 corecUU_thm: thm, 67 corecUU_unique: thm, 68 corecUU_transfer: thm, 69 buffer: buffer, 70 all_dead_k_bnfs: BNF_Def.bnf list, 71 Retr: term, 72 equivp_Retr: thm, 73 Retr_coinduct: thm, 74 dtor_coinduct_info: dtor_coinduct_info} 75 76 type friend_info = 77 {algrho: term, 78 dtor_algrho: thm, 79 algLam_algrho: thm} 80 81 val not_codatatype: Proof.context -> typ -> 'a 82 val mk_fp_binding: binding -> string -> binding 83 val bnf_kill_all_but: int -> BNF_Def.bnf -> local_theory -> BNF_Def.bnf * local_theory 84 85 val print_corec_infos: Proof.context -> unit 86 val has_no_corec_info: Proof.context -> string -> bool 87 val corec_info_of: typ -> local_theory -> corec_info * local_theory 88 val maybe_corec_info_of: Proof.context -> typ -> corec_info option 89 val corec_infos_of: Proof.context -> string -> corec_info list 90 val corec_infos_of_generic: Context.generic -> Symtab.key -> corec_info list 91 val prepare_friend_corec: string -> typ -> local_theory -> 92 (corec_info * binding * int * typ * typ * typ * typ * typ * BNF_Def.bnf * BNF_Def.bnf 93 * BNF_FP_Def_Sugar.fp_sugar * BNF_FP_Def_Sugar.fp_sugar * buffer) * local_theory 94 val register_friend_corec: string -> binding -> int -> typ -> typ -> typ -> BNF_Def.bnf -> 95 BNF_FP_Def_Sugar.fp_sugar -> BNF_FP_Def_Sugar.fp_sugar -> term -> term -> thm -> corec_info -> 96 local_theory -> friend_info * local_theory 97end; 98 99structure BNF_GFP_Grec : BNF_GFP_GREC = 100struct 101 102open Ctr_Sugar 103open BNF_Util 104open BNF_Def 105open BNF_Comp 106open BNF_FP_Util 107open BNF_LFP 108open BNF_FP_Def_Sugar 109open BNF_LFP_Rec_Sugar 110open BNF_GFP_Grec_Tactics 111 112val algLamN = "algLam"; 113val algLam_algLamN = "algLam_algLam"; 114val algLam_algrhoN = "algLam_algrho"; 115val algrhoN = "algrho"; 116val CLeafN = "CLeaf"; 117val congN = "congclp"; 118val cong_alg_introsN = "cong_alg_intros"; 119val cong_localeN = "cong_locale"; 120val corecUUN = "corecUU"; 121val corecUU_transferN = "corecUU_transfer"; 122val corecUU_uniqueN = "corecUU_unique"; 123val cutSsigN = "cutSsig"; 124val dtor_algLamN = "dtor_algLam"; 125val dtor_algrhoN = "dtor_algrho"; 126val dtor_coinductN = "dtor_coinduct"; 127val dtor_transferN = "dtor_transfer"; 128val embLN = "embL"; 129val embLLN = "embLL"; 130val embLRN = "embLR"; 131val embL_pointful_naturalN = "embL_pointful_natural"; 132val embL_transferN = "embL_transfer"; 133val equivp_RetrN = "equivp_Retr"; 134val evalN = "eval"; 135val eval_coreN = "eval_core"; 136val eval_core_pointful_naturalN = "eval_core_pointful_natural"; 137val eval_core_transferN = "eval_core_transfer"; 138val eval_flatN = "eval_flat"; 139val eval_simpsN = "eval_simps"; 140val flatN = "flat"; 141val flat_pointful_naturalN = "flat_pointful_natural"; 142val flat_transferN = "flat_transfer"; 143val k_as_ssig_naturalN = "k_as_ssig_natural"; 144val k_as_ssig_transferN = "k_as_ssig_transfer"; 145val LamN = "Lam"; 146val Lam_transferN = "Lam_transfer"; 147val Lam_pointful_naturalN = "Lam_pointful_natural"; 148val OperN = "Oper"; 149val proto_sctrN = "proto_sctr"; 150val proto_sctr_pointful_naturalN = "proto_sctr_pointful_natural"; 151val proto_sctr_transferN = "proto_sctr_transfer"; 152val rho_transferN = "rho_transfer"; 153val Retr_coinductN = "Retr_coinduct"; 154val sctrN = "sctr"; 155val sctr_transferN = "sctr_transfer"; 156val sctr_pointful_naturalN = "sctr_pointful_natural"; 157val sigN = "sig"; 158val SigN = "Sig"; 159val Sig_pointful_naturalN = "Sig_pointful_natural"; 160val corecUN = "corecU"; 161val corecU_ctorN = "corecU_ctor"; 162val corecU_uniqueN = "corecU_unique"; 163val unsigN = "unsig"; 164val VLeafN = "VLeaf"; 165 166val s_prefix = "s"; (* transforms "sig" into "ssig" *) 167 168fun not_codatatype ctxt T = 169 error ("Not a codatatype: " ^ Syntax.string_of_typ ctxt T); 170fun mutual_codatatype () = 171 error ("Mutually corecursive codatatypes are not supported (try " ^ 172 quote (#1 \<^command_keyword>\<open>primcorec\<close>) ^ " instead of " ^ 173 quote (#1 \<^command_keyword>\<open>corec\<close>) ^ ")"); 174fun noncorecursive_codatatype () = 175 error ("Noncorecursive codatatypes are not supported (try " ^ 176 quote (#1 \<^command_keyword>\<open>definition\<close>) ^ " instead of " ^ 177 quote (#1 \<^command_keyword>\<open>corec\<close>) ^ ")"); 178fun singleton_codatatype ctxt = 179 error ("Singleton corecursive codatatypes are not supported (use " ^ 180 quote (Syntax.string_of_typ ctxt \<^typ>\<open>unit\<close>) ^ " instead)"); 181 182fun merge_lists eq old1 old2 = (old1 |> subtract eq old2) @ old2; 183 184fun add_type_namesT (Type (s, Ts)) = insert (op =) s #> fold add_type_namesT Ts 185 | add_type_namesT _ = I; 186 187fun Tsubst Y T = Term.typ_subst_atomic [(Y, T)]; 188fun substT Y T = Term.subst_atomic_types [(Y, T)]; 189 190fun freeze_types ctxt except_tvars Ts = 191 let 192 val As = fold Term.add_tvarsT Ts [] |> subtract (op =) except_tvars; 193 val (Bs, _) = ctxt |> mk_TFrees' (map snd As); 194 in 195 map (Term.typ_subst_TVars (map fst As ~~ Bs)) Ts 196 end; 197 198fun typ_unify_disjointly thy (T, T') = 199 if T = T' then 200 T 201 else 202 let 203 val tvars = Term.add_tvar_namesT T []; 204 val tvars' = Term.add_tvar_namesT T' []; 205 val maxidx' = maxidx_of_typ T'; 206 val T = T |> exists (member (op =) tvars') tvars ? Logic.incr_tvar (maxidx' + 1); 207 val maxidx = Integer.max (maxidx_of_typ T) maxidx'; 208 val (tyenv, _) = Sign.typ_unify thy (T, T') (Vartab.empty, maxidx); 209 in 210 Envir.subst_type tyenv T 211 end; 212 213val dummify_atomic_types = Term.map_types (Term.map_atyps (K Term.dummyT)); 214 215fun mk_internal internal ctxt f = 216 if internal andalso not (Config.get ctxt bnf_internals) then f else I 217fun mk_fp_binding fp_b pre = Binding.map_name (K pre) fp_b 218 |> Binding.qualify true (Binding.name_of fp_b); 219fun mk_version_binding version = Binding.qualify false ("v" ^ string_of_int version); 220fun mk_version_fp_binding internal ctxt = 221 mk_internal internal ctxt Binding.concealed ooo (mk_fp_binding oo mk_version_binding); 222(*FIXME: get rid of ugly names when typedef and primrec respect qualification*) 223fun mk_version_binding_ugly version = Binding.suffix_name ("_v" ^ string_of_int version); 224fun mk_version_fp_binding_ugly internal ctxt version fp_b pre = 225 Binding.prefix_name (pre ^ "_") fp_b 226 |> mk_version_binding_ugly version 227 |> mk_internal internal ctxt Binding.concealed; 228 229fun mk_mapN ctxt live_AsBs TA bnf = 230 let val TB = Term.typ_subst_atomic live_AsBs TA in 231 enforce_type ctxt (snd o strip_typeN (length live_AsBs)) (TA --> TB) (map_of_bnf bnf) 232 end; 233 234fun mk_relN ctxt live_AsBs TA bnf = 235 let val TB = Term.typ_subst_atomic live_AsBs TA in 236 enforce_type ctxt (snd o strip_typeN (length live_AsBs)) (mk_pred2T TA TB) (rel_of_bnf bnf) 237 end; 238 239fun mk_map1 ctxt Y Z = mk_mapN ctxt [(Y, Z)]; 240fun mk_rel1 ctxt Y Z = mk_relN ctxt [(Y, Z)]; 241 242fun define_const internal fp_b version name rhs lthy = 243 let 244 val b = mk_version_fp_binding internal lthy version fp_b name; 245 246 val ((free, (_, def_free)), (lthy, lthy_old)) = lthy 247 |> Local_Theory.open_target |> snd 248 |> Local_Theory.define ((b, NoSyn), ((Thm.def_binding b |> Binding.concealed, []), rhs)) 249 ||> `Local_Theory.close_target; 250 251 val phi = Proof_Context.export_morphism lthy_old lthy; 252 253 val const = Morphism.term phi free; 254 val const' = enforce_type lthy I (fastype_of free) const; 255 in 256 ((const', Morphism.thm phi def_free), lthy) 257 end; 258 259fun define_single_primrec b eqs lthy = 260 let 261 val (([free], [def_free], [simps_free]), (lthy, lthy_old)) = lthy 262 |> Local_Theory.open_target |> snd 263 |> Local_Theory.map_background_naming (mk_internal true lthy Name_Space.concealed) (*TODO check*) 264 |> primrec false [] [(b, NONE, NoSyn)] (map (fn eq => ((Binding.empty_atts, eq), [], [])) eqs) 265 ||> `Local_Theory.close_target; 266 267 val phi = Proof_Context.export_morphism lthy_old lthy; 268 269 val const = Morphism.term phi free; 270 val const' = enforce_type lthy I (fastype_of free) const; 271 in 272 ((const', Morphism.thm phi def_free, map (Morphism.thm phi) simps_free), lthy) 273 end; 274 275type buffer = 276 {Oper: term, 277 VLeaf: term, 278 CLeaf: term, 279 ctr_wrapper: term, 280 friends: (typ * term) Symtab.table}; 281 282fun map_buffer f {Oper, VLeaf, CLeaf, ctr_wrapper, friends} = 283 {Oper = f Oper, VLeaf = f VLeaf, CLeaf = f CLeaf, ctr_wrapper = f ctr_wrapper, 284 friends = Symtab.map (K (apsnd f)) friends}; 285 286fun morph_buffer phi = map_buffer (Morphism.term phi); 287 288fun specialize_buffer_types {Oper, VLeaf, CLeaf, ctr_wrapper, friends} = 289 let 290 val ssig_T as Type (_, Ts) = body_type (fastype_of VLeaf); 291 val Y = List.last Ts; 292 val ssigifyT = substT Y ssig_T; 293 in 294 {Oper = Oper, VLeaf = VLeaf, CLeaf = CLeaf, ctr_wrapper = ssigifyT ctr_wrapper, 295 friends = Symtab.map (K (apsnd ssigifyT)) friends} 296 end; 297 298type dtor_coinduct_info = 299 {dtor_coinduct: thm, 300 cong_def: thm, 301 cong_locale: thm, 302 cong_base: thm, 303 cong_refl: thm, 304 cong_sym: thm, 305 cong_trans: thm, 306 cong_alg_intros: thm list}; 307 308fun map_dtor_coinduct_info f {dtor_coinduct, cong_def, cong_locale, cong_base, cong_refl, cong_sym, 309 cong_trans, cong_alg_intros} = 310 {dtor_coinduct = f dtor_coinduct, cong_def = f cong_def, cong_locale = f cong_locale, 311 cong_base = f cong_base, cong_refl = f cong_refl, cong_sym = f cong_sym, 312 cong_trans = f cong_trans, cong_alg_intros = map f cong_alg_intros}; 313 314fun morph_dtor_coinduct_info phi = map_dtor_coinduct_info (Morphism.thm phi); 315 316type corec_ad = 317 {fpT: typ, 318 friend_names: string list}; 319 320fun morph_corec_ad phi {fpT, friend_names} = 321 {fpT = Morphism.typ phi fpT, friend_names = friend_names}; 322 323type corec_info = 324 {fp_b: binding, 325 version: int, 326 fpT: typ, 327 Y: typ, 328 Z: typ, 329 friend_names: string list, 330 sig_fp_sugars: fp_sugar list, 331 ssig_fp_sugar: fp_sugar, 332 Lam: term, 333 proto_sctr: term, 334 flat: term, 335 eval_core: term, 336 eval: term, 337 algLam: term, 338 corecUU: term, 339 dtor_transfer: thm, 340 Lam_transfer: thm, 341 Lam_pointful_natural: thm, 342 proto_sctr_transfer: thm, 343 flat_simps: thm list, 344 eval_core_simps: thm list, 345 eval_thm: thm, 346 eval_simps: thm list, 347 all_algLam_algs: thm list, 348 algLam_thm: thm, 349 dtor_algLam: thm, 350 corecUU_thm: thm, 351 corecUU_unique: thm, 352 corecUU_transfer: thm, 353 buffer: buffer, 354 all_dead_k_bnfs: bnf list, 355 Retr: term, 356 equivp_Retr: thm, 357 Retr_coinduct: thm, 358 dtor_coinduct_info: dtor_coinduct_info}; 359 360fun morph_corec_info phi 361 ({fp_b, version, fpT, Y, Z, friend_names, sig_fp_sugars, ssig_fp_sugar, Lam, proto_sctr, flat, 362 eval_core, eval, algLam, corecUU, dtor_transfer, Lam_transfer, Lam_pointful_natural, 363 proto_sctr_transfer, flat_simps, eval_core_simps, eval_thm, eval_simps, all_algLam_algs, 364 algLam_thm, dtor_algLam, corecUU_thm, corecUU_unique, corecUU_transfer, buffer, 365 all_dead_k_bnfs, Retr, equivp_Retr, Retr_coinduct, dtor_coinduct_info} : corec_info) = 366 {fp_b = fp_b, version = version, fpT = Morphism.typ phi fpT, Y = Morphism.typ phi Y, 367 Z = Morphism.typ phi Z, friend_names = friend_names, sig_fp_sugars = sig_fp_sugars (*no morph*), 368 ssig_fp_sugar = ssig_fp_sugar (*no morph*), Lam = Morphism.term phi Lam, 369 proto_sctr = Morphism.term phi proto_sctr, flat = Morphism.term phi flat, 370 eval_core = Morphism.term phi eval_core, eval = Morphism.term phi eval, 371 algLam = Morphism.term phi algLam, corecUU = Morphism.term phi corecUU, 372 dtor_transfer = dtor_transfer, Lam_transfer = Morphism.thm phi Lam_transfer, 373 Lam_pointful_natural = Morphism.thm phi Lam_pointful_natural, 374 proto_sctr_transfer = Morphism.thm phi proto_sctr_transfer, 375 flat_simps = map (Morphism.thm phi) flat_simps, 376 eval_core_simps = map (Morphism.thm phi) eval_core_simps, eval_thm = Morphism.thm phi eval_thm, 377 eval_simps = map (Morphism.thm phi) eval_simps, 378 all_algLam_algs = map (Morphism.thm phi) all_algLam_algs, 379 algLam_thm = Morphism.thm phi algLam_thm, dtor_algLam = Morphism.thm phi dtor_algLam, 380 corecUU_thm = Morphism.thm phi corecUU_thm, corecUU_unique = Morphism.thm phi corecUU_unique, 381 corecUU_transfer = Morphism.thm phi corecUU_transfer, buffer = morph_buffer phi buffer, 382 all_dead_k_bnfs = map (morph_bnf phi) all_dead_k_bnfs, Retr = Morphism.term phi Retr, 383 equivp_Retr = Morphism.thm phi equivp_Retr, Retr_coinduct = Morphism.thm phi Retr_coinduct, 384 dtor_coinduct_info = morph_dtor_coinduct_info phi dtor_coinduct_info}; 385 386datatype ('a, 'b) expr = 387 Ad of 'a * (local_theory -> 'b * local_theory) | 388 Info of 'b; 389 390fun is_Ad (Ad _) = true 391 | is_Ad _ = false; 392 393fun is_Info (Info _) = true 394 | is_Info _ = false; 395 396type corec_info_expr = (corec_ad, corec_info) expr; 397 398fun morph_corec_info_expr phi (Ad (ad, f)) = Ad (morph_corec_ad phi ad, f) 399 | morph_corec_info_expr phi (Info info) = Info (morph_corec_info phi info); 400 401val transfer_corec_info_expr = morph_corec_info_expr o Morphism.transfer_morphism; 402 403type corec_data = int Symtab.table * corec_info_expr list Symtab.table list; 404 405structure Data = Generic_Data 406( 407 type T = corec_data; 408 val empty = (Symtab.empty, [Symtab.empty]); 409 val extend = I; 410 fun merge ((version_tab1, info_tabs1), (version_tab2, info_tabs2)) : T = 411 (Symtab.join (K Int.max) (version_tab1, version_tab2), info_tabs1 @ info_tabs2); 412); 413 414fun corec_ad_of_expr (Ad (ad, _)) = ad 415 | corec_ad_of_expr (Info {fpT, friend_names, ...}) = {fpT = fpT, friend_names = friend_names}; 416 417fun corec_info_exprs_of_generic context fpT_name = 418 let 419 val thy = Context.theory_of context; 420 val info_tabs = snd (Data.get context); 421 in 422 maps (fn info_tab => these (Symtab.lookup info_tab fpT_name)) info_tabs 423 |> map (transfer_corec_info_expr thy) 424 end; 425 426val corec_info_exprs_of = corec_info_exprs_of_generic o Context.Proof; 427 428val keep_corec_infos = map_filter (fn Ad _ => NONE | Info info => SOME info); 429 430val corec_infos_of_generic = keep_corec_infos oo corec_info_exprs_of_generic; 431val corec_infos_of = keep_corec_infos oo corec_info_exprs_of; 432 433fun str_of_corec_ad ctxt {fpT, friend_names} = 434 "[" ^ Syntax.string_of_typ ctxt fpT ^ "; " ^ commas friend_names ^ "]"; 435 436fun str_of_corec_info ctxt {fpT, version, friend_names, ...} = 437 "{" ^ Syntax.string_of_typ ctxt fpT ^ "; " ^ commas friend_names ^ "; v" ^ string_of_int version ^ 438 "}"; 439 440fun str_of_corec_info_expr ctxt (Ad (ad, _)) = str_of_corec_ad ctxt ad 441 | str_of_corec_info_expr ctxt (Info info) = str_of_corec_info ctxt info; 442 443fun print_corec_infos ctxt = 444 Symtab.fold (fn (fpT_name, exprs) => fn () => 445 writeln (fpT_name ^ ":\n" ^ 446 cat_lines (map (prefix " " o str_of_corec_info_expr ctxt) exprs))) 447 (the_single (snd (Data.get (Context.Proof ctxt)))) (); 448 449val has_no_corec_info = null oo corec_info_exprs_of; 450 451fun get_name_next_version_of fpT_name ctxt = 452 let 453 val (version_tab, info_tabs) = Data.get (Context.Theory (Proof_Context.theory_of ctxt)); 454 val fp_base = Long_Name.base_name fpT_name; 455 val fp_b = Binding.name fp_base; 456 val version_tab' = Symtab.map_default (fp_base, ~1) (Integer.add 1) version_tab; 457 val SOME version = Symtab.lookup version_tab' fp_base; 458 val ctxt' = ctxt 459 |> Local_Theory.background_theory (Context.theory_map (Data.put (version_tab', info_tabs))); 460 in 461 ((fp_b, version), ctxt') 462 end; 463 464type friend_info = 465 {algrho: term, 466 dtor_algrho: thm, 467 algLam_algrho: thm}; 468 469fun morph_friend_info phi ({algrho, dtor_algrho, algLam_algrho} : friend_info) = 470 {algrho = Morphism.term phi algrho, dtor_algrho = Morphism.thm phi dtor_algrho, 471 algLam_algrho = Morphism.thm phi algLam_algrho}; 472 473fun checked_fp_sugar_of ctxt fpT_name = 474 let 475 val fp_sugar as {X, fp_res = {Ts = fpTs, ...}, fp_ctr_sugar = {ctrXs_Tss, ...}, ...} = 476 (case fp_sugar_of ctxt fpT_name of 477 SOME (fp_sugar as {fp = Greatest_FP, ...}) => fp_sugar 478 | _ => not_codatatype ctxt (Type (fpT_name, [] (*yuck*)))); 479 480 val _ = 481 if length fpTs > 1 then 482 mutual_codatatype () 483 else if not (exists (exists (Term.exists_subtype (curry (op =) X))) ctrXs_Tss) then 484 noncorecursive_codatatype () 485 else if ctrXs_Tss = [[X]] then 486 singleton_codatatype ctxt 487 else 488 (); 489 in 490 fp_sugar 491 end; 492 493fun bnf_kill_all_but nn bnf lthy = 494 ((empty_comp_cache, empty_unfolds), lthy) 495 |> kill_bnf I (live_of_bnf bnf - nn) bnf 496 ||> snd; 497 498fun bnf_with_deads_and_lives dead_Es live_As Y fpT T lthy = 499 let 500 val qsoty = quote o Syntax.string_of_typ lthy; 501 502 val unfreeze_fp = Tsubst Y fpT; 503 504 fun flatten_tyargs Ass = 505 map dest_TFree live_As 506 |> filter (fn T => exists (fn Ts => member (op =) Ts T) Ass); 507 508 val ((bnf, _), (_, lthy)) = 509 bnf_of_typ false Do_Inline I flatten_tyargs [Term.dest_TFree Y] (map Term.dest_TFree dead_Es) 510 T ((empty_comp_cache, empty_unfolds), lthy) 511 handle BAD_DEAD (Y, Y_backdrop) => 512 (case Y_backdrop of 513 Type (bad_tc, _) => 514 let 515 val T = qsoty (unfreeze_fp Y); 516 val T_backdrop = qsoty (unfreeze_fp Y_backdrop); 517 fun register_hint () = 518 "\nUse the " ^ quote (#1 \<^command_keyword>\<open>bnf\<close>) ^ " command to register " ^ 519 quote bad_tc ^ " as a bounded natural functor to allow nested (co)recursion through \ 520 \it"; 521 in 522 if is_some (bnf_of lthy bad_tc) orelse is_some (fp_sugar_of lthy bad_tc) then 523 error ("Inadmissible occurrence of type " ^ T ^ " in type expression " ^ 524 T_backdrop) 525 else 526 error ("Unsupported occurrence of type " ^ T ^ " via type constructor " ^ 527 quote bad_tc ^ " in type expression " ^ T_backdrop ^ register_hint ()) 528 end); 529 530 val phi = 531 Morphism.term_morphism "BNF" (Raw_Simplifier.rewrite_term (Proof_Context.theory_of lthy) 532 @{thms BNF_Composition.id_bnf_def} []) 533 $> Morphism.thm_morphism "BNF" (unfold_thms lthy @{thms BNF_Composition.id_bnf_def}); 534 in 535 (morph_bnf phi bnf, lthy) 536 end; 537 538fun define_sig_type fp_b version fp_alives Es Y rhsT lthy = 539 let 540 val T_b = mk_version_fp_binding_ugly true lthy version fp_b sigN; 541 val ctr_b = mk_version_fp_binding false lthy version fp_b SigN; 542 val sel_b = mk_version_fp_binding true lthy version fp_b unsigN; 543 544 val lthy = Local_Theory.open_target lthy |> snd; 545 546 val T_name = Local_Theory.full_name lthy T_b; 547 548 val tyargs = map2 (fn alive => fn T => 549 (if alive then SOME Binding.empty else NONE, (T, Type.sort_of_atyp T))) 550 (fp_alives @ [true]) (Es @ [Y]); 551 val ctr_specs = [(((Binding.empty, ctr_b), [(sel_b, rhsT)]), NoSyn)]; 552 val spec = (((((tyargs, T_b), NoSyn), ctr_specs), 553 (Binding.empty, Binding.empty, Binding.empty)), []); 554 555 val plugins = Plugin_Name.make_filter lthy (K (curry (op =) transfer_plugin)); 556 val discs_sels = true; 557 558 val lthy = lthy 559 |> Local_Theory.map_background_naming (mk_internal true lthy Name_Space.concealed) (*TODO check*) 560 |> with_typedef_threshold ~1 561 (co_datatypes Least_FP construct_lfp ((plugins, discs_sels), [spec])) 562 |> Local_Theory.close_target; 563 564 val SOME fp_sugar = fp_sugar_of lthy T_name; 565 in 566 (fp_sugar, lthy) 567 end; 568 569fun define_ssig_type fp_b version fp_alives Es Y fpT lthy = 570 let 571 val sig_T_b = mk_version_fp_binding_ugly true lthy version fp_b sigN; 572 val T_b = Binding.prefix_name s_prefix sig_T_b; 573 val Oper_b = mk_version_fp_binding false lthy version fp_b OperN; 574 val VLeaf_b = mk_version_fp_binding false lthy version fp_b VLeafN; 575 val CLeaf_b = mk_version_fp_binding false lthy version fp_b CLeafN; 576 577 val lthy = Local_Theory.open_target lthy |> snd; 578 579 val sig_T_name = Local_Theory.full_name lthy sig_T_b; 580 val T_name = Long_Name.map_base_name (prefix s_prefix) sig_T_name; 581 582 val As = Es @ [Y]; 583 val ssig_sig_T = Type (sig_T_name, Es @ [Type (T_name, As)]); 584 585 val tyargs = map2 (fn alive => fn T => 586 (if alive then SOME Binding.empty else NONE, (T, Type.sort_of_atyp T))) 587 (fp_alives @ [true]) (Es @ [Y]); 588 val ctr_specs = 589 [(((Binding.empty, Oper_b), [(Binding.empty, ssig_sig_T)]), NoSyn), 590 (((Binding.empty, VLeaf_b), [(Binding.empty, Y)]), NoSyn), 591 (((Binding.empty, CLeaf_b), [(Binding.empty, fpT)]), NoSyn)]; 592 val spec = (((((tyargs, T_b), NoSyn), ctr_specs), 593 (Binding.empty, Binding.empty, Binding.empty)), []); 594 595 val plugins = Plugin_Name.make_filter lthy (K (curry (op =) transfer_plugin)); 596 val discs_sels = false; 597 598 val lthy = lthy 599 |> Local_Theory.map_background_naming (mk_internal true lthy Name_Space.concealed) (*TODO check*) 600 |> with_typedef_threshold ~1 601 (co_datatypes Least_FP construct_lfp ((plugins, discs_sels), [spec])) 602 |> Local_Theory.close_target; 603 604 val SOME fp_sugar = fp_sugar_of lthy T_name; 605 in 606 (fp_sugar, lthy) 607 end; 608 609fun embed_Sig ctxt Sig inl_or_r t = 610 Library.foldl1 HOLogic.mk_comp [Sig, inl_or_r, dummify_atomic_types t] 611 |> Syntax.check_term ctxt; 612 613fun mk_ctr_wrapper_friends ctxt friend_name friend_T old_sig_T k_T Sig old_buffer = 614 let 615 val embed_Sig_inl = embed_Sig ctxt Sig (Inl_const old_sig_T k_T); 616 617 val ctr_wrapper = embed_Sig_inl (#ctr_wrapper old_buffer); 618 val friends = Symtab.map (K (apsnd embed_Sig_inl)) (#friends old_buffer) 619 |> Symtab.update_new (friend_name, (friend_T, 620 HOLogic.mk_comp (Sig, Inr_const old_sig_T k_T))); 621 in 622 (ctr_wrapper, friends) 623 end; 624 625fun pre_type_of_ctor Y ctor = 626 let 627 val (fp_preT, fpT) = dest_funT (fastype_of ctor); 628 in 629 typ_subst_nonatomic [(fpT, Y)] fp_preT 630 end; 631 632fun mk_k_as_ssig Z old_sig_T k_T ssig_T Sig dead_sig_map Oper VLeaf = 633 let 634 val inr' = Inr_const old_sig_T k_T; 635 val dead_sig_map' = substT Z ssig_T dead_sig_map; 636 in 637 Library.foldl1 HOLogic.mk_comp [Oper, dead_sig_map' $ VLeaf, Sig, inr'] 638 end; 639 640fun define_embL name fp_b version Y Z fpT old_sig_T old_ssig_T other_summand_T ssig_T Inl_or_r_const 641 dead_old_sig_map Sig old_Oper old_VLeaf old_CLeaf Oper VLeaf CLeaf lthy = 642 let 643 val embL_b = mk_version_fp_binding true lthy version fp_b name; 644 val old_ssig_old_sig_T = Tsubst Y old_ssig_T old_sig_T; 645 val ssig_old_sig_T = Tsubst Y ssig_T old_sig_T; 646 val ssig_other_summand_T = Tsubst Y ssig_T other_summand_T; 647 648 val sigx = Var (("s", 0), old_ssig_old_sig_T); 649 val x = Var (("x", 0), Y); 650 val j = Var (("j", 0), fpT); 651 val embL = Free (Binding.name_of embL_b, old_ssig_T --> ssig_T); 652 val dead_old_sig_map' = Term.subst_atomic_types [(Y, old_ssig_T), (Z, ssig_T)] dead_old_sig_map; 653 val Sig' = substT Y ssig_T Sig; 654 val inl' = Inl_or_r_const ssig_old_sig_T ssig_other_summand_T; 655 656 val Oper_eq = mk_Trueprop_eq (embL $ (old_Oper $ sigx), 657 Oper $ (Sig' $ (inl' $ (dead_old_sig_map' $ embL $ sigx)))) 658 |> Logic.all sigx; 659 val VLeaf_eq = mk_Trueprop_eq (embL $ (old_VLeaf $ x), VLeaf $ x) 660 |> Logic.all x; 661 val CLeaf_eq = mk_Trueprop_eq (embL $ (old_CLeaf $ j), CLeaf $ j) 662 |> Logic.all j; 663 in 664 define_single_primrec embL_b [Oper_eq, VLeaf_eq, CLeaf_eq] lthy 665 end; 666 667fun define_Lam_base fp_b version Y Z preT ssig_T dead_pre_map Sig unsig dead_sig_map Oper VLeaf 668 lthy = 669 let 670 val YpreT = HOLogic.mk_prodT (Y, preT); 671 672 val snd' = snd_const YpreT; 673 val dead_pre_map' = substT Z ssig_T dead_pre_map; 674 val Sig' = substT Y ssig_T Sig; 675 val unsig' = substT Y ssig_T unsig; 676 val dead_sig_map' = Term.subst_atomic_types [(Y, YpreT), (Z, ssig_T)] dead_sig_map; 677 678 val rhs = HOLogic.mk_comp (unsig', dead_sig_map' 679 $ Library.foldl1 HOLogic.mk_comp [Oper, Sig', dead_pre_map' $ VLeaf, snd']); 680 in 681 define_const true fp_b version LamN rhs lthy 682 end; 683 684fun define_Lam_step_or_merge fp_b version Y preT unsig left_case right_case lthy = 685 let 686 val YpreT = HOLogic.mk_prodT (Y, preT); 687 688 val unsig' = substT Y YpreT unsig; 689 690 val rhs = HOLogic.mk_comp (mk_case_sum (left_case, right_case), unsig'); 691 in 692 define_const true fp_b version LamN rhs lthy 693 end; 694 695fun define_Lam_step fp_b version Y Z preT old_ssig_T ssig_T dead_pre_map unsig rho embL old_Lam 696 lthy = 697 let 698 val dead_pre_map' = Term.subst_atomic_types [(Y, old_ssig_T), (Z, ssig_T)] dead_pre_map; 699 val left_case = HOLogic.mk_comp (dead_pre_map' $ embL, old_Lam); 700 in 701 define_Lam_step_or_merge fp_b version Y preT unsig left_case rho lthy 702 end; 703 704fun define_Lam_merge fp_b version Y Z preT old1_ssig_T old2_ssig_T ssig_T dead_pre_map unsig embLL 705 embLR old1_Lam old2_Lam lthy = 706 let 707 val dead_pre_map' = Term.subst_atomic_types [(Y, old1_ssig_T), (Z, ssig_T)] dead_pre_map; 708 val dead_pre_map'' = Term.subst_atomic_types [(Y, old2_ssig_T), (Z, ssig_T)] dead_pre_map; 709 val left_case = HOLogic.mk_comp (dead_pre_map' $ embLL, old1_Lam); 710 val right_case = HOLogic.mk_comp (dead_pre_map'' $ embLR, old2_Lam); 711 in 712 define_Lam_step_or_merge fp_b version Y preT unsig left_case right_case lthy 713 end; 714 715fun define_proto_sctr_step_or_merge fp_b version old_sig_T right_T Sig old_proto_sctr = 716 let 717 val rhs = Library.foldl1 HOLogic.mk_comp [Sig, Inl_const old_sig_T right_T, old_proto_sctr]; 718 in 719 define_const true fp_b version proto_sctrN rhs 720 end; 721 722fun define_flat fp_b version Y Z fpT sig_T ssig_T Oper VLeaf CLeaf dead_sig_map lthy = 723 let 724 val flat_b = mk_version_fp_binding true lthy version fp_b flatN; 725 val ssig_sig_T = Tsubst Y ssig_T sig_T; 726 val ssig_ssig_sig_T = Tsubst Y ssig_T ssig_sig_T; 727 val ssig_ssig_T = Tsubst Y ssig_T ssig_T; 728 729 val sigx = Var (("s", 0), ssig_ssig_sig_T); 730 val x = Var (("x", 0), ssig_T); 731 val j = Var (("j", 0), fpT); 732 val flat = Free (Binding.name_of flat_b, ssig_ssig_T --> ssig_T); 733 val Oper' = substT Y ssig_T Oper; 734 val VLeaf' = substT Y ssig_T VLeaf; 735 val CLeaf' = substT Y ssig_T CLeaf; 736 val dead_sig_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_sig_map; 737 738 val Oper_eq = mk_Trueprop_eq (flat $ (Oper' $ sigx), Oper $ (dead_sig_map' $ flat $ sigx)) 739 |> Logic.all sigx; 740 val VLeaf_eq = mk_Trueprop_eq (flat $ (VLeaf' $ x), x) 741 |> Logic.all x; 742 val CLeaf_eq = mk_Trueprop_eq (flat $ (CLeaf' $ j), CLeaf $ j) 743 |> Logic.all j; 744 in 745 define_single_primrec flat_b [Oper_eq, VLeaf_eq, CLeaf_eq] lthy 746 end; 747 748fun define_eval_core fp_b version Y Z preT fpT sig_T ssig_T dtor Oper VLeaf CLeaf dead_pre_map 749 dead_sig_map dead_ssig_map flat Lam lthy = 750 let 751 val eval_core_b = mk_version_fp_binding true lthy version fp_b eval_coreN; 752 val YpreT = HOLogic.mk_prodT (Y, preT); 753 val Ypre_ssig_T = Tsubst Y YpreT ssig_T; 754 val Ypre_ssig_sig_T = Tsubst Y Ypre_ssig_T sig_T; 755 val ssig_preT = Tsubst Y ssig_T preT; 756 val ssig_YpreT = Tsubst Y ssig_T YpreT; 757 val ssig_ssig_T = Tsubst Y ssig_T ssig_T; 758 759 val sigx = Var (("s", 0), Ypre_ssig_sig_T); 760 val x = Var (("x", 0), YpreT); 761 val j = Var (("j", 0), fpT); 762 val eval_core = Free (Binding.name_of eval_core_b, Ypre_ssig_T --> ssig_preT); 763 val Oper' = substT Y YpreT Oper; 764 val VLeaf' = substT Y YpreT VLeaf; 765 val CLeaf' = substT Y YpreT CLeaf; 766 val dead_pre_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_pre_map; 767 val dead_pre_map'' = substT Z ssig_T dead_pre_map; 768 val dead_pre_map''' = Term.subst_atomic_types [(Y, fpT), (Z, ssig_T)] dead_pre_map; 769 val dead_sig_map' = Term.subst_atomic_types [(Y, Ypre_ssig_T), (Z, ssig_YpreT)] dead_sig_map; 770 val dead_ssig_map' = Term.subst_atomic_types [(Y, YpreT), (Z, Y)] dead_ssig_map; 771 val Lam' = substT Y ssig_T Lam; 772 val fst' = fst_const YpreT; 773 val snd' = snd_const YpreT; 774 775 val Oper_eq = mk_Trueprop_eq (eval_core $ (Oper' $ sigx), 776 dead_pre_map' $ flat $ (Lam' $ (dead_sig_map' $ (Abs (Name.uu, Ypre_ssig_T, 777 HOLogic.mk_prod (dead_ssig_map' $ fst' $ Bound 0, eval_core $ Bound 0))) $ sigx))) 778 |> Logic.all sigx; 779 val VLeaf_eq = mk_Trueprop_eq (eval_core $ (VLeaf' $ x), dead_pre_map'' $ VLeaf $ (snd' $ x)) 780 |> Logic.all x; 781 val CLeaf_eq = mk_Trueprop_eq (eval_core $ (CLeaf' $ j), dead_pre_map''' $ CLeaf $ (dtor $ j)) 782 |> Logic.all j; 783 in 784 define_single_primrec eval_core_b [Oper_eq, VLeaf_eq, CLeaf_eq] lthy 785 end; 786 787fun define_eval fp_b version Y Z preT fpT ssig_T dtor dtor_unfold dead_ssig_map eval_core lthy = 788 let 789 val fp_preT = Tsubst Y fpT preT; 790 val fppreT = HOLogic.mk_prodT (fpT, fp_preT); 791 val fp_ssig_T = Tsubst Y fpT ssig_T; 792 793 val dtor_unfold' = substT Z fp_ssig_T dtor_unfold; 794 val dead_ssig_map' = Term.subst_atomic_types [(Y, fpT), (Z, fppreT)] dead_ssig_map; 795 val eval_core' = substT Y fpT eval_core; 796 val id' = HOLogic.id_const fpT; 797 798 val rhs = dtor_unfold' $ HOLogic.mk_comp (eval_core', dead_ssig_map' $ mk_convol (id', dtor)); 799 in 800 define_const true fp_b version evalN rhs lthy 801 end; 802 803fun define_cutSsig fp_b version Y Z preT ssig_T dead_pre_map VLeaf dead_ssig_map flat eval_core 804 lthy = 805 let 806 val ssig_preT = Tsubst Y ssig_T preT; 807 val ssig_ssig_T = Tsubst Y ssig_T ssig_T; 808 val ssig_ssig_preT = HOLogic.mk_prodT (ssig_T, ssig_preT); 809 810 val h = Var (("h", 0), Y --> ssig_preT); 811 val dead_pre_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_pre_map; 812 val dead_ssig_map' = substT Z ssig_ssig_preT dead_ssig_map; 813 val eval_core' = substT Y ssig_T eval_core; 814 815 val rhs = Library.foldl1 HOLogic.mk_comp [dead_pre_map' $ flat, eval_core', 816 dead_ssig_map' $ mk_convol (VLeaf, h)] 817 |> Term.lambda h; 818 in 819 define_const true fp_b version cutSsigN rhs lthy 820 end; 821 822fun define_algLam fp_b version Y Z fpT ssig_T Oper VLeaf dead_sig_map eval lthy = 823 let 824 val fp_ssig_T = Tsubst Y fpT ssig_T; 825 826 val Oper' = substT Y fpT Oper; 827 val VLeaf' = substT Y fpT VLeaf; 828 val dead_sig_map' = Term.subst_atomic_types [(Y, fpT), (Z, fp_ssig_T)] dead_sig_map; 829 830 val rhs = Library.foldl1 HOLogic.mk_comp [eval, Oper', dead_sig_map' $ VLeaf']; 831 in 832 define_const true fp_b version algLamN rhs lthy 833 end; 834 835fun define_corecU fp_b version Y Z preT ssig_T dtor_unfold VLeaf cutSsig lthy = 836 let 837 val ssig_preT = Tsubst Y ssig_T preT; 838 839 val h = Var (("h", 0), Y --> ssig_preT); 840 val dtor_unfold' = substT Z ssig_T dtor_unfold; 841 842 val rhs = HOLogic.mk_comp (dtor_unfold' $ (cutSsig $ h), VLeaf) 843 |> Term.lambda h; 844 in 845 define_const true fp_b version corecUN rhs lthy 846 end; 847 848fun define_corecUU fp_b version Y Z preT ssig_T dead_pre_map dead_ssig_map flat eval_core sctr 849 corecU lthy = 850 let 851 val ssig_preT = Tsubst Y ssig_T preT; 852 val ssig_ssig_T = Tsubst Y ssig_T ssig_T 853 val ssig_ssig_preT = HOLogic.mk_prodT (ssig_T, ssig_preT); 854 855 val ssig_pre_ssig_T = Tsubst Y ssig_preT ssig_T; 856 857 val h = Var (("h", 0), Y --> ssig_pre_ssig_T); 858 val dead_pre_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_pre_map; 859 val eval_core' = substT Y ssig_T eval_core; 860 val dead_ssig_map' = 861 Term.subst_atomic_types [(Y, ssig_preT), (Z, ssig_ssig_preT)] dead_ssig_map; 862 val id' = HOLogic.id_const ssig_preT; 863 864 val rhs = corecU $ Library.foldl1 HOLogic.mk_comp 865 [dead_pre_map' $ flat, eval_core', dead_ssig_map' $ mk_convol (sctr, id'), h] 866 |> Term.lambda h; 867 in 868 define_const true fp_b version corecUUN rhs lthy 869 end; 870 871fun derive_sig_transfer maybe_swap ctxt live_AsBs pre_rel sig_rel Rs R const pre_rel_def 872 preT_rel_eqs transfer_thm = 873 let 874 val RRpre_rel = list_comb (pre_rel, Rs) $ R; 875 val RRsig_rel = list_comb (sig_rel, Rs) $ R; 876 val constB = Term.subst_atomic_types live_AsBs const; 877 878 val goal = uncurry mk_rel_fun (maybe_swap (RRpre_rel, RRsig_rel)) $ const $ constB 879 |> HOLogic.mk_Trueprop; 880 in 881 Variable.add_free_names ctxt goal [] 882 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 883 mk_sig_transfer_tac ctxt pre_rel_def preT_rel_eqs transfer_thm)) 884 |> Thm.close_derivation \<^here> 885 end; 886 887fun derive_transfer_by_transfer_prover ctxt live_AsBs Rs R const const_defs rel_eqs transfers = 888 let 889 val constB = Term.subst_atomic_types live_AsBs const; 890 val goal = mk_parametricity_goal ctxt (Rs @ [R]) const constB; 891 in 892 Variable.add_free_names ctxt goal [] 893 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 894 mk_transfer_by_transfer_prover_tac ctxt (const_defs @ map (fn thm => thm RS sym) rel_eqs) 895 rel_eqs transfers)) 896 |> Thm.close_derivation \<^here> 897 end; 898 899fun derive_dtor_transfer ctxt live_EsFs Y Z pre_rel fp_rel Rs dtor dtor_rel_thm = 900 let 901 val Type (\<^type_name>\<open>fun\<close>, [fpT, Type (\<^type_name>\<open>fun\<close>, [fpTB, \<^typ>\<open>bool\<close>])]) = 902 snd (strip_typeN (length live_EsFs) (fastype_of fp_rel)); 903 904 val pre_rel' = Term.subst_atomic_types [(Y, fpT), (Z, fpTB)] pre_rel; 905 val Rpre_rel = list_comb (pre_rel', Rs); 906 val Rfp_rel = list_comb (fp_rel, Rs); 907 val dtorB = Term.subst_atomic_types live_EsFs dtor; 908 909 val goal = HOLogic.mk_Trueprop (mk_rel_fun Rfp_rel (Rpre_rel $ Rfp_rel) $ dtor $ dtorB); 910 in 911 Variable.add_free_names ctxt goal [] 912 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 913 mk_dtor_transfer_tac ctxt dtor_rel_thm)) 914 |> Thm.close_derivation \<^here> 915 end; 916 917fun derive_Lam_or_eval_core_transfer ctxt live_AsBs Y Z preT ssig_T Rs R pre_rel sig_or_ssig_rel 918 ssig_rel const const_def rel_eqs transfers = 919 let 920 val YpreT = HOLogic.mk_prodT (Y, preT); 921 val ZpreTB = typ_subst_atomic live_AsBs YpreT; 922 val ssig_TB = typ_subst_atomic live_AsBs ssig_T; 923 924 val pre_rel' = Term.subst_atomic_types [(Y, ssig_T), (Z, ssig_TB)] pre_rel; 925 val sig_or_ssig_rel' = Term.subst_atomic_types [(Y, YpreT), (Z, ZpreTB)] sig_or_ssig_rel; 926 val Rsig_or_ssig_rel' = list_comb (sig_or_ssig_rel', Rs); 927 val RRpre_rel = list_comb (pre_rel, Rs) $ R; 928 val RRssig_rel = list_comb (ssig_rel, Rs) $ R; 929 val Rpre_rel' = list_comb (pre_rel', Rs); 930 val constB = subst_atomic_types live_AsBs const; 931 932 val goal = mk_rel_fun (Rsig_or_ssig_rel' $ mk_rel_prod R RRpre_rel) (Rpre_rel' $ RRssig_rel) 933 $ const $ constB 934 |> HOLogic.mk_Trueprop; 935 in 936 Variable.add_free_names ctxt goal [] 937 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 938 mk_transfer_by_transfer_prover_tac ctxt [const_def] rel_eqs transfers)) 939 |> Thm.close_derivation \<^here> 940 end; 941 942fun derive_proto_sctr_transfer_step_or_merge ctxt Y Z R dead_pre_rel dead_sig_rel proto_sctr 943 proto_sctr_def fp_k_T_rel_eqs transfers = 944 let 945 val proto_sctrZ = substT Y Z proto_sctr; 946 val goal = mk_rel_fun (dead_pre_rel $ R) (dead_sig_rel $ R) $ proto_sctr $ proto_sctrZ 947 |> HOLogic.mk_Trueprop; 948 in 949 Variable.add_free_names ctxt goal [] 950 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 951 mk_transfer_by_transfer_prover_tac ctxt [proto_sctr_def] fp_k_T_rel_eqs transfers)) 952 |> Thm.close_derivation \<^here> 953 end; 954 955fun derive_sctr_transfer ctxt live_AsBs Y Z ssig_T Rs R pre_rel ssig_rel sctr sctr_def 956 fp_k_T_rel_eqs transfers = 957 let 958 val ssig_TB = typ_subst_atomic live_AsBs ssig_T; 959 960 val pre_rel' = Term.subst_atomic_types [(Y, ssig_T), (Z, ssig_TB)] pre_rel; 961 val Rpre_rel' = list_comb (pre_rel', Rs); 962 val RRssig_rel = list_comb (ssig_rel, Rs) $ R; 963 val sctrB = subst_atomic_types live_AsBs sctr; 964 965 val goal = HOLogic.mk_Trueprop (mk_rel_fun (Rpre_rel' $ RRssig_rel) RRssig_rel $ sctr $ sctrB); 966 in 967 Variable.add_free_names ctxt goal [] 968 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 969 mk_transfer_by_transfer_prover_tac ctxt [sctr_def] fp_k_T_rel_eqs transfers)) 970 |> Thm.close_derivation \<^here> 971 end; 972 973fun derive_corecUU_transfer ctxt live_AsBs Y Z Rs R preT ssig_T pre_rel fp_rel ssig_rel corecUU 974 cutSsig_def corecU_def corecUU_def fp_k_T_rel_eqs transfers = 975 let 976 val ssig_preT = Tsubst Y ssig_T preT; 977 val ssig_TB = typ_subst_atomic live_AsBs ssig_T; 978 val ssig_preTB = typ_subst_atomic live_AsBs ssig_preT; 979 980 val pre_rel' = Term.subst_atomic_types [(Y, ssig_T), (Z, ssig_TB)] pre_rel; 981 val ssig_rel' = Term.subst_atomic_types [(Y, ssig_preT), (Z, ssig_preTB)] ssig_rel; 982 val Rpre_rel' = list_comb (pre_rel', Rs); 983 val Rfp_rel = list_comb (fp_rel, Rs); 984 val RRssig_rel = list_comb (ssig_rel, Rs) $ R; 985 val Rssig_rel' = list_comb (ssig_rel', Rs); 986 val corecUUB = subst_atomic_types live_AsBs corecUU; 987 988 val goal = mk_rel_fun (mk_rel_fun R (Rssig_rel' $ (Rpre_rel' $ RRssig_rel))) 989 (mk_rel_fun R Rfp_rel) $ corecUU $ corecUUB 990 |> HOLogic.mk_Trueprop; 991 in 992 Variable.add_free_names ctxt goal [] 993 |> (fn vars => Goal.prove (*no sorry*) ctxt vars [] goal (fn {context = ctxt, prems = _} => 994 mk_transfer_by_transfer_prover_tac ctxt [cutSsig_def, corecU_def, corecUU_def] fp_k_T_rel_eqs 995 transfers)) 996 |> Thm.close_derivation \<^here> 997 end; 998 999fun mk_natural_goal ctxt simple_T_mapfs fs t u = 1000 let 1001 fun build_simple (T, _) = 1002 (case AList.lookup (op =) simple_T_mapfs T of 1003 SOME mapf => mapf 1004 | NONE => the (find_first (fn f => domain_type (fastype_of f) = T) fs)); 1005 1006 val simple_Ts = map fst simple_T_mapfs; 1007 1008 val t_map = build_map ctxt simple_Ts [] build_simple (apply2 (range_type o fastype_of) (t, u)); 1009 val u_map = build_map ctxt simple_Ts [] build_simple (apply2 (domain_type o fastype_of) (t, u)); 1010 in 1011 mk_Trueprop_eq (HOLogic.mk_comp (u, u_map), HOLogic.mk_comp (t_map, t)) 1012 end; 1013 1014fun derive_natural_by_unfolding ctxt live_AsBs preT pre_map fs f const map_thms = 1015 let 1016 val ffpre_map = list_comb (pre_map, fs) $ f; 1017 val constB = subst_atomic_types live_AsBs const; 1018 1019 val goal = mk_natural_goal ctxt [(preT, ffpre_map)] (fs @ [f]) const constB; 1020 in 1021 Variable.add_free_names ctxt goal [] 1022 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1023 mk_natural_by_unfolding_tac ctxt map_thms)) 1024 |> Thm.close_derivation \<^here> 1025 end; 1026 1027fun derive_natural_from_transfer ctxt live_AsBs simple_T_mapfs fs f const transfer bnfs subst_bnfs = 1028 let 1029 val m = length live_AsBs; 1030 1031 val constB = Term.subst_atomic_types live_AsBs const; 1032 val goal = mk_natural_goal ctxt simple_T_mapfs (fs @ [f]) const constB; 1033 in 1034 Variable.add_free_names ctxt goal [] 1035 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1036 mk_natural_from_transfer_tac ctxt m (replicate m true) transfer [] (map rel_Grp_of_bnf bnfs) 1037 (map rel_Grp_of_bnf subst_bnfs))) 1038 |> Thm.close_derivation \<^here> 1039 end; 1040 1041fun derive_natural_from_transfer_with_pre_type ctxt live_AsBs Y Z preT ssig_T pre_map ssig_map fs 1042 f = 1043 let 1044 val ssig_TB = typ_subst_atomic live_AsBs ssig_T; 1045 val preT' = Term.typ_subst_atomic [(Y, ssig_T), (Z, ssig_TB)] preT; 1046 1047 val ffpre_map = list_comb (pre_map, fs) $ f; 1048 val pre_map' = Term.subst_atomic_types [(Y, ssig_T), (Z, ssig_TB)] pre_map; 1049 val fpre_map' = list_comb (pre_map', fs); 1050 val ffssig_map = list_comb (ssig_map, fs) $ f; 1051 1052 val preT_mapfs = [(preT, ffpre_map), (preT', fpre_map' $ ffssig_map)]; 1053 in 1054 derive_natural_from_transfer ctxt live_AsBs preT_mapfs fs f 1055 end; 1056 1057fun derive_Lam_Inl_Inr ctxt Y Z preT old_sig_T old_ssig_T k_T ssig_T dead_pre_map Sig embL old_Lam 1058 Lam rho unsig_thm Lam_def = 1059 let 1060 val YpreT = HOLogic.mk_prodT (Y, preT); 1061 val Ypre_old_sig_T = Tsubst Y YpreT old_sig_T; 1062 val Ypre_k_T = Tsubst Y YpreT k_T; 1063 1064 val inl' = Inl_const Ypre_old_sig_T Ypre_k_T; 1065 val inr' = Inr_const Ypre_old_sig_T Ypre_k_T; 1066 val dead_pre_map' = Term.subst_atomic_types [(Y, old_ssig_T), (Z, ssig_T)] dead_pre_map; 1067 val Sig' = substT Y YpreT Sig; 1068 val Lam_o_Sig = HOLogic.mk_comp (Lam, Sig'); 1069 1070 val inl_goal = mk_Trueprop_eq (HOLogic.mk_comp (Lam_o_Sig, inl'), 1071 HOLogic.mk_comp (dead_pre_map' $ embL, old_Lam)); 1072 val inr_goal = mk_Trueprop_eq (HOLogic.mk_comp (Lam_o_Sig, inr'), rho); 1073 val goals = [inl_goal, inr_goal]; 1074 val goal = Logic.mk_conjunction_balanced goals; 1075 in 1076 Variable.add_free_names ctxt goal [] 1077 |> (fn vars => Goal.prove_sorry ctxt vars [] goal 1078 (fn {context = ctxt, prems = _} => mk_Lam_Inl_Inr_tac ctxt unsig_thm Lam_def)) 1079 |> Conjunction.elim_balanced (length goals) 1080 |> map (Thm.close_derivation \<^here>) 1081 end; 1082 1083fun derive_flat_VLeaf ctxt Y Z ssig_T x VLeaf dead_ssig_map flat ssig_induct fp_map_id sig_map_cong 1084 sig_map_ident sig_map_comp ssig_map_thms flat_simps = 1085 let 1086 val x' = substT Y ssig_T x; 1087 val dead_ssig_map' = substT Z ssig_T dead_ssig_map; 1088 1089 val goal = mk_Trueprop_eq (flat $ (dead_ssig_map' $ VLeaf $ x'), x'); 1090 1091 val ssig_induct' = infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt x')] ssig_induct; 1092 in 1093 Variable.add_free_names ctxt goal [] 1094 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1095 mk_flat_VLeaf_or_flat_tac ctxt ssig_induct' sig_map_cong 1096 (fp_map_id :: sig_map_ident :: sig_map_comp :: ssig_map_thms @ flat_simps @ 1097 @{thms o_apply id_apply id_def[symmetric]}))) 1098 |> Thm.close_derivation \<^here> 1099 end; 1100 1101fun derive_flat_flat ctxt Y Z ssig_T x dead_ssig_map flat ssig_induct fp_map_id sig_map_cong 1102 sig_map_comp ssig_map_thms flat_simps = 1103 let 1104 val ssig_ssig_T = Tsubst Y ssig_T ssig_T; 1105 val ssig_ssig_ssig_T = Tsubst Y ssig_T ssig_ssig_T; 1106 1107 val x' = substT Y ssig_ssig_ssig_T x; 1108 val dead_ssig_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_ssig_map; 1109 val flat' = substT Y ssig_T flat; 1110 1111 val goal = mk_Trueprop_eq (flat $ (dead_ssig_map' $ flat $ x'), flat $ (flat' $ x')); 1112 1113 val ssig_induct' = infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt x')] ssig_induct; 1114 in 1115 Variable.add_free_names ctxt goal [] 1116 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1117 mk_flat_VLeaf_or_flat_tac ctxt ssig_induct' sig_map_cong 1118 (o_apply :: fp_map_id :: sig_map_comp :: ssig_map_thms @ flat_simps))) 1119 |> Thm.close_derivation \<^here> 1120 end; 1121 1122fun derive_eval_core_flat ctxt Y Z preT ssig_T dead_pre_map dead_ssig_map flat eval_core x 1123 ssig_induct dead_pre_map_id dead_pre_map_comp0 dead_pre_map_comp fp_map_id sig_map_comp 1124 sig_map_cong ssig_map_thms ssig_map_comp flat_simps flat_pointful_natural flat_flat 1125 Lam_pointful_natural eval_core_simps = 1126 let 1127 val YpreT = HOLogic.mk_prodT (Y, preT); 1128 val ssig_ssig_T = Tsubst Y ssig_T ssig_T; 1129 val Ypre_ssig_T = Tsubst Y YpreT ssig_T; 1130 val Ypre_ssig_ssig_T = Tsubst Y YpreT ssig_ssig_T; 1131 val ssig_YpreT = Tsubst Y ssig_T YpreT; 1132 1133 val dead_pre_map' = Term.subst_atomic_types [(Y, ssig_ssig_T), (Z, ssig_T)] dead_pre_map; 1134 val dead_ssig_map' = Term.subst_atomic_types [(Y, Ypre_ssig_T), (Z, ssig_YpreT)] dead_ssig_map; 1135 val dead_ssig_map'' = Term.subst_atomic_types [(Y, YpreT), (Z, Y)] dead_ssig_map; 1136 val flat' = substT Y YpreT flat; 1137 val eval_core' = substT Y ssig_T eval_core; 1138 val x' = substT Y Ypre_ssig_ssig_T x; 1139 val fst' = fst_const YpreT; 1140 1141 val goal = mk_Trueprop_eq (eval_core $ (flat' $ x'), dead_pre_map' $ flat 1142 $ (eval_core' $ (dead_ssig_map' $ mk_convol (dead_ssig_map'' $ fst', eval_core) $ x'))); 1143 1144 val ssig_induct' = infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt x')] ssig_induct; 1145 in 1146 Variable.add_free_names ctxt goal [] 1147 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1148 mk_eval_core_flat_tac ctxt ssig_induct' dead_pre_map_id dead_pre_map_comp0 dead_pre_map_comp 1149 fp_map_id sig_map_comp sig_map_cong ssig_map_thms ssig_map_comp flat_simps 1150 flat_pointful_natural flat_flat Lam_pointful_natural eval_core_simps)) 1151 |> Thm.close_derivation \<^here> 1152 end; 1153 1154fun derive_eval_thm ctxt dtor_inject dtor_unfold_thm eval_def = 1155 (trans OF [iffD2 OF [dtor_inject, HOLogic.mk_obj_eq eval_def RS fun_cong], dtor_unfold_thm]) 1156 |> unfold_thms ctxt [o_apply, eval_def RS symmetric_thm]; 1157 1158fun derive_eval_flat ctxt Y Z fpT ssig_T dead_ssig_map flat eval x dead_pre_map_comp0 1159 dtor_unfold_unique ssig_map_id ssig_map_comp flat_pointful_natural eval_core_pointful_natural 1160 eval_core_flat eval_thm = 1161 let 1162 val fp_ssig_T = Tsubst Y fpT ssig_T; 1163 val fp_ssig_ssig_T = Tsubst Y fp_ssig_T ssig_T; 1164 1165 val dead_ssig_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_ssig_map; 1166 val flat' = substT Y fpT flat; 1167 val x' = substT Y fp_ssig_ssig_T x; 1168 1169 val goal = mk_Trueprop_eq (eval $ (flat' $ x'), eval $ (dead_ssig_map' $ eval $ x')); 1170 1171 val cond_eval_o_flat = 1172 infer_instantiate' ctxt [SOME (Thm.cterm_of ctxt (HOLogic.mk_comp (eval, flat')))] 1173 (trans OF [dtor_unfold_unique, dtor_unfold_unique RS sym] RS fun_cong) 1174 OF [ext, ext]; 1175 in 1176 Variable.add_free_names ctxt goal [] 1177 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1178 mk_eval_flat_tac ctxt dead_pre_map_comp0 ssig_map_id ssig_map_comp flat_pointful_natural 1179 eval_core_pointful_natural eval_core_flat eval_thm cond_eval_o_flat)) 1180 |> Thm.close_derivation \<^here> 1181 end; 1182 1183fun derive_eval_Oper ctxt live Y Z fpT sig_T ssig_T dead_sig_map Oper eval algLam x sig_map_ident 1184 sig_map_comp0 sig_map_comp Oper_natural_pointful VLeaf_natural flat_simps eval_flat algLam_def = 1185 let 1186 val fp_ssig_T = Tsubst Y fpT ssig_T; 1187 val fp_ssig_sig_T = Tsubst Y fp_ssig_T sig_T; 1188 1189 val dead_sig_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_sig_map; 1190 val Oper' = substT Y fpT Oper; 1191 val x' = substT Y fp_ssig_sig_T x; 1192 1193 val goal = mk_Trueprop_eq (eval $ (Oper' $ x'), algLam $ (dead_sig_map' $ eval $ x')); 1194 in 1195 Variable.add_free_names ctxt goal [] 1196 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1197 mk_eval_Oper_tac ctxt live sig_map_ident sig_map_comp0 sig_map_comp Oper_natural_pointful 1198 VLeaf_natural flat_simps eval_flat algLam_def)) 1199 |> Thm.close_derivation \<^here> 1200 end; 1201 1202fun derive_eval_V_or_CLeaf ctxt Y fpT V_or_CLeaf eval x dead_pre_map_id dead_pre_map_comp fp_map_id 1203 dtor_unfold_unique V_or_CLeaf_map_thm eval_core_simps eval_thm = 1204 let 1205 val V_or_CLeaf' = substT Y fpT V_or_CLeaf; 1206 val x' = substT Y fpT x; 1207 1208 val goal = mk_Trueprop_eq (eval $ (V_or_CLeaf' $ x'), x'); 1209 in 1210 Variable.add_free_names ctxt goal [] 1211 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1212 mk_eval_V_or_CLeaf_tac ctxt dead_pre_map_id dead_pre_map_comp fp_map_id dtor_unfold_unique 1213 V_or_CLeaf_map_thm eval_core_simps eval_thm)) 1214 |> Thm.close_derivation \<^here> 1215 end; 1216 1217fun derive_extdd_mor ctxt Y Z preT fpT ssig_T dead_pre_map dtor extdd cutSsig f g dead_pre_map_comp0 1218 dead_pre_map_comp VLeaf_map_thm ssig_map_comp flat_pointful_natural eval_core_pointful_natural 1219 eval_thm eval_flat eval_VLeaf cutSsig_def = 1220 let 1221 val ssig_preT = Tsubst Y ssig_T preT; 1222 1223 val dead_pre_map' = Term.subst_atomic_types [(Y, ssig_T), (Z, fpT)] dead_pre_map; 1224 val f' = substT Z fpT f; 1225 val g' = substT Z ssig_preT g; 1226 val extdd_f = extdd $ f'; 1227 1228 val prem = mk_Trueprop_eq (HOLogic.mk_comp (dead_pre_map' $ extdd_f, g'), 1229 HOLogic.mk_comp (dtor, f')); 1230 val goal = mk_Trueprop_eq (HOLogic.mk_comp (dead_pre_map' $ extdd_f, cutSsig $ g'), 1231 HOLogic.mk_comp (dtor, extdd_f)); 1232 in 1233 fold (Variable.add_free_names ctxt) [prem, goal] [] 1234 |> (fn vars => Goal.prove_sorry ctxt vars [prem] goal (fn {context = ctxt, prems = [prem]} => 1235 mk_extdd_mor_tac ctxt dead_pre_map_comp0 dead_pre_map_comp VLeaf_map_thm ssig_map_comp 1236 flat_pointful_natural eval_core_pointful_natural eval_thm eval_flat eval_VLeaf cutSsig_def 1237 prem)) 1238 |> Thm.close_derivation \<^here> 1239 end; 1240 1241fun derive_mor_cutSsig_flat ctxt Y Z preT fpT ssig_T dead_pre_map dead_ssig_map dtor flat eval_core 1242 eval cutSsig f g dead_pre_map_comp0 dead_pre_map_comp dead_pre_map_cong dtor_unfold_unique 1243 dead_ssig_map_comp0 ssig_map_comp flat_simps flat_pointful_natural eval_core_pointful_natural 1244 flat_flat flat_VLeaf eval_core_flat cutSsig_def cutSsig_def_pointful_natural eval_thm = 1245 let 1246 val ssig_preT = Tsubst Y ssig_T preT; 1247 1248 val substYZ = Term.subst_atomic_types [(Y, ssig_T), (Z, fpT)]; 1249 1250 val dead_pre_map' = substYZ dead_pre_map; 1251 val dead_ssig_map' = substYZ dead_ssig_map; 1252 val f' = substYZ f; 1253 val g' = substT Z ssig_preT g; 1254 val cutSsig_g = cutSsig $ g'; 1255 1256 val id' = HOLogic.id_const ssig_T; 1257 val convol' = mk_convol (id', cutSsig_g); 1258 val dead_ssig_map'' = 1259 Term.subst_atomic_types [(Y, ssig_T), (Z, range_type (fastype_of convol'))] dead_ssig_map; 1260 val eval_core' = substT Y ssig_T eval_core; 1261 val eval_core_o_map = HOLogic.mk_comp (eval_core', dead_ssig_map'' $ convol'); 1262 1263 val prem = mk_Trueprop_eq (HOLogic.mk_comp (dead_pre_map' $ f', cutSsig_g), 1264 HOLogic.mk_comp (dtor, f')); 1265 val goal = mk_Trueprop_eq (HOLogic.mk_comp (eval, dead_ssig_map' $ f'), 1266 HOLogic.mk_comp (f', flat)); 1267 in 1268 fold (Variable.add_free_names ctxt) [prem, goal] [] 1269 |> (fn vars => Goal.prove_sorry ctxt vars [prem] goal (fn {context = ctxt, prems = [prem]} => 1270 mk_mor_cutSsig_flat_tac ctxt eval_core_o_map dead_pre_map_comp0 dead_pre_map_comp 1271 dead_pre_map_cong dtor_unfold_unique dead_ssig_map_comp0 ssig_map_comp flat_simps 1272 flat_pointful_natural eval_core_pointful_natural flat_flat flat_VLeaf eval_core_flat 1273 cutSsig_def cutSsig_def_pointful_natural eval_thm prem)) 1274 |> Thm.close_derivation \<^here> 1275 end; 1276 1277fun derive_extdd_o_VLeaf ctxt Y Z preT fpT ssig_T dead_pre_map dtor VLeaf extdd f g 1278 dead_pre_map_comp0 dead_pre_map_comp dtor_inject ssig_map_thms eval_core_simps eval_thm 1279 eval_VLeaf = 1280 let 1281 val ssig_preT = Tsubst Y ssig_T preT; 1282 1283 val substYZ = Term.subst_atomic_types [(Y, ssig_T), (Z, fpT)]; 1284 1285 val dead_pre_map' = substYZ dead_pre_map; 1286 val f' = substT Z fpT f; 1287 val g' = substT Z ssig_preT g; 1288 val extdd_f = extdd $ f'; 1289 1290 val prem = mk_Trueprop_eq (HOLogic.mk_comp (dead_pre_map' $ extdd_f, g'), 1291 HOLogic.mk_comp (dtor, f')); 1292 val goal = mk_Trueprop_eq (HOLogic.mk_comp (extdd_f, VLeaf), f'); 1293 in 1294 fold (Variable.add_free_names ctxt) [prem, goal] [] 1295 |> (fn vars => Goal.prove_sorry ctxt vars [prem] goal (fn {context = ctxt, prems = [prem]} => 1296 mk_extdd_o_VLeaf_tac ctxt dead_pre_map_comp0 dead_pre_map_comp dtor_inject ssig_map_thms 1297 eval_core_simps eval_thm eval_VLeaf prem)) 1298 |> Thm.close_derivation \<^here> 1299 end; 1300 1301fun derive_corecU_pointfree ctxt Y Z preT fpT ssig_T dead_pre_map dtor extdd corecU g 1302 dead_pre_map_comp dtor_unfold_thm ssig_map_thms dead_ssig_map_comp0 flat_simps flat_VLeaf 1303 eval_core_simps cutSsig_def mor_cutSsig_flat corecU_def = 1304 let 1305 val ssig_preT = Tsubst Y ssig_T preT; 1306 1307 val substYZ = Term.subst_atomic_types [(Y, ssig_T), (Z, fpT)]; 1308 1309 val dead_pre_map' = substYZ dead_pre_map; 1310 val g' = substT Z ssig_preT g; 1311 val corecU_g = corecU $ g'; 1312 1313 val goal = mk_Trueprop_eq (HOLogic.mk_comp (dead_pre_map' $ (extdd $ corecU_g), g'), 1314 HOLogic.mk_comp (dtor, corecU_g)); 1315 in 1316 Variable.add_free_names ctxt goal [] 1317 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1318 mk_corecU_pointfree_tac ctxt dead_pre_map_comp dtor_unfold_thm ssig_map_thms 1319 dead_ssig_map_comp0 flat_simps flat_VLeaf eval_core_simps cutSsig_def mor_cutSsig_flat 1320 corecU_def)) 1321 |> Thm.close_derivation \<^here> 1322 end; 1323 1324fun derive_corecU_ctor_unique ctxt Y Z preT fpT ssig_T dead_pre_map ctor dtor VLeaf extdd corecU f g 1325 dead_pre_map_comp ctor_dtor dtor_unfold_thm dtor_unfold_unique ssig_map_thms dead_ssig_map_comp0 1326 flat_simps flat_VLeaf eval_core_simps extdd_mor extdd_o_VLeaf cutSsig_def mor_cutSsig_flat 1327 corecU_def = 1328 let 1329 val corecU_pointfree = derive_corecU_pointfree ctxt Y Z preT fpT ssig_T dead_pre_map dtor extdd 1330 corecU g dead_pre_map_comp dtor_unfold_thm ssig_map_thms dead_ssig_map_comp0 flat_simps 1331 flat_VLeaf eval_core_simps cutSsig_def mor_cutSsig_flat corecU_def; 1332 1333 val corecU_thm = corecU_pointfree RS @{thm comp_eq_dest}; 1334 1335 val corecU_ctor = 1336 let 1337 val arg_cong' = 1338 infer_instantiate' ctxt [NONE, NONE, SOME (Thm.cterm_of ctxt ctor)] arg_cong; 1339 in 1340 unfold_thms ctxt [ctor_dtor] (corecU_thm RS arg_cong') 1341 end; 1342 1343 val corecU_unique = 1344 let 1345 val substYZ = Term.subst_atomic_types [(Y, ssig_T), (Z, fpT)]; 1346 1347 val f' = substYZ f; 1348 val abs_f_o_VLeaf = Term.lambda f' (HOLogic.mk_comp (f', VLeaf)); 1349 1350 val inject_refine' = infer_instantiate' ctxt [SOME (Thm.cterm_of ctxt abs_f_o_VLeaf), 1351 SOME (Thm.cterm_of ctxt extdd)] @{thm inject_refine}; 1352 in 1353 unfold_thms ctxt @{thms atomize_imp} 1354 (((inject_refine' OF [extdd_o_VLeaf, extdd_o_VLeaf] RS iffD1) 1355 OF [asm_rl, corecU_pointfree]) 1356 OF [asm_rl, trans OF [dtor_unfold_unique, dtor_unfold_unique RS sym] 1357 OF [extdd_mor, corecU_pointfree RS extdd_mor]]) 1358 RS @{thm obj_distinct_prems} 1359 end; 1360 in 1361 (corecU_ctor, corecU_unique) 1362 end; 1363 1364fun derive_dtor_algLam ctxt Y Z preT fpT sig_T ssig_T dead_pre_map dtor dead_sig_map Lam eval algLam 1365 x pre_map_comp dead_pre_map_id dead_pre_map_comp0 dead_pre_map_comp sig_map_comp 1366 Oper_pointful_natural ssig_map_thms dead_ssig_map_comp0 Lam_pointful_natural eval_core_simps 1367 eval_thm eval_flat eval_VLeaf algLam_def = 1368 let 1369 val fp_preT = Tsubst Y fpT preT; 1370 val fppreT = HOLogic.mk_prodT (fpT, fp_preT); 1371 val fp_sig_T = Tsubst Y fpT sig_T; 1372 val fp_ssig_T = Tsubst Y fpT ssig_T; 1373 1374 val id' = HOLogic.id_const fpT; 1375 val convol' = mk_convol (id', dtor); 1376 val dead_pre_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_pre_map; 1377 val dead_sig_map' = Term.subst_atomic_types [(Y, fpT), (Z, fppreT)] dead_sig_map; 1378 val Lam' = substT Y fpT Lam; 1379 val x' = substT Y fp_sig_T x; 1380 1381 val goal = mk_Trueprop_eq (dtor $ (algLam $ x'), 1382 dead_pre_map' $ eval $ (Lam' $ (dead_sig_map' $ convol' $ x'))); 1383 in 1384 Variable.add_free_names ctxt goal [] 1385 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1386 mk_dtor_algLam_tac ctxt pre_map_comp dead_pre_map_id dead_pre_map_comp0 dead_pre_map_comp 1387 sig_map_comp Oper_pointful_natural ssig_map_thms dead_ssig_map_comp0 Lam_pointful_natural 1388 eval_core_simps eval_thm eval_flat eval_VLeaf algLam_def)) 1389 |> Thm.close_derivation \<^here> 1390 end; 1391 1392fun derive_algLam_base ctxt Y Z preT fpT dead_pre_map ctor dtor algLam proto_sctr dead_pre_map_id 1393 dead_pre_map_comp ctor_dtor dtor_ctor dtor_unfold_unique unsig_thm Sig_pointful_natural 1394 ssig_map_thms Lam_def flat_simps eval_core_simps eval_thm algLam_def = 1395 let 1396 val fp_preT = Tsubst Y fpT preT; 1397 1398 val proto_sctr' = substT Y fpT proto_sctr; 1399 1400 val dead_pre_map' = Term.subst_atomic_types [(Y, fpT), (Z, fp_preT)] dead_pre_map; 1401 val dead_pre_map_dtor = dead_pre_map' $ dtor; 1402 1403 val goal = mk_Trueprop_eq (HOLogic.mk_comp (algLam, proto_sctr'), ctor); 1404 in 1405 Variable.add_free_names ctxt goal [] 1406 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1407 mk_algLam_base_tac ctxt dead_pre_map_dtor dead_pre_map_id dead_pre_map_comp ctor_dtor 1408 dtor_ctor dtor_unfold_unique unsig_thm Sig_pointful_natural ssig_map_thms Lam_def flat_simps 1409 eval_core_simps eval_thm algLam_def)) 1410 |> Thm.close_derivation \<^here> 1411 end; 1412 1413fun derive_flat_embL ctxt Y Z old_ssig_T ssig_T dead_old_ssig_map embL old_flat flat x 1414 old_ssig_induct fp_map_id Sig_pointful_natural old_sig_map_comp old_sig_map_cong 1415 old_ssig_map_thms old_flat_simps flat_simps embL_simps = 1416 let 1417 val old_ssig_old_ssig_T = Tsubst Y old_ssig_T old_ssig_T; 1418 1419 val dead_old_ssig_map' = 1420 Term.subst_atomic_types [(Y, old_ssig_T), (Z, ssig_T)] dead_old_ssig_map; 1421 val embL' = substT Y ssig_T embL; 1422 val x' = substT Y old_ssig_old_ssig_T x; 1423 1424 val goal = mk_Trueprop_eq (flat $ (embL' $ (dead_old_ssig_map' $ embL $ x')), 1425 embL $ (old_flat $ x')); 1426 1427 val old_ssig_induct' = 1428 infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt x')] old_ssig_induct; 1429 in 1430 Variable.add_free_names ctxt goal [] 1431 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1432 mk_flat_embL_tac ctxt old_ssig_induct' fp_map_id Sig_pointful_natural old_sig_map_comp 1433 old_sig_map_cong old_ssig_map_thms old_flat_simps flat_simps embL_simps)) 1434 |> Thm.close_derivation \<^here> 1435 end; 1436 1437fun derive_eval_core_embL ctxt Y Z preT old_ssig_T ssig_T dead_pre_map embL old_eval_core eval_core 1438 x old_ssig_induct dead_pre_map_comp0 dead_pre_map_comp Sig_pointful_natural unsig_thm 1439 old_sig_map_comp old_sig_map_cong old_Lam_pointful_natural Lam_def flat_embL embL_simps 1440 embL_pointful_natural old_eval_core_simps eval_core_simps = 1441 let 1442 val YpreT = HOLogic.mk_prodT (Y, preT); 1443 val Ypre_old_ssig_T = Tsubst Y YpreT old_ssig_T; 1444 1445 val dead_pre_map' = Term.subst_atomic_types [(Y, old_ssig_T), (Z, ssig_T)] dead_pre_map; 1446 val embL' = substT Y YpreT embL; 1447 val x' = substT Y Ypre_old_ssig_T x; 1448 1449 val goal = 1450 mk_Trueprop_eq (eval_core $ (embL' $ x'), dead_pre_map' $ embL $ (old_eval_core $ x')); 1451 1452 val old_ssig_induct' = 1453 infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt x')] old_ssig_induct; 1454 in 1455 Variable.add_free_names ctxt goal [] 1456 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1457 mk_eval_core_embL_tac ctxt old_ssig_induct' dead_pre_map_comp0 dead_pre_map_comp 1458 Sig_pointful_natural unsig_thm old_sig_map_comp old_sig_map_cong old_Lam_pointful_natural 1459 Lam_def flat_embL old_eval_core_simps eval_core_simps embL_simps embL_pointful_natural)) 1460 |> Thm.close_derivation \<^here> 1461 end; 1462 1463fun derive_eval_embL ctxt Y fpT embL old_eval eval dead_pre_map_comp0 dtor_unfold_unique 1464 embL_pointful_natural eval_core_embL old_eval_thm eval_thm = 1465 let 1466 val embL' = substT Y fpT embL; 1467 val goal = mk_Trueprop_eq (HOLogic.mk_comp (eval, embL'), old_eval); 1468 in 1469 Variable.add_free_names ctxt goal [] 1470 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1471 mk_eval_embL_tac ctxt dead_pre_map_comp0 dtor_unfold_unique embL_pointful_natural 1472 eval_core_embL old_eval_thm eval_thm)) 1473 |> Thm.close_derivation \<^here> 1474 end; 1475 1476fun derive_algLam_algLam ctxt Inx_const Y fpT Sig old_algLam algLam dead_pre_map_comp dtor_inject 1477 unsig_thm sig_map_thm Lam_def eval_embL old_dtor_algLam dtor_algLam = 1478 let 1479 val Sig' = substT Y fpT Sig; 1480 val (left_T, right_T) = dest_sumT (domain_type (fastype_of Sig')); 1481 val inx' = Inx_const left_T right_T; 1482 1483 val goal = mk_Trueprop_eq (Library.foldl1 HOLogic.mk_comp [algLam, Sig', inx'], old_algLam); 1484 in 1485 Variable.add_free_names ctxt goal [] 1486 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1487 mk_algLam_algLam_tac ctxt dead_pre_map_comp dtor_inject unsig_thm sig_map_thm Lam_def 1488 eval_embL old_dtor_algLam dtor_algLam)) 1489 |> Thm.close_derivation \<^here> 1490 end; 1491 1492fun derive_eval_core_k_as_ssig ctxt Y preT k_T rho eval_core k_as_ssig x pre_map_comp 1493 dead_pre_map_id sig_map_comp ssig_map_thms Lam_natural_pointful Lam_Inr flat_VLeaf 1494 eval_core_simps = 1495 let 1496 val YpreT = HOLogic.mk_prodT (Y, preT); 1497 val Ypre_k_T = Tsubst Y YpreT k_T; 1498 1499 val k_as_ssig' = substT Y YpreT k_as_ssig; 1500 val x' = substT Y Ypre_k_T x; 1501 1502 val goal = mk_Trueprop_eq (eval_core $ (k_as_ssig' $ x'), rho $ x'); 1503 in 1504 Variable.add_free_names ctxt goal [] 1505 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1506 mk_eval_core_k_as_ssig_tac ctxt pre_map_comp dead_pre_map_id sig_map_comp ssig_map_thms 1507 Lam_natural_pointful Lam_Inr flat_VLeaf eval_core_simps)) 1508 |> Thm.close_derivation \<^here> 1509 end; 1510 1511fun derive_algLam_algrho ctxt Y fpT Sig algLam algrho algLam_def algrho_def = 1512 let 1513 val Sig' = substT Y fpT Sig; 1514 val (left_T, right_T) = dest_sumT (domain_type (fastype_of Sig')); 1515 val inr' = Inr_const left_T right_T; 1516 1517 val goal = mk_Trueprop_eq (Library.foldl1 HOLogic.mk_comp [algLam, Sig', inr'], algrho); 1518 in 1519 Variable.add_free_names ctxt goal [] 1520 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1521 mk_algLam_algrho_tac ctxt algLam_def algrho_def)) 1522 |> Thm.close_derivation \<^here> 1523 end; 1524 1525fun derive_dtor_algrho ctxt Y Z preT fpT k_T ssig_T dead_pre_map dead_k_map dtor rho eval algrho x 1526 eval_thm k_as_ssig_natural_pointful eval_core_k_as_ssig algrho_def = 1527 let 1528 val YpreT = HOLogic.mk_prodT (Y, preT); 1529 val fppreT = Tsubst Y fpT YpreT; 1530 val fp_k_T = Tsubst Y fpT k_T; 1531 val fp_ssig_T = Tsubst Y fpT ssig_T; 1532 1533 val id' = HOLogic.id_const fpT; 1534 val convol' = mk_convol (id', dtor); 1535 val dead_pre_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_pre_map; 1536 val dead_k_map' = Term.subst_atomic_types [(Y, fpT), (Z, fppreT)] dead_k_map; 1537 val rho' = substT Y fpT rho; 1538 val x' = substT Y fp_k_T x; 1539 1540 val goal = mk_Trueprop_eq (dtor $ (algrho $ x'), 1541 dead_pre_map' $ eval $ (rho' $ (dead_k_map' $ convol' $ x'))); 1542 in 1543 Variable.add_free_names ctxt goal [] 1544 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1545 mk_dtor_algrho_tac ctxt eval_thm k_as_ssig_natural_pointful eval_core_k_as_ssig algrho_def)) 1546 |> Thm.close_derivation \<^here> 1547 end; 1548 1549fun derive_algLam_step_or_merge ctxt Y fpT ctor proto_sctr algLam proto_sctr_def old_algLam_pointful 1550 algLam_algLam = 1551 let 1552 val proto_sctr' = substT Y fpT proto_sctr; 1553 val goal = mk_Trueprop_eq (HOLogic.mk_comp (algLam, proto_sctr'), ctor); 1554 1555 val algLam_algLam_pointful = mk_pointful ctxt algLam_algLam; 1556 in 1557 Variable.add_free_names ctxt goal [] 1558 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1559 mk_algLam_step_tac ctxt proto_sctr_def old_algLam_pointful algLam_algLam_pointful)) 1560 |> Thm.close_derivation \<^here> 1561 end; 1562 1563fun derive_eval_sctr ctxt Y Z fpT ssig_T dead_pre_map ctor eval sctr proto_sctr_pointful_natural 1564 eval_Oper algLam_thm sctr_def = 1565 let 1566 val fp_ssig_T = Tsubst Y fpT ssig_T; 1567 1568 val dead_pre_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_pre_map; 1569 val sctr' = substT Y fpT sctr; 1570 1571 val goal = mk_Trueprop_eq (HOLogic.mk_comp (eval, sctr'), 1572 HOLogic.mk_comp (ctor, dead_pre_map' $ eval)); 1573 in 1574 Variable.add_free_names ctxt goal [] 1575 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1576 mk_eval_sctr_tac ctxt proto_sctr_pointful_natural eval_Oper algLam_thm sctr_def)) 1577 |> Thm.close_derivation \<^here> 1578 end; 1579 1580fun derive_corecUU_pointfree_unique ctxt Y Z preT fpT ssig_T dead_pre_map ctor dead_ssig_map eval 1581 corecUU f g dead_pre_map_comp0 dead_pre_map_comp dtor_ctor dtor_inject ssig_map_comp 1582 flat_pointful_natural eval_core_pointful_natural eval_thm eval_flat corecU_ctor corecU_unique 1583 sctr_pointful_natural eval_sctr_pointful corecUU_def = 1584 let 1585 val ssig_preT = Tsubst Y ssig_T preT; 1586 val ssig_pre_ssig_T = Tsubst Y ssig_preT ssig_T; 1587 val fp_ssig_T = Tsubst Y fpT ssig_T; 1588 1589 val dead_pre_map' = Term.subst_atomic_types [(Y, fp_ssig_T), (Z, fpT)] dead_pre_map; 1590 val dead_pre_map'' = Term.subst_atomic_types [(Y, ssig_T), (Z, fp_ssig_T)] dead_pre_map; 1591 val dead_ssig_map' = Term.subst_atomic_types [(Y, ssig_preT), (Z, fpT)] dead_ssig_map; 1592 val dead_ssig_map'' = substT Z fpT dead_ssig_map; 1593 val f' = substT Z ssig_pre_ssig_T f; 1594 val g' = substT Z fpT g; 1595 val corecUU_f = corecUU $ f'; 1596 1597 fun mk_eq fpf = 1598 mk_Trueprop_eq (fpf, Library.foldl1 HOLogic.mk_comp [eval, dead_ssig_map' $ 1599 Library.foldl1 HOLogic.mk_comp [ctor, dead_pre_map' $ eval, dead_pre_map'' 1600 $ (dead_ssig_map'' $ fpf)], 1601 f']); 1602 1603 val corecUU_pointfree = 1604 let 1605 val goal = mk_eq corecUU_f; 1606 in 1607 Variable.add_free_names ctxt goal [] 1608 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1609 mk_corecUU_pointfree_tac ctxt dead_pre_map_comp0 dead_pre_map_comp dtor_ctor dtor_inject 1610 ssig_map_comp flat_pointful_natural eval_core_pointful_natural eval_thm eval_flat 1611 corecU_ctor sctr_pointful_natural eval_sctr_pointful corecUU_def)) 1612 |> Thm.close_derivation \<^here> 1613 end; 1614 1615 val corecUU_unique = 1616 let 1617 val prem = mk_eq g'; 1618 val goal = mk_Trueprop_eq (g', corecUU_f); 1619 in 1620 fold (Variable.add_free_names ctxt) [prem, goal] [] 1621 |> (fn vars => Goal.prove_sorry ctxt vars [prem] goal 1622 (fn {context = ctxt, prems = [prem]} => 1623 mk_corecUU_unique_tac ctxt dead_pre_map_comp0 dead_pre_map_comp dtor_ctor 1624 ssig_map_comp flat_pointful_natural eval_core_pointful_natural eval_thm eval_flat 1625 corecU_unique sctr_pointful_natural eval_sctr_pointful corecUU_def prem)) 1626 |> Thm.close_derivation \<^here> 1627 end; 1628 in 1629 (corecUU_pointfree, corecUU_unique) 1630 end; 1631 1632fun define_flat_etc fp_b version live_AsBs Y Z preT fpT sig_T ssig_T Oper VLeaf CLeaf pre_rel 1633 dead_pre_map dtor dtor_unfold dead_sig_map ssig_rel dead_ssig_map Lam Rs R pre_map_transfer 1634 fp_k_T_rel_eqs sig_map_transfer ssig_map_transfer Lam_transfer dtor_transfer lthy = 1635 let 1636 val (flat_data as (flat, flat_def, _), lthy) = lthy 1637 |> define_flat fp_b version Y Z fpT sig_T ssig_T Oper VLeaf CLeaf dead_sig_map; 1638 1639 val (eval_core_data as (eval_core, eval_core_def, _), lthy) = lthy 1640 |> define_eval_core fp_b version Y Z preT fpT sig_T ssig_T dtor Oper VLeaf CLeaf dead_pre_map 1641 dead_sig_map dead_ssig_map flat Lam; 1642 1643 val ((eval_data as (eval, _), cutSsig_data as (cutSsig, _)), lthy) = lthy 1644 |> define_eval fp_b version Y Z preT fpT ssig_T dtor dtor_unfold dead_ssig_map eval_core 1645 ||>> define_cutSsig fp_b version Y Z preT ssig_T dead_pre_map VLeaf dead_ssig_map flat 1646 eval_core; 1647 1648 val ((algLam_data, unfold_data), lthy) = lthy 1649 |> define_algLam fp_b version Y Z fpT ssig_T Oper VLeaf dead_sig_map eval 1650 ||>> define_corecU fp_b version Y Z preT ssig_T dtor_unfold VLeaf cutSsig; 1651 1652 val flat_transfer = derive_transfer_by_transfer_prover lthy live_AsBs Rs R flat [flat_def] [] 1653 [sig_map_transfer]; 1654 val eval_core_transfer = derive_Lam_or_eval_core_transfer lthy live_AsBs Y Z preT ssig_T Rs R 1655 pre_rel ssig_rel ssig_rel eval_core eval_core_def fp_k_T_rel_eqs 1656 [pre_map_transfer, sig_map_transfer, ssig_map_transfer, flat_transfer, Lam_transfer, 1657 dtor_transfer]; 1658 in 1659 (((((((flat_data, flat_transfer), (eval_core_data, eval_core_transfer)), eval_data), 1660 cutSsig_data), algLam_data), unfold_data), lthy) 1661 end; 1662 1663fun derive_Sig_natural_etc ctxt live live_AsBs Y Z preT fpT k_or_fpT sig_T ssig_T pre_map 1664 dead_pre_map ctor dtor Sig dead_sig_map Oper VLeaf CLeaf ssig_map dead_ssig_map Lam flat 1665 eval_core eval cutSsig algLam corecU x fs f g ctor_dtor dtor_inject dtor_unfold_thm 1666 dtor_unfold_unique sig_map_thm ssig_induct ssig_map_thms Oper_map_thm VLeaf_map_thm 1667 CLeaf_map_thm Lam_transfer flat_simps flat_transfer eval_core_simps eval_core_transfer eval_def 1668 cutSsig_def algLam_def corecU_def live_pre_bnf pre_bnf dead_pre_bnf fp_bnf sig_bnf ssig_bnf 1669 dead_ssig_bnf = 1670 let 1671 val SOME prod_bnf = bnf_of ctxt \<^type_name>\<open>prod\<close>; 1672 1673 val f' = substT Z fpT f; 1674 val dead_ssig_map' = substT Z fpT dead_ssig_map; 1675 val extdd = Term.lambda f' (HOLogic.mk_comp (eval, dead_ssig_map' $ f')); 1676 1677 val live_pre_map_def = map_def_of_bnf live_pre_bnf; 1678 val pre_map_comp = map_comp_of_bnf pre_bnf; 1679 val dead_pre_map_id = map_id_of_bnf dead_pre_bnf; 1680 val dead_pre_map_comp0 = map_comp0_of_bnf dead_pre_bnf; 1681 val dead_pre_map_comp = map_comp_of_bnf dead_pre_bnf; 1682 val dead_pre_map_cong = map_cong_of_bnf dead_pre_bnf; 1683 val fp_map_id = map_id_of_bnf fp_bnf; 1684 val sig_map_ident = map_ident_of_bnf sig_bnf; 1685 val sig_map_comp0 = map_comp0_of_bnf sig_bnf; 1686 val sig_map_comp = map_comp_of_bnf sig_bnf; 1687 val sig_map_cong = map_cong_of_bnf sig_bnf; 1688 val ssig_map_id = map_id_of_bnf ssig_bnf; 1689 val ssig_map_comp = map_comp_of_bnf ssig_bnf; 1690 val dead_ssig_map_comp0 = map_comp0_of_bnf dead_ssig_bnf; 1691 1692 val k_preT_map_id0s = 1693 map map_id0_of_bnf (map_filter (bnf_of ctxt) (fold add_type_namesT [preT, k_or_fpT] [])); 1694 1695 val Sig_natural = derive_natural_by_unfolding ctxt live_AsBs preT pre_map fs f Sig 1696 ([sig_map_thm, live_pre_map_def, @{thm BNF_Composition.id_bnf_def}] @ k_preT_map_id0s); 1697 val Oper_natural = 1698 derive_natural_by_unfolding ctxt live_AsBs preT pre_map fs f Oper [Oper_map_thm]; 1699 val VLeaf_natural = 1700 derive_natural_by_unfolding ctxt live_AsBs preT pre_map fs f VLeaf [VLeaf_map_thm]; 1701 val Lam_natural = derive_natural_from_transfer_with_pre_type ctxt live_AsBs Y Z preT ssig_T 1702 pre_map ssig_map fs f Lam Lam_transfer [prod_bnf, pre_bnf, sig_bnf, ssig_bnf] []; 1703 val flat_natural = derive_natural_from_transfer ctxt live_AsBs [] fs f flat flat_transfer 1704 [ssig_bnf] []; 1705 val eval_core_natural = derive_natural_from_transfer_with_pre_type ctxt live_AsBs Y Z preT 1706 ssig_T pre_map ssig_map fs f eval_core eval_core_transfer [prod_bnf, pre_bnf, ssig_bnf] []; 1707 1708 val Sig_pointful_natural = mk_pointful ctxt Sig_natural RS sym; 1709 val Oper_natural_pointful = mk_pointful ctxt Oper_natural; 1710 val Oper_pointful_natural = Oper_natural_pointful RS sym; 1711 val flat_pointful_natural = mk_pointful ctxt flat_natural RS sym; 1712 val Lam_natural_pointful = mk_pointful ctxt Lam_natural; 1713 val Lam_pointful_natural = Lam_natural_pointful RS sym; 1714 val eval_core_pointful_natural = mk_pointful ctxt eval_core_natural RS sym; 1715 val cutSsig_def_pointful_natural = mk_pointful ctxt (HOLogic.mk_obj_eq cutSsig_def) RS sym; 1716 1717 val flat_VLeaf = derive_flat_VLeaf ctxt Y Z ssig_T x VLeaf dead_ssig_map flat ssig_induct 1718 fp_map_id sig_map_cong sig_map_ident sig_map_comp ssig_map_thms flat_simps; 1719 val flat_flat = derive_flat_flat ctxt Y Z ssig_T x dead_ssig_map flat ssig_induct fp_map_id 1720 sig_map_cong sig_map_comp ssig_map_thms flat_simps; 1721 1722 val eval_core_flat = derive_eval_core_flat ctxt Y Z preT ssig_T dead_pre_map dead_ssig_map flat 1723 eval_core x ssig_induct dead_pre_map_id dead_pre_map_comp0 dead_pre_map_comp fp_map_id 1724 sig_map_comp sig_map_cong ssig_map_thms ssig_map_comp flat_simps flat_pointful_natural 1725 flat_flat Lam_pointful_natural eval_core_simps; 1726 1727 val eval_thm = derive_eval_thm ctxt dtor_inject dtor_unfold_thm eval_def; 1728 val eval_flat = derive_eval_flat ctxt Y Z fpT ssig_T dead_ssig_map flat eval x 1729 dead_pre_map_comp0 dtor_unfold_unique ssig_map_id ssig_map_comp flat_pointful_natural 1730 eval_core_pointful_natural eval_core_flat eval_thm; 1731 val eval_Oper = derive_eval_Oper ctxt live Y Z fpT sig_T ssig_T dead_sig_map Oper eval algLam x 1732 sig_map_ident sig_map_comp0 sig_map_comp Oper_natural_pointful VLeaf_natural flat_simps 1733 eval_flat algLam_def; 1734 val eval_VLeaf = derive_eval_V_or_CLeaf ctxt Y fpT VLeaf eval x dead_pre_map_id 1735 dead_pre_map_comp fp_map_id dtor_unfold_unique VLeaf_map_thm eval_core_simps eval_thm; 1736 val eval_CLeaf = derive_eval_V_or_CLeaf ctxt Y fpT CLeaf eval x dead_pre_map_id 1737 dead_pre_map_comp fp_map_id dtor_unfold_unique CLeaf_map_thm eval_core_simps eval_thm; 1738 1739 val extdd_mor = derive_extdd_mor ctxt Y Z preT fpT ssig_T dead_pre_map dtor extdd cutSsig f g 1740 dead_pre_map_comp0 dead_pre_map_comp VLeaf_map_thm ssig_map_comp flat_pointful_natural 1741 eval_core_pointful_natural eval_thm eval_flat eval_VLeaf cutSsig_def; 1742 val mor_cutSsig_flat = derive_mor_cutSsig_flat ctxt Y Z preT fpT ssig_T dead_pre_map 1743 dead_ssig_map dtor flat eval_core eval cutSsig f g dead_pre_map_comp0 dead_pre_map_comp 1744 dead_pre_map_cong dtor_unfold_unique dead_ssig_map_comp0 ssig_map_comp flat_simps 1745 flat_pointful_natural eval_core_pointful_natural flat_flat flat_VLeaf eval_core_flat 1746 cutSsig_def cutSsig_def_pointful_natural eval_thm; 1747 val extdd_o_VLeaf = derive_extdd_o_VLeaf ctxt Y Z preT fpT ssig_T dead_pre_map dtor VLeaf extdd 1748 f g dead_pre_map_comp0 dead_pre_map_comp dtor_inject ssig_map_thms eval_core_simps eval_thm 1749 eval_VLeaf; 1750 1751 val (corecU_ctor, corecU_unique) = derive_corecU_ctor_unique ctxt Y Z preT fpT ssig_T 1752 dead_pre_map ctor dtor VLeaf extdd corecU f g dead_pre_map_comp ctor_dtor dtor_unfold_thm 1753 dtor_unfold_unique ssig_map_thms dead_ssig_map_comp0 flat_simps flat_VLeaf eval_core_simps 1754 extdd_mor extdd_o_VLeaf cutSsig_def mor_cutSsig_flat corecU_def; 1755 1756 val dtor_algLam = derive_dtor_algLam ctxt Y Z preT fpT sig_T ssig_T dead_pre_map dtor 1757 dead_sig_map Lam eval algLam x pre_map_comp dead_pre_map_id dead_pre_map_comp0 1758 dead_pre_map_comp sig_map_comp Oper_pointful_natural ssig_map_thms dead_ssig_map_comp0 1759 Lam_pointful_natural eval_core_simps eval_thm eval_flat eval_VLeaf algLam_def; 1760 in 1761 (Sig_pointful_natural, flat_pointful_natural, Lam_natural_pointful, Lam_pointful_natural, 1762 flat_VLeaf, eval_core_pointful_natural, eval_thm, eval_flat, 1763 [eval_Oper, eval_VLeaf, eval_CLeaf], corecU_ctor, corecU_unique, dtor_algLam) 1764 end; 1765 1766fun derive_embL_natural_etc ctxt Inx_const old_ssig_bnf ssig_bnf Y Z preT fpT old_ssig_T ssig_T 1767 dead_pre_map Sig dead_old_ssig_map embL old_algLam algLam old_flat flat old_eval_core eval_core 1768 old_eval eval x f old_ssig_induct dead_pre_map_comp0 dead_pre_map_comp fp_map_id dtor_inject 1769 dtor_unfold_unique Sig_pointful_natural unsig_thm sig_map_thm old_sig_map_comp old_sig_map_cong 1770 old_ssig_map_thms old_Lam_pointful_natural Lam_def old_flat_simps flat_simps embL_simps 1771 embL_transfer old_eval_core_simps eval_core_simps old_eval_thm eval_thm old_dtor_algLam 1772 dtor_algLam old_algLam_thm = 1773 let 1774 val embL_natural = derive_natural_from_transfer ctxt [(Y, Z)] [] [] f embL embL_transfer 1775 [old_ssig_bnf, ssig_bnf] []; 1776 1777 val embL_pointful_natural = mk_pointful ctxt embL_natural RS sym; 1778 val old_algLam_pointful = mk_pointful ctxt old_algLam_thm; 1779 1780 val flat_embL = derive_flat_embL ctxt Y Z old_ssig_T ssig_T dead_old_ssig_map embL old_flat flat 1781 x old_ssig_induct fp_map_id Sig_pointful_natural old_sig_map_comp old_sig_map_cong 1782 old_ssig_map_thms old_flat_simps flat_simps embL_simps; 1783 val eval_core_embL = derive_eval_core_embL ctxt Y Z preT old_ssig_T ssig_T dead_pre_map embL 1784 old_eval_core eval_core x old_ssig_induct dead_pre_map_comp0 dead_pre_map_comp 1785 Sig_pointful_natural unsig_thm old_sig_map_comp old_sig_map_cong old_Lam_pointful_natural 1786 Lam_def flat_embL embL_simps embL_pointful_natural old_eval_core_simps eval_core_simps; 1787 val eval_embL = derive_eval_embL ctxt Y fpT embL old_eval eval dead_pre_map_comp0 1788 dtor_unfold_unique embL_pointful_natural eval_core_embL old_eval_thm eval_thm; 1789 1790 val algLam_algLam = derive_algLam_algLam ctxt Inx_const Y fpT Sig old_algLam algLam 1791 dead_pre_map_comp dtor_inject unsig_thm sig_map_thm Lam_def eval_embL old_dtor_algLam 1792 dtor_algLam; 1793 in 1794 (embL_pointful_natural, old_algLam_pointful, eval_embL, algLam_algLam) 1795 end; 1796 1797fun define_corecUU_etc fp_b version live_AsBs Y Z preT fpT ssig_T pre_map dead_pre_map pre_rel 1798 fp_rel ctor Oper ssig_map dead_ssig_map ssig_rel proto_sctr flat eval_core eval corecU fs f g Rs 1799 R pre_map_transfer fp_k_T_rel_eqs dtor_unfold_transfer dtor_transfer ssig_map_transfer 1800 proto_sctr_transfer proto_sctr_pointful_natural flat_transfer flat_pointful_natural 1801 eval_core_transfer eval_core_pointful_natural eval_thm eval_flat eval_Oper algLam_thm 1802 cutSsig_def corecU_def corecU_ctor corecU_unique pre_bnf dead_pre_bnf fp_res ssig_fp_sugar 1803 lthy = 1804 let 1805 val ssig_bnf = #fp_bnf ssig_fp_sugar; 1806 1807 val dead_pre_map_comp0 = map_comp0_of_bnf dead_pre_bnf; 1808 val dead_pre_map_comp = map_comp_of_bnf dead_pre_bnf; 1809 val [dtor_ctor] = #dtor_ctors fp_res; 1810 val [dtor_inject] = #dtor_injects fp_res; 1811 val ssig_map_comp = map_comp_of_bnf ssig_bnf; 1812 1813 val sctr_rhs = HOLogic.mk_comp (Oper, substT Y ssig_T proto_sctr); 1814 val ((sctr, sctr_def), lthy) = lthy 1815 |> define_const true fp_b version sctrN sctr_rhs; 1816 1817 val (corecUU_data as (corecUU, corecUU_def), lthy) = lthy 1818 |> define_corecUU fp_b version Y Z preT ssig_T dead_pre_map dead_ssig_map flat eval_core sctr 1819 corecU; 1820 1821 val eval_sctr = derive_eval_sctr lthy Y Z fpT ssig_T dead_pre_map ctor eval sctr 1822 proto_sctr_pointful_natural eval_Oper algLam_thm sctr_def; 1823 1824 val sctr_transfer = derive_sctr_transfer lthy live_AsBs Y Z ssig_T Rs R pre_rel ssig_rel sctr 1825 sctr_def fp_k_T_rel_eqs [proto_sctr_transfer]; 1826 1827 val sctr_natural = derive_natural_from_transfer_with_pre_type lthy live_AsBs Y Z preT ssig_T 1828 pre_map ssig_map fs f sctr sctr_transfer [pre_bnf, ssig_bnf] []; 1829 1830 val sctr_pointful_natural = mk_pointful lthy sctr_natural RS sym; 1831 val eval_sctr_pointful = mk_pointful lthy eval_sctr RS sym; 1832 1833 val (corecUU_pointfree, corecUU_unique) = derive_corecUU_pointfree_unique lthy Y Z preT fpT 1834 ssig_T dead_pre_map ctor dead_ssig_map eval corecUU f g dead_pre_map_comp0 dead_pre_map_comp 1835 dtor_ctor dtor_inject ssig_map_comp flat_pointful_natural eval_core_pointful_natural eval_thm 1836 eval_flat corecU_ctor corecU_unique sctr_pointful_natural eval_sctr_pointful corecUU_def; 1837 1838 val corecUU_thm = mk_pointful lthy corecUU_pointfree; 1839 1840 val corecUU_transfer = derive_corecUU_transfer lthy live_AsBs Y Z Rs R preT ssig_T pre_rel 1841 fp_rel ssig_rel corecUU cutSsig_def corecU_def corecUU_def fp_k_T_rel_eqs 1842 [pre_map_transfer, dtor_unfold_transfer, dtor_transfer, ssig_map_transfer, flat_transfer, 1843 eval_core_transfer, sctr_transfer, @{thm convol_transfer} (*FIXME: needed?*)]; 1844 in 1845 ((corecUU_data, corecUU_thm, corecUU_unique, corecUU_transfer, eval_sctr, sctr_transfer, 1846 sctr_pointful_natural), lthy) 1847 end; 1848 1849fun mk_equivp T = Const (\<^const_name>\<open>equivp\<close>, mk_predT [mk_pred2T T T]); 1850 1851fun derive_equivp_Retr ctxt fpT Retr R dead_pre_rel_refl_thm dead_pre_rel_flip_thm 1852 dead_pre_rel_mono_thm dead_pre_rel_compp_thm = 1853 let 1854 val prem = HOLogic.mk_Trueprop (mk_equivp fpT $ R); 1855 val goal = Logic.mk_implies (prem, HOLogic.mk_Trueprop (mk_equivp fpT $ (betapply (Retr, R)))); 1856 in 1857 Variable.add_free_names ctxt goal [] 1858 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => 1859 mk_equivp_Retr_tac ctxt dead_pre_rel_refl_thm dead_pre_rel_flip_thm dead_pre_rel_mono_thm 1860 dead_pre_rel_compp_thm)) 1861 |> Thm.close_derivation \<^here> 1862 end; 1863 1864fun derive_Retr_coinduct ctxt fpT Retr R dtor_rel_coinduct_thm rel_eq_thm = 1865 let 1866 val goal = HOLogic.mk_Trueprop (list_all_free [R] 1867 (HOLogic.mk_imp (mk_leq R (Retr $ R), mk_leq R (HOLogic.eq_const fpT)))); 1868 in 1869 Goal.prove_sorry ctxt [] [] goal (fn {context = ctxt, prems = _} => 1870 mk_Retr_coinduct_tac ctxt dtor_rel_coinduct_thm rel_eq_thm) 1871 |> Thm.close_derivation \<^here> 1872 end; 1873 1874fun derive_Retr fp_sugar fpT dead_pre_bnf ctor dtor names_lthy lthy = 1875 let 1876 val (R, _) = names_lthy 1877 |> yield_singleton (mk_Frees "R") (mk_pred2T fpT fpT); 1878 val pre_fpT = pre_type_of_ctor fpT ctor; 1879 val fp_pre_rel = mk_rel1 lthy fpT fpT pre_fpT dead_pre_bnf; 1880 val Retr = Abs ("R", fastype_of R, Abs ("a", fpT, 1881 Abs ("b", fpT, list_comb (fp_pre_rel, [Bound 2, dtor $ Bound 1, dtor $ Bound 0])))); 1882 val equivp_Retr = derive_equivp_Retr lthy fpT Retr R (rel_refl_of_bnf dead_pre_bnf) 1883 (rel_flip_of_bnf dead_pre_bnf) (rel_mono_of_bnf dead_pre_bnf) (rel_OO_of_bnf dead_pre_bnf); 1884 1885 val Retr_coinduct = derive_Retr_coinduct lthy fpT Retr R 1886 (fp_sugar |> #fp_res |> #xtor_rel_co_induct) (fp_sugar |> #fp_bnf |> rel_eq_of_bnf); 1887 in 1888 (Retr, equivp_Retr, Retr_coinduct) 1889 end; 1890 1891fun mk_gen_cong fpT eval_domT = 1892 let val fp_relT = mk_pred2T fpT fpT in 1893 Const (\<^const_name>\<open>cong.gen_cong\<close>, 1894 [mk_predT [fp_relT, eval_domT, eval_domT], eval_domT --> fpT, fp_relT] ---> fp_relT) 1895 end; 1896 1897fun mk_cong_locale rel eval Retr = 1898 Const (\<^const_name>\<open>cong\<close>, mk_predT (map fastype_of [rel, eval, Retr])); 1899 1900fun derive_cong_locale ctxt rel eval Retr0 tac = 1901 let 1902 val Retr = enforce_type ctxt domain_type (domain_type (fastype_of rel)) Retr0; 1903 val goal = HOLogic.mk_Trueprop (list_comb (mk_cong_locale rel eval Retr, [rel, eval, Retr])); 1904 in 1905 Variable.add_free_names ctxt goal [] 1906 |> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} => tac ctxt)) 1907 |> Thm.close_derivation \<^here> 1908 end; 1909 1910fun derive_cong_general fp_b version fpT dead_ssig_bnf dead_pre_bnf eval Retr equivp_Retr 1911 Retr_coinduct eval_thm eval_core_transfer lthy = 1912 let 1913 val eval_domT = domain_type (fastype_of eval); 1914 1915 fun cong_locale_tac ctxt = 1916 mk_cong_locale_tac ctxt (rel_mono_of_bnf dead_pre_bnf) (rel_map_of_bnf dead_pre_bnf) 1917 equivp_Retr (rel_mono_of_bnf dead_ssig_bnf) (rel_map_of_bnf dead_ssig_bnf) eval_thm 1918 eval_core_transfer; 1919 1920 val rel = mk_rel1 lthy fpT fpT eval_domT dead_ssig_bnf; 1921 val cong_rhs = list_comb (mk_gen_cong fpT eval_domT, [rel, eval]); 1922 val ((_, cong_def), lthy) = lthy 1923 |> define_const false fp_b version congN cong_rhs; 1924 1925 val cong_locale = derive_cong_locale lthy rel eval Retr cong_locale_tac; 1926 1927 val fold_cong_def = Local_Defs.fold lthy [cong_def]; 1928 1929 fun instance_of_gen thm = fold_cong_def (thm OF [cong_locale]); 1930 1931 val cong_base = instance_of_gen @{thm cong.imp_gen_cong}; 1932 val cong_refl = instance_of_gen @{thm cong.gen_cong_reflp}; 1933 val cong_sym = instance_of_gen @{thm cong.gen_cong_symp}; 1934 val cong_trans = instance_of_gen @{thm cong.gen_cong_transp}; 1935 1936 fun mk_cong_rho thm = thm RS instance_of_gen @{thm cong.gen_cong_rho}; 1937 1938 val dtor_coinduct = @{thm predicate2I_obj} RS 1939 (Retr_coinduct RS instance_of_gen @{thm cong.coinduction} RS @{thm predicate2D_obj}); 1940 in 1941 (cong_def, cong_locale, cong_base, cong_refl, cong_sym, cong_trans, dtor_coinduct, mk_cong_rho, 1942 lthy) 1943 end; 1944 1945fun derive_cong_base fp_b version fpT dead_ssig_bnf ssig_fp_bnf_sugar dead_pre_bnf eval eval_thm 1946 eval_core_transfer eval_VLeaf eval_sctr sctr_transfer Retr equivp_Retr Retr_coinduct lthy = 1947 let 1948 val (cong_def, cong_locale, cong_base, cong_refl, cong_sym, cong_trans, dtor_coinduct, 1949 mk_cong_rho, lthy) = 1950 derive_cong_general fp_b version fpT dead_ssig_bnf dead_pre_bnf eval Retr equivp_Retr 1951 Retr_coinduct eval_thm eval_core_transfer lthy; 1952 1953 val dead_pre_map_id0 = map_id0_of_bnf dead_pre_bnf; 1954 val dead_pre_map_comp0 = map_comp0_of_bnf dead_pre_bnf; 1955 val dead_pre_map_cong0 = map_cong0_of_bnf dead_pre_bnf; 1956 val dead_pre_map_cong0' = 1957 @{thm box_equals[OF _ o_apply[symmetric] id_apply[symmetric]]} RS dead_pre_map_cong0 RS ext; 1958 val dead_pre_rel_map = rel_map_of_bnf dead_pre_bnf; 1959 1960 val ctor_alt_thm = eval_VLeaf RS (@{thm eq_comp_compI} OF [eval_sctr, 1961 trans OF [dead_pre_map_comp0 RS sym, trans OF [dead_pre_map_cong0', dead_pre_map_id0]]]); 1962 1963 val cong_ctor_intro = mk_cong_rho ctor_alt_thm 1964 |> unfold_thms lthy [o_apply] 1965 |> (fn thm => sctr_transfer RS rel_funD RS thm) 1966 |> unfold_thms lthy (id_apply :: dead_pre_rel_map @ #rel_injects ssig_fp_bnf_sugar); 1967 in 1968 ({cong_def = cong_def, cong_locale = cong_locale, cong_base = cong_base, cong_refl = cong_refl, 1969 cong_sym = cong_sym, cong_trans = cong_trans, dtor_coinduct = dtor_coinduct, 1970 cong_alg_intros = [cong_ctor_intro]}, lthy) 1971 end; 1972 1973fun update_cong_alg_intros ctxt cong_def cong_locale old_cong_def old_cong_locale emb = 1974 let 1975 fun instance_of_gen thm = Local_Defs.fold ctxt [cong_def] (thm OF [cong_locale]); 1976 fun instance_of_old_gen thm = Local_Defs.fold ctxt [old_cong_def] (thm OF [old_cong_locale]); 1977 1978 val emb_idem = @{thm ord_le_eq_trans} OF [emb, instance_of_gen @{thm cong.gen_cong_idem}]; 1979 fun mk_rel_mono bnf = instance_of_old_gen @{thm cong.leq_gen_cong} RS rel_mono_of_bnf bnf RS 1980 @{thm predicate2D}; 1981 fun mk_intro bnf thm = mk_rel_mono bnf RS (@{thm predicate2D} OF [emb_idem, thm]); 1982 in 1983 map2 mk_intro 1984 end 1985 1986fun derive_cong_step fp_b version fpT dead_ssig_bnf dead_pre_bnf eval eval_thm eval_core_transfer 1987 old_dtor_coinduct_info algrho_def k_as_ssig_transfer Retr equivp_Retr Retr_coinduct 1988 eval_embL embL_transfer old_all_dead_k_bnfs lthy = 1989 let 1990 val old_cong_def = #cong_def old_dtor_coinduct_info; 1991 val old_cong_locale = #cong_locale old_dtor_coinduct_info; 1992 val old_cong_alg_intros = #cong_alg_intros old_dtor_coinduct_info; 1993 1994 val (cong_def, cong_locale, cong_base, cong_refl, cong_sym, cong_trans, dtor_coinduct, 1995 mk_cong_rho, lthy) = 1996 derive_cong_general fp_b version fpT dead_ssig_bnf dead_pre_bnf eval Retr equivp_Retr 1997 Retr_coinduct eval_thm eval_core_transfer lthy; 1998 1999 val cong_alg_intro = 2000 k_as_ssig_transfer RS rel_funD RS mk_cong_rho (HOLogic.mk_obj_eq algrho_def); 2001 2002 val gen_cong_emb = 2003 (@{thm gen_cong_emb} OF [old_cong_locale, cong_locale, eval_embL, embL_transfer]) 2004 |> Local_Defs.fold lthy [old_cong_def, cong_def]; 2005 2006 val cong_alg_intros = update_cong_alg_intros lthy cong_def cong_locale old_cong_def 2007 old_cong_locale gen_cong_emb old_all_dead_k_bnfs old_cong_alg_intros; 2008 in 2009 ({cong_def = cong_def, cong_locale = cong_locale, cong_base = cong_base, cong_refl = cong_refl, 2010 cong_sym = cong_sym, cong_trans = cong_trans, dtor_coinduct = dtor_coinduct, 2011 cong_alg_intros = cong_alg_intro :: cong_alg_intros}, lthy) 2012 end; 2013 2014fun derive_cong_merge fp_b version fpT old1_friend_names old2_friend_names dead_ssig_bnf 2015 dead_pre_bnf eval eval_thm eval_core_transfer old1_dtor_coinduct_info old2_dtor_coinduct_info 2016 Retr equivp_Retr Retr_coinduct eval_embLL embLL_transfer eval_embLR embLR_transfer 2017 old1_all_dead_k_bnfs old2_all_dead_k_bnfs lthy = 2018 let 2019 val old1_cong_def = #cong_def old1_dtor_coinduct_info; 2020 val old1_cong_locale = #cong_locale old1_dtor_coinduct_info; 2021 val old1_cong_alg_intros = #cong_alg_intros old1_dtor_coinduct_info; 2022 val old2_cong_def = #cong_def old2_dtor_coinduct_info; 2023 val old2_cong_locale = #cong_locale old2_dtor_coinduct_info; 2024 val old2_cong_alg_intros = #cong_alg_intros old2_dtor_coinduct_info; 2025 2026 val (cong_def, cong_locale, cong_base, cong_refl, cong_sym, cong_trans, dtor_coinduct, _, 2027 lthy) = 2028 derive_cong_general fp_b version fpT dead_ssig_bnf dead_pre_bnf eval Retr equivp_Retr 2029 Retr_coinduct eval_thm eval_core_transfer lthy; 2030 2031 val emb1 = (@{thm gen_cong_emb} OF [old1_cong_locale, cong_locale, eval_embLL, embLL_transfer]) 2032 |> Local_Defs.fold lthy [old1_cong_def, cong_def]; 2033 val emb2 = (@{thm gen_cong_emb} OF [old2_cong_locale, cong_locale, eval_embLR, embLR_transfer]) 2034 |> Local_Defs.fold lthy [old2_cong_def, cong_def]; 2035 2036 val cong_alg_intros1 = update_cong_alg_intros lthy cong_def cong_locale old1_cong_def 2037 old1_cong_locale emb1 old1_all_dead_k_bnfs old1_cong_alg_intros; 2038 val cong_alg_intros2 = update_cong_alg_intros lthy cong_def cong_locale old2_cong_def 2039 old2_cong_locale emb2 old2_all_dead_k_bnfs old2_cong_alg_intros; 2040 2041 val (cong_algrho_intros1, cong_ctor_intro1) = split_last cong_alg_intros1; 2042 val (cong_algrho_intros2, _) = split_last cong_alg_intros2; 2043 val (old1_all_rho_k_bnfs, old1_Sig_bnf) = split_last old1_all_dead_k_bnfs; 2044 val (old2_all_rho_k_bnfs, _) = split_last old2_all_dead_k_bnfs; 2045 2046 val (friend_names, (cong_algrho_intros, all_rho_k_bnfs)) = 2047 merge_lists (op = o apply2 fst) 2048 (old1_friend_names ~~ (cong_algrho_intros1 ~~ old1_all_rho_k_bnfs)) 2049 (old2_friend_names ~~ (cong_algrho_intros2 ~~ old2_all_rho_k_bnfs)) 2050 |> split_list ||> split_list; 2051 in 2052 (({cong_def = cong_def, cong_locale = cong_locale, cong_base = cong_base, cong_refl = cong_refl, 2053 cong_sym = cong_sym, cong_trans = cong_trans, dtor_coinduct = dtor_coinduct, 2054 cong_alg_intros = cong_algrho_intros @ [cong_ctor_intro1]}, all_rho_k_bnfs @ [old1_Sig_bnf], 2055 friend_names), lthy) 2056 end; 2057 2058fun derive_corecUU_base fpT_name lthy = 2059 let 2060 val fp_sugar as {T = Type (_, fpT_args0), pre_bnf, fp_bnf, fp_res, ...} = 2061 checked_fp_sugar_of lthy fpT_name; 2062 val fpT_Ss = map Type.sort_of_atyp fpT_args0; 2063 val fp_alives = liveness_of_fp_bnf (length fpT_args0) fp_bnf; 2064 2065 val (((Es, Fs0), [Y, Z]), names_lthy) = lthy 2066 |> mk_TFrees' fpT_Ss 2067 ||>> mk_TFrees' fpT_Ss 2068 ||>> mk_TFrees 2; 2069 val Fs = @{map 3} (fn alive => fn E => fn F => if alive then F else E) fp_alives Es Fs0; 2070 2071 val As = Es @ [Y]; 2072 val Bs = Es @ [Z]; 2073 2074 val live_EsFs = filter (op <>) (Es ~~ Fs); 2075 val live_AsBs = live_EsFs @ [(Y, Z)]; 2076 val fTs = map (op -->) live_EsFs; 2077 val RTs = map (uncurry mk_pred2T) live_EsFs; 2078 val live = length live_EsFs; 2079 2080 val ((((((x, fs), f), g), Rs), R), names_lthy) = names_lthy 2081 |> yield_singleton (mk_Frees "x") Y 2082 ||>> mk_Frees "f" fTs 2083 ||>> yield_singleton (mk_Frees "f") (Y --> Z) 2084 ||>> yield_singleton (mk_Frees "g") (Y --> Z) 2085 ||>> mk_Frees "R" RTs 2086 ||>> yield_singleton (mk_Frees "R") (mk_pred2T Y Z); 2087 2088 val ctor = mk_ctor Es (the_single (#ctors fp_res)); 2089 val dtor = mk_dtor Es (the_single (#dtors fp_res)); 2090 2091 val fpT = Type (fpT_name, Es); 2092 val preT = pre_type_of_ctor Y ctor; 2093 2094 val ((fp_b, version), lthy) = lthy |> get_name_next_version_of fpT_name; 2095 2096 val ((sig_fp_sugar, ssig_fp_sugar), lthy) = lthy 2097 |> define_sig_type fp_b version fp_alives Es Y preT 2098 ||>> define_ssig_type fp_b version fp_alives Es Y fpT; 2099 2100 val sig_bnf = #fp_bnf sig_fp_sugar; 2101 val ssig_bnf = #fp_bnf ssig_fp_sugar; 2102 2103 val (((dead_pre_bnf, dead_sig_bnf), dead_ssig_bnf), lthy) = lthy 2104 |> bnf_kill_all_but 1 pre_bnf 2105 ||>> bnf_kill_all_but 1 sig_bnf 2106 ||>> bnf_kill_all_but 1 ssig_bnf; 2107 2108 val sig_fp_ctr_sugar = #fp_ctr_sugar sig_fp_sugar; 2109 val ssig_fp_ctr_sugar = #fp_ctr_sugar ssig_fp_sugar; 2110 2111 val sig_fp_bnf_sugar = #fp_bnf_sugar sig_fp_sugar; 2112 val ssig_fp_bnf_sugar = #fp_bnf_sugar ssig_fp_sugar; 2113 val ssig_fp_induct_sugar = the (#fp_co_induct_sugar ssig_fp_sugar); 2114 2115 val sig_ctr_sugar = #ctr_sugar sig_fp_ctr_sugar; 2116 val ssig_ctr_sugar = #ctr_sugar ssig_fp_ctr_sugar; 2117 2118 val sig_T_name = fst (dest_Type (#T sig_fp_sugar)); 2119 val ssig_T_name = fst (dest_Type (#T ssig_fp_sugar)); 2120 2121 val sig_T = Type (sig_T_name, As); 2122 val ssig_T = Type (ssig_T_name, As); 2123 2124 val pre_map = mk_mapN lthy live_AsBs preT pre_bnf; 2125 val pre_rel = mk_relN lthy live_AsBs preT pre_bnf; 2126 val dead_pre_map = mk_map1 lthy Y Z preT dead_pre_bnf; 2127 val fp_rel = mk_relN lthy live_EsFs fpT fp_bnf; 2128 val dtor_unfold = mk_co_rec (Proof_Context.theory_of lthy) Greatest_FP [Z] fpT 2129 (the_single (#xtor_un_folds fp_res)); 2130 val Sig = mk_ctr As (the_single (#ctrs sig_ctr_sugar)); 2131 val unsig = mk_disc_or_sel As (the_single (the_single (#selss sig_ctr_sugar))); 2132 val sig_rel = mk_relN lthy live_AsBs sig_T sig_bnf; 2133 val dead_sig_map = mk_map 1 As Bs (map_of_bnf dead_sig_bnf); 2134 val [Oper, VLeaf, CLeaf] = map (mk_ctr As) (#ctrs ssig_ctr_sugar); 2135 val ssig_map = mk_mapN lthy live_AsBs ssig_T ssig_bnf; 2136 val ssig_rel = mk_relN lthy live_AsBs ssig_T ssig_bnf; 2137 val dead_ssig_map = mk_map 1 As Bs (map_of_bnf dead_ssig_bnf); 2138 2139 val ((Lam, Lam_def), lthy) = lthy 2140 |> define_Lam_base fp_b version Y Z preT ssig_T dead_pre_map Sig unsig dead_sig_map Oper 2141 VLeaf; 2142 2143 val proto_sctr = Sig; 2144 2145 val pre_map_transfer = map_transfer_of_bnf pre_bnf; 2146 val pre_rel_def = rel_def_of_bnf pre_bnf; 2147 val dead_pre_map_id = map_id_of_bnf dead_pre_bnf; 2148 val dead_pre_map_comp = map_comp_of_bnf dead_pre_bnf; 2149 val fp_rel_eq = rel_eq_of_bnf fp_bnf; 2150 val [ctor_dtor] = #ctor_dtors fp_res; 2151 val [dtor_ctor] = #dtor_ctors fp_res; 2152 val [dtor_inject] = #dtor_injects fp_res; 2153 val [dtor_unfold_thm] = #xtor_un_fold_thms fp_res; 2154 val dtor_unfold_unique = #xtor_un_fold_unique fp_res; 2155 val [dtor_unfold_transfer] = #xtor_un_fold_transfers fp_res; 2156 val [dtor_rel_thm] = #xtor_rels fp_res; 2157 val unsig_thm = the_single (the_single (#sel_thmss sig_ctr_sugar)); 2158 val [sig_map_thm] = #map_thms sig_fp_bnf_sugar; 2159 val [Oper_map_thm, VLeaf_map_thm, CLeaf_map_thm] = #map_thms ssig_fp_bnf_sugar; 2160 val sig_map_transfer = map_transfer_of_bnf sig_bnf; 2161 val ssig_map_thms = #map_thms ssig_fp_bnf_sugar; 2162 val ssig_map_transfer = map_transfer_of_bnf ssig_bnf; 2163 val ssig_induct = the_single (#co_inducts ssig_fp_induct_sugar); 2164 2165 val dtor_transfer = derive_dtor_transfer lthy live_EsFs Y Z pre_rel fp_rel Rs dtor dtor_rel_thm; 2166 val preT_rel_eqs = map rel_eq_of_bnf (map_filter (bnf_of lthy) (add_type_namesT preT [])); 2167 2168 val Sig_transfer = derive_sig_transfer I lthy live_AsBs pre_rel sig_rel Rs R Sig pre_rel_def 2169 preT_rel_eqs (the_single (#ctr_transfers sig_fp_ctr_sugar)); 2170 val proto_sctr_transfer = Sig_transfer; 2171 val unsig_transfer = derive_sig_transfer swap lthy live_AsBs pre_rel sig_rel Rs R unsig 2172 pre_rel_def preT_rel_eqs (the_single (#sel_transfers sig_fp_ctr_sugar)); 2173 val Lam_transfer = derive_Lam_or_eval_core_transfer lthy live_AsBs Y Z preT ssig_T Rs R pre_rel 2174 sig_rel ssig_rel Lam Lam_def [] 2175 [pre_map_transfer, sig_map_transfer, Sig_transfer, unsig_transfer]; 2176 2177 val ((((((((flat, _, flat_simps), flat_transfer), 2178 ((eval_core, _, eval_core_simps), eval_core_transfer)), (eval, eval_def)), 2179 (cutSsig, cutSsig_def)), (algLam, algLam_def)), (corecU, corecU_def)), lthy) = lthy 2180 |> define_flat_etc fp_b version live_AsBs Y Z preT fpT sig_T ssig_T Oper VLeaf CLeaf pre_rel 2181 dead_pre_map dtor dtor_unfold dead_sig_map ssig_rel dead_ssig_map Lam Rs R pre_map_transfer 2182 [fp_rel_eq] sig_map_transfer ssig_map_transfer Lam_transfer dtor_transfer; 2183 2184 val (Sig_pointful_natural, flat_pointful_natural, _, Lam_pointful_natural, _, 2185 eval_core_pointful_natural, eval_thm, eval_flat, eval_simps as [eval_Oper, eval_VLeaf, _], 2186 corecU_ctor, corecU_unique, dtor_algLam) = 2187 derive_Sig_natural_etc lthy live live_AsBs Y Z preT fpT fpT sig_T ssig_T pre_map dead_pre_map 2188 ctor dtor Sig dead_sig_map Oper VLeaf CLeaf ssig_map dead_ssig_map Lam flat eval_core eval 2189 cutSsig algLam corecU x fs f g ctor_dtor dtor_inject dtor_unfold_thm dtor_unfold_unique 2190 sig_map_thm ssig_induct ssig_map_thms Oper_map_thm VLeaf_map_thm CLeaf_map_thm Lam_transfer 2191 flat_simps flat_transfer eval_core_simps eval_core_transfer eval_def cutSsig_def algLam_def 2192 corecU_def pre_bnf pre_bnf dead_pre_bnf fp_bnf sig_bnf ssig_bnf dead_ssig_bnf; 2193 2194 val proto_sctr_pointful_natural = Sig_pointful_natural; 2195 2196 val algLam_thm = derive_algLam_base lthy Y Z preT fpT dead_pre_map ctor dtor algLam proto_sctr 2197 dead_pre_map_id dead_pre_map_comp ctor_dtor dtor_ctor dtor_unfold_unique unsig_thm 2198 Sig_pointful_natural ssig_map_thms Lam_def flat_simps eval_core_simps eval_thm algLam_def; 2199 2200 val (((corecUU, _), corecUU_thm, corecUU_unique, corecUU_transfer, eval_sctr, sctr_transfer, 2201 sctr_pointful_natural), lthy) = lthy 2202 |> define_corecUU_etc fp_b version live_AsBs Y Z preT fpT ssig_T pre_map dead_pre_map pre_rel 2203 fp_rel ctor Oper ssig_map dead_ssig_map ssig_rel proto_sctr flat eval_core eval corecU fs f 2204 g Rs R pre_map_transfer [] dtor_unfold_transfer dtor_transfer ssig_map_transfer 2205 proto_sctr_transfer proto_sctr_pointful_natural flat_transfer flat_pointful_natural 2206 eval_core_transfer eval_core_pointful_natural eval_thm eval_flat eval_Oper algLam_thm 2207 cutSsig_def corecU_def corecU_ctor corecU_unique pre_bnf dead_pre_bnf fp_res ssig_fp_sugar; 2208 2209 val (Retr, equivp_Retr, Retr_coinduct) = lthy 2210 |> derive_Retr fp_sugar fpT dead_pre_bnf ctor dtor names_lthy; 2211 2212 val (dtor_coinduct_info, lthy) = lthy 2213 |> derive_cong_base fp_b version fpT dead_ssig_bnf ssig_fp_bnf_sugar dead_pre_bnf eval 2214 eval_thm eval_core_transfer eval_VLeaf eval_sctr sctr_transfer Retr equivp_Retr Retr_coinduct; 2215 2216 val buffer = 2217 {Oper = Oper, VLeaf = VLeaf, CLeaf = CLeaf, ctr_wrapper = Sig, friends = Symtab.empty}; 2218 2219 val notes = 2220 [(corecUU_transferN, [corecUU_transfer])] @ 2221 (if Config.get lthy bnf_internals then 2222 [(algLamN, [algLam_thm]), 2223 (cong_alg_introsN, #cong_alg_intros dtor_coinduct_info), 2224 (cong_localeN, [#cong_locale dtor_coinduct_info]), 2225 (corecU_ctorN, [corecU_ctor]), 2226 (corecU_uniqueN, [corecU_unique]), 2227 (corecUUN, [corecUU_thm]), 2228 (corecUU_uniqueN, [corecUU_unique]), 2229 (dtor_algLamN, [dtor_algLam]), 2230 (dtor_coinductN, [#dtor_coinduct dtor_coinduct_info]), 2231 (dtor_transferN, [dtor_transfer]), 2232 (equivp_RetrN, [equivp_Retr]), 2233 (evalN, [eval_thm]), 2234 (eval_core_pointful_naturalN, [eval_core_pointful_natural]), 2235 (eval_core_transferN, [eval_core_transfer]), 2236 (eval_flatN, [eval_flat]), 2237 (eval_simpsN, eval_simps), 2238 (flat_pointful_naturalN, [flat_pointful_natural]), 2239 (flat_transferN, [flat_transfer]), 2240 (Lam_pointful_naturalN, [Lam_pointful_natural]), 2241 (Lam_transferN, [Lam_transfer]), 2242 (proto_sctr_pointful_naturalN, [proto_sctr_pointful_natural]), 2243 (proto_sctr_transferN, [proto_sctr_transfer]), 2244 (Retr_coinductN, [Retr_coinduct]), 2245 (sctr_pointful_naturalN, [sctr_pointful_natural]), 2246 (sctr_transferN, [sctr_transfer]), 2247 (Sig_pointful_naturalN, [Sig_pointful_natural])] 2248 else 2249 []) 2250 |> map (fn (thmN, thms) => 2251 ((mk_version_fp_binding true lthy version fp_b thmN, []), [(thms, [])])); 2252 in 2253 ({fp_b = fp_b, version = version, fpT = fpT, Y = Y, Z = Z, friend_names = [], 2254 sig_fp_sugars = [sig_fp_sugar], ssig_fp_sugar = ssig_fp_sugar, Lam = Lam, 2255 proto_sctr = proto_sctr, flat = flat, eval_core = eval_core, eval = eval, algLam = algLam, 2256 corecUU = corecUU, dtor_transfer = dtor_transfer, Lam_transfer = Lam_transfer, 2257 Lam_pointful_natural = Lam_pointful_natural, proto_sctr_transfer = proto_sctr_transfer, 2258 flat_simps = flat_simps, eval_core_simps = eval_core_simps, eval_thm = eval_thm, 2259 eval_simps = eval_simps, all_algLam_algs = [algLam_thm], algLam_thm = algLam_thm, 2260 dtor_algLam = dtor_algLam, corecUU_thm = corecUU_thm, corecUU_unique = corecUU_unique, 2261 corecUU_transfer = corecUU_transfer, buffer = buffer, all_dead_k_bnfs = [dead_pre_bnf], 2262 Retr = Retr, equivp_Retr = equivp_Retr, Retr_coinduct = Retr_coinduct, 2263 dtor_coinduct_info = dtor_coinduct_info} 2264 |> morph_corec_info (Local_Theory.target_morphism lthy), 2265 lthy |> Local_Theory.notes notes |> snd) 2266 end; 2267 2268fun derive_corecUU_step (fpT as Type (fpT_name, res_Ds)) 2269 ({friend_names = old_friend_names, sig_fp_sugars = old_sig_fp_sugars as old_sig_fp_sugar :: _, 2270 ssig_fp_sugar = old_ssig_fp_sugar, Lam = old_Lam0, proto_sctr = old_proto_sctr0, 2271 flat = old_flat0, eval_core = old_eval_core0, eval = old_eval0, algLam = old_algLam0, 2272 dtor_transfer, Lam_transfer = old_Lam_transfer, 2273 Lam_pointful_natural = old_Lam_pointful_natural, 2274 proto_sctr_transfer = old_proto_sctr_transfer, flat_simps = old_flat_simps, 2275 eval_core_simps = old_eval_core_simps, eval_thm = old_eval_thm, 2276 all_algLam_algs = old_all_algLam_algs, algLam_thm = old_algLam_thm, 2277 dtor_algLam = old_dtor_algLam, buffer = old_buffer, all_dead_k_bnfs = old_all_dead_k_bnfs, 2278 Retr = old_Retr0, equivp_Retr, Retr_coinduct, dtor_coinduct_info = old_dtor_coinduct_info, 2279 ...} : corec_info) 2280 friend_name friend_T fp_b version Y Z k_T dead_k_bnf sig_fp_sugar ssig_fp_sugar rho rho_transfer 2281 lthy = 2282 let 2283 val {pre_bnf = live_pre_bnf, fp_bnf = live_fp_bnf, fp_res, ...} = 2284 checked_fp_sugar_of lthy fpT_name; 2285 2286 val names_lthy = lthy 2287 |> fold Variable.declare_typ [Y, Z]; 2288 2289 (* FIXME *) 2290 val live_EsFs = []; 2291 val live_AsBs = live_EsFs @ [(Y, Z)]; 2292 val live = length live_EsFs; 2293 2294 val ((((x, f), g), R), _) = names_lthy 2295 |> yield_singleton (mk_Frees "x") Y 2296 ||>> yield_singleton (mk_Frees "f") (Y --> Z) 2297 ||>> yield_singleton (mk_Frees "g") (Y --> Z) 2298 ||>> yield_singleton (mk_Frees "R") (mk_pred2T Y Z); 2299 2300 (* FIXME *) 2301 val fs = []; 2302 val Rs = []; 2303 2304 val ctor = mk_ctor res_Ds (the_single (#ctors fp_res)); 2305 val dtor = mk_dtor res_Ds (the_single (#dtors fp_res)); 2306 2307 val friend_names = friend_name :: old_friend_names; 2308 2309 val old_sig_bnf = #fp_bnf old_sig_fp_sugar; 2310 val old_ssig_bnf = #fp_bnf old_ssig_fp_sugar; 2311 val sig_bnf = #fp_bnf sig_fp_sugar; 2312 val ssig_bnf = #fp_bnf ssig_fp_sugar; 2313 2314 val ((((((dead_pre_bnf, dead_fp_bnf), dead_old_sig_bnf), dead_old_ssig_bnf), dead_sig_bnf), 2315 dead_ssig_bnf), lthy) = lthy 2316 |> bnf_kill_all_but 1 live_pre_bnf 2317 ||>> bnf_kill_all_but 0 live_fp_bnf 2318 ||>> bnf_kill_all_but 1 old_sig_bnf 2319 ||>> bnf_kill_all_but 1 old_ssig_bnf 2320 ||>> bnf_kill_all_but 1 sig_bnf 2321 ||>> bnf_kill_all_but 1 ssig_bnf; 2322 2323 (* FIXME *) 2324 val pre_bnf = dead_pre_bnf; 2325 val fp_bnf = dead_fp_bnf; 2326 2327 val old_ssig_fp_ctr_sugar = #fp_ctr_sugar old_ssig_fp_sugar; 2328 val sig_fp_ctr_sugar = #fp_ctr_sugar sig_fp_sugar; 2329 val ssig_fp_ctr_sugar = #fp_ctr_sugar ssig_fp_sugar; 2330 2331 val sig_fp_bnf_sugar = #fp_bnf_sugar sig_fp_sugar; 2332 val old_ssig_fp_bnf_sugar = #fp_bnf_sugar old_ssig_fp_sugar; 2333 val ssig_fp_bnf_sugar = #fp_bnf_sugar ssig_fp_sugar; 2334 val old_ssig_fp_induct_sugar = the (#fp_co_induct_sugar old_ssig_fp_sugar); 2335 val ssig_fp_induct_sugar = the (#fp_co_induct_sugar ssig_fp_sugar); 2336 2337 val old_ssig_ctr_sugar = #ctr_sugar old_ssig_fp_ctr_sugar; 2338 val sig_ctr_sugar = #ctr_sugar sig_fp_ctr_sugar; 2339 val ssig_ctr_sugar = #ctr_sugar ssig_fp_ctr_sugar; 2340 2341 val old_sig_T_name = fst (dest_Type (#T old_sig_fp_sugar)); 2342 val old_ssig_T_name = fst (dest_Type (#T old_ssig_fp_sugar)); 2343 val sig_T_name = fst (dest_Type (#T sig_fp_sugar)); 2344 val ssig_T_name = fst (dest_Type (#T ssig_fp_sugar)); 2345 2346 val res_As = res_Ds @ [Y]; 2347 val res_Bs = res_Ds @ [Z]; 2348 val preT = pre_type_of_ctor Y ctor; 2349 val YpreT = HOLogic.mk_prodT (Y, preT); 2350 val old_sig_T = Type (old_sig_T_name, res_As); 2351 val old_ssig_T = Type (old_ssig_T_name, res_As); 2352 val sig_T = Type (sig_T_name, res_As); 2353 val ssig_T = Type (ssig_T_name, res_As); 2354 val old_Lam_domT = Tsubst Y YpreT old_sig_T; 2355 val old_eval_core_domT = Tsubst Y YpreT old_ssig_T; 2356 2357 val pre_map = mk_mapN lthy live_AsBs preT pre_bnf; 2358 val pre_rel = mk_relN lthy live_AsBs preT pre_bnf; 2359 val dead_pre_map = mk_map1 lthy Y Z preT dead_pre_bnf; 2360 val dead_pre_rel = mk_rel1 lthy Y Z preT dead_pre_bnf; 2361 val fp_rel = mk_relN lthy live_EsFs fpT fp_bnf; 2362 val dtor_unfold = mk_co_rec (Proof_Context.theory_of lthy) Greatest_FP [Z] fpT 2363 (the_single (#xtor_un_folds fp_res)); 2364 val dead_k_map = mk_map1 lthy Y Z k_T dead_k_bnf; 2365 val Sig = mk_ctr res_As (the_single (#ctrs sig_ctr_sugar)); 2366 val unsig = mk_disc_or_sel res_As (the_single (the_single (#selss sig_ctr_sugar))); 2367 val sig_rel = mk_relN lthy live_AsBs sig_T sig_bnf; 2368 val dead_old_sig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old_sig_bnf); 2369 val dead_sig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_sig_bnf); 2370 val dead_sig_rel = mk_rel 1 res_As res_Bs (rel_of_bnf dead_sig_bnf); 2371 val [old_Oper, old_VLeaf, old_CLeaf] = map (mk_ctr res_As) (#ctrs old_ssig_ctr_sugar); 2372 val [Oper, VLeaf, CLeaf] = map (mk_ctr res_As) (#ctrs ssig_ctr_sugar); 2373 val dead_old_ssig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old_ssig_bnf); 2374 val ssig_map = mk_mapN lthy live_AsBs ssig_T ssig_bnf; 2375 val ssig_rel = mk_relN lthy live_AsBs ssig_T ssig_bnf; 2376 val dead_ssig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_ssig_bnf); 2377 val old_Lam = enforce_type lthy domain_type old_Lam_domT old_Lam0; 2378 val old_proto_sctr = enforce_type lthy domain_type preT old_proto_sctr0; 2379 val old_flat = enforce_type lthy range_type old_ssig_T old_flat0; 2380 val old_eval_core = enforce_type lthy domain_type old_eval_core_domT old_eval_core0; 2381 val old_eval = enforce_type lthy range_type fpT old_eval0; 2382 val old_algLam = enforce_type lthy range_type fpT old_algLam0; 2383 2384 val ((embL, embL_def, embL_simps), lthy) = lthy 2385 |> define_embL embLN fp_b version Y Z fpT old_sig_T old_ssig_T k_T ssig_T Inl_const 2386 dead_old_sig_map Sig old_Oper old_VLeaf old_CLeaf Oper VLeaf CLeaf; 2387 2388 val ((Lam, Lam_def), lthy) = lthy 2389 |> define_Lam_step fp_b version Y Z preT old_ssig_T ssig_T dead_pre_map unsig rho embL 2390 old_Lam; 2391 2392 val ((proto_sctr, proto_sctr_def), lthy) = lthy 2393 |> define_proto_sctr_step_or_merge fp_b version old_sig_T k_T Sig old_proto_sctr; 2394 2395 val pre_map_comp = map_comp_of_bnf pre_bnf; 2396 val pre_map_transfer = map_transfer_of_bnf pre_bnf; 2397 val dead_pre_map_id = map_id_of_bnf dead_pre_bnf; 2398 val dead_pre_map_comp0 = map_comp0_of_bnf dead_pre_bnf; 2399 val dead_pre_map_comp = map_comp_of_bnf dead_pre_bnf; 2400 val fp_map_id = map_id_of_bnf fp_bnf; 2401 val [ctor_dtor] = #ctor_dtors fp_res; 2402 val [dtor_inject] = #dtor_injects fp_res; 2403 val [dtor_unfold_thm] = #xtor_un_fold_thms fp_res; 2404 val dtor_unfold_unique = #xtor_un_fold_unique fp_res; 2405 val [dtor_unfold_transfer] = #xtor_un_fold_transfers fp_res; 2406 val fp_k_T_rel_eqs = 2407 map rel_eq_of_bnf (map_filter (bnf_of lthy) (fold add_type_namesT [fpT, k_T] [])); 2408 val unsig_thm = the_single (the_single (#sel_thmss sig_ctr_sugar)); 2409 val [sig_map_thm] = #map_thms sig_fp_bnf_sugar; 2410 val old_sig_map_comp = map_comp_of_bnf old_sig_bnf; 2411 val old_sig_map_cong = map_cong_of_bnf old_sig_bnf; 2412 val old_ssig_map_thms = #map_thms old_ssig_fp_bnf_sugar; 2413 val [Oper_map_thm, VLeaf_map_thm, CLeaf_map_thm] = #map_thms ssig_fp_bnf_sugar; 2414 val old_sig_map_transfer = map_transfer_of_bnf old_sig_bnf; 2415 val sig_map_comp = map_comp_of_bnf sig_bnf; 2416 val sig_map_transfer = map_transfer_of_bnf sig_bnf; 2417 val ssig_map_thms = #map_thms ssig_fp_bnf_sugar; 2418 val ssig_map_transfer = map_transfer_of_bnf ssig_bnf; 2419 val old_ssig_induct = the_single (#co_inducts old_ssig_fp_induct_sugar); 2420 val ssig_induct = the_single (#co_inducts ssig_fp_induct_sugar); 2421 2422 val proto_sctr_transfer = derive_proto_sctr_transfer_step_or_merge lthy Y Z R dead_pre_rel 2423 dead_sig_rel proto_sctr proto_sctr_def fp_k_T_rel_eqs [old_proto_sctr_transfer]; 2424 val embL_transfer = derive_transfer_by_transfer_prover lthy live_AsBs Rs R embL [embL_def] 2425 fp_k_T_rel_eqs [old_sig_map_transfer]; 2426 val Lam_transfer = derive_Lam_or_eval_core_transfer lthy live_AsBs Y Z preT ssig_T Rs R pre_rel 2427 sig_rel ssig_rel Lam Lam_def fp_k_T_rel_eqs 2428 [pre_map_transfer, old_Lam_transfer, embL_transfer, rho_transfer]; 2429 2430 val ((((((((flat, _, flat_simps), flat_transfer), 2431 ((eval_core, _, eval_core_simps), eval_core_transfer)), (eval, eval_def)), 2432 (cutSsig, cutSsig_def)), (algLam, algLam_def)), (corecU, corecU_def)), lthy) = lthy 2433 |> define_flat_etc fp_b version live_AsBs Y Z preT fpT sig_T ssig_T Oper VLeaf CLeaf pre_rel 2434 dead_pre_map dtor dtor_unfold dead_sig_map ssig_rel dead_ssig_map Lam Rs R pre_map_transfer 2435 fp_k_T_rel_eqs sig_map_transfer ssig_map_transfer Lam_transfer dtor_transfer; 2436 2437 val (Sig_pointful_natural, flat_pointful_natural, Lam_natural_pointful, Lam_pointful_natural, 2438 flat_VLeaf, eval_core_pointful_natural, eval_thm, eval_flat, 2439 eval_simps as [eval_Oper, _, _], corecU_ctor, corecU_unique, dtor_algLam) = 2440 derive_Sig_natural_etc lthy live live_AsBs Y Z preT fpT k_T sig_T ssig_T pre_map dead_pre_map 2441 ctor dtor Sig dead_sig_map Oper VLeaf CLeaf ssig_map dead_ssig_map Lam flat eval_core eval 2442 cutSsig algLam corecU x fs f g ctor_dtor dtor_inject dtor_unfold_thm dtor_unfold_unique 2443 sig_map_thm ssig_induct ssig_map_thms Oper_map_thm VLeaf_map_thm CLeaf_map_thm Lam_transfer 2444 flat_simps flat_transfer eval_core_simps eval_core_transfer eval_def cutSsig_def algLam_def 2445 corecU_def live_pre_bnf pre_bnf dead_pre_bnf fp_bnf sig_bnf ssig_bnf dead_ssig_bnf; 2446 2447 val proto_sctr_natural = derive_natural_from_transfer_with_pre_type lthy live_AsBs Y Z preT 2448 ssig_T pre_map ssig_map fs f proto_sctr proto_sctr_transfer [pre_bnf, sig_bnf] []; 2449 val proto_sctr_pointful_natural = mk_pointful lthy proto_sctr_natural RS sym; 2450 2451 val (embL_pointful_natural, old_algLam_pointful, eval_embL, algLam_algLam) = 2452 derive_embL_natural_etc lthy Inl_const old_ssig_bnf ssig_bnf Y Z preT fpT old_ssig_T ssig_T 2453 dead_pre_map Sig dead_old_ssig_map embL old_algLam algLam old_flat flat old_eval_core 2454 eval_core old_eval eval x f old_ssig_induct dead_pre_map_comp0 dead_pre_map_comp fp_map_id 2455 dtor_inject dtor_unfold_unique Sig_pointful_natural unsig_thm sig_map_thm old_sig_map_comp 2456 old_sig_map_cong old_ssig_map_thms old_Lam_pointful_natural Lam_def old_flat_simps 2457 flat_simps embL_simps embL_transfer old_eval_core_simps eval_core_simps old_eval_thm 2458 eval_thm old_dtor_algLam dtor_algLam old_algLam_thm; 2459 2460 val algLam_thm = derive_algLam_step_or_merge lthy Y fpT ctor proto_sctr algLam proto_sctr_def 2461 old_algLam_pointful algLam_algLam; 2462 2463 val k_as_ssig = mk_k_as_ssig Z old_sig_T k_T ssig_T Sig dead_sig_map Oper VLeaf; 2464 val k_as_ssig' = substT Y fpT k_as_ssig; 2465 2466 val algrho_rhs = HOLogic.mk_comp (eval, k_as_ssig'); 2467 val ((algrho, algrho_def), lthy) = lthy 2468 |> define_const true fp_b version algrhoN algrho_rhs; 2469 2470 val k_as_ssig_transfer = derive_transfer_by_transfer_prover lthy live_AsBs Rs R k_as_ssig [] 2471 fp_k_T_rel_eqs [sig_map_transfer]; 2472 2473 val k_as_ssig_natural = derive_natural_from_transfer lthy [(Y, Z)] [] [] f k_as_ssig 2474 k_as_ssig_transfer [ssig_bnf] [dead_k_bnf]; 2475 2476 val k_as_ssig_natural_pointful = mk_pointful lthy k_as_ssig_natural; 2477 2478 val [_, Lam_Inr] = derive_Lam_Inl_Inr lthy Y Z preT old_sig_T old_ssig_T k_T ssig_T 2479 dead_pre_map Sig embL old_Lam Lam rho unsig_thm Lam_def; 2480 2481 val eval_core_k_as_ssig = derive_eval_core_k_as_ssig lthy Y preT k_T rho eval_core k_as_ssig x 2482 pre_map_comp dead_pre_map_id sig_map_comp ssig_map_thms Lam_natural_pointful Lam_Inr 2483 flat_VLeaf eval_core_simps; 2484 2485 val algLam_algrho = derive_algLam_algrho lthy Y fpT Sig algLam algrho algLam_def algrho_def; 2486 val dtor_algrho = derive_dtor_algrho lthy Y Z preT fpT k_T ssig_T dead_pre_map dead_k_map dtor 2487 rho eval algrho x eval_thm k_as_ssig_natural_pointful eval_core_k_as_ssig algrho_def; 2488 val all_algLam_algs = algLam_algLam :: algLam_algrho :: old_all_algLam_algs; 2489 2490 val (((corecUU, _), corecUU_thm, corecUU_unique, corecUU_transfer, _, sctr_transfer, 2491 sctr_pointful_natural), lthy) = lthy 2492 |> define_corecUU_etc fp_b version live_AsBs Y Z preT fpT ssig_T pre_map dead_pre_map pre_rel 2493 fp_rel ctor Oper ssig_map dead_ssig_map ssig_rel proto_sctr flat eval_core eval corecU fs f 2494 g Rs R pre_map_transfer fp_k_T_rel_eqs dtor_unfold_transfer dtor_transfer ssig_map_transfer 2495 proto_sctr_transfer proto_sctr_pointful_natural flat_transfer flat_pointful_natural 2496 eval_core_transfer eval_core_pointful_natural eval_thm eval_flat eval_Oper algLam_thm 2497 cutSsig_def corecU_def corecU_ctor corecU_unique pre_bnf dead_pre_bnf fp_res ssig_fp_sugar; 2498 2499 val (ctr_wrapper, friends) = 2500 mk_ctr_wrapper_friends lthy friend_name friend_T old_sig_T k_T Sig old_buffer; 2501 2502 val Retr = enforce_type lthy (domain_type o domain_type) fpT old_Retr0; 2503 2504 val (dtor_coinduct_info, lthy) = lthy 2505 |> derive_cong_step fp_b version fpT dead_ssig_bnf dead_pre_bnf eval eval_thm 2506 eval_core_transfer old_dtor_coinduct_info algrho_def k_as_ssig_transfer Retr equivp_Retr 2507 Retr_coinduct eval_embL embL_transfer old_all_dead_k_bnfs; 2508 2509 val buffer = 2510 {Oper = Oper, VLeaf = VLeaf, CLeaf = CLeaf, ctr_wrapper = ctr_wrapper, friends = friends}; 2511 2512 val notes = 2513 [(corecUU_transferN, [corecUU_transfer])] @ 2514 (if Config.get lthy bnf_internals then 2515 [(algLamN, [algLam_thm]), 2516 (algLam_algLamN, [algLam_algLam]), 2517 (algLam_algrhoN, [algLam_algrho]), 2518 (cong_alg_introsN, #cong_alg_intros dtor_coinduct_info), 2519 (cong_localeN, [#cong_locale dtor_coinduct_info]), 2520 (corecU_ctorN, [corecU_ctor]), 2521 (corecU_uniqueN, [corecU_unique]), 2522 (corecUUN, [corecUU_thm]), 2523 (corecUU_uniqueN, [corecUU_unique]), 2524 (dtor_algLamN, [dtor_algLam]), 2525 (dtor_algrhoN, [dtor_algrho]), 2526 (dtor_coinductN, [#dtor_coinduct dtor_coinduct_info]), 2527 (embL_pointful_naturalN, [embL_pointful_natural]), 2528 (embL_transferN, [embL_transfer]), 2529 (evalN, [eval_thm]), 2530 (eval_core_pointful_naturalN, [eval_core_pointful_natural]), 2531 (eval_core_transferN, [eval_core_transfer]), 2532 (eval_flatN, [eval_flat]), 2533 (eval_simpsN, eval_simps), 2534 (flat_pointful_naturalN, [flat_pointful_natural]), 2535 (flat_transferN, [flat_transfer]), 2536 (k_as_ssig_naturalN, [k_as_ssig_natural]), 2537 (k_as_ssig_transferN, [k_as_ssig_transfer]), 2538 (Lam_pointful_naturalN, [Lam_pointful_natural]), 2539 (Lam_transferN, [Lam_transfer]), 2540 (proto_sctr_pointful_naturalN, [proto_sctr_pointful_natural]), 2541 (proto_sctr_transferN, [proto_sctr_transfer]), 2542 (rho_transferN, [rho_transfer]), 2543 (sctr_pointful_naturalN, [sctr_pointful_natural]), 2544 (sctr_transferN, [sctr_transfer]), 2545 (Sig_pointful_naturalN, [Sig_pointful_natural])] 2546 else 2547 []) 2548 |> map (fn (thmN, thms) => 2549 ((mk_version_fp_binding true lthy version fp_b thmN, []), [(thms, [])])); 2550 2551 val phi = Local_Theory.target_morphism lthy; 2552 in 2553 (({fp_b = fp_b, version = version, fpT = fpT, Y = Y, Z = Z, friend_names = friend_names, 2554 sig_fp_sugars = sig_fp_sugar :: old_sig_fp_sugars, ssig_fp_sugar = ssig_fp_sugar, Lam = Lam, 2555 proto_sctr = proto_sctr, flat = flat, eval_core = eval_core, eval = eval, algLam = algLam, 2556 corecUU = corecUU, dtor_transfer = dtor_transfer, Lam_transfer = Lam_transfer, 2557 Lam_pointful_natural = Lam_pointful_natural, proto_sctr_transfer = proto_sctr_transfer, 2558 flat_simps = flat_simps, eval_core_simps = eval_core_simps, eval_thm = eval_thm, 2559 eval_simps = eval_simps, all_algLam_algs = all_algLam_algs, algLam_thm = algLam_thm, 2560 dtor_algLam = dtor_algLam, corecUU_thm = corecUU_thm, corecUU_unique = corecUU_unique, 2561 corecUU_transfer = corecUU_transfer, buffer = buffer, 2562 all_dead_k_bnfs = dead_k_bnf :: old_all_dead_k_bnfs, Retr = Retr, equivp_Retr = equivp_Retr, 2563 Retr_coinduct = Retr_coinduct, dtor_coinduct_info = dtor_coinduct_info} 2564 |> morph_corec_info phi, 2565 ({algrho = algrho, dtor_algrho = dtor_algrho, algLam_algrho = algLam_algrho} 2566 |> morph_friend_info phi)), 2567 lthy |> Local_Theory.notes notes |> snd) 2568 end; 2569 2570fun derive_corecUU_merge (fpT as Type (fpT_name, res_Ds)) 2571 ({friend_names = old1_friend_names, 2572 sig_fp_sugars = old1_sig_fp_sugars as old1_sig_fp_sugar :: _, 2573 ssig_fp_sugar = old1_ssig_fp_sugar, Lam = old1_Lam0, proto_sctr = old1_proto_sctr0, 2574 flat = old1_flat0, eval_core = old1_eval_core0, eval = old1_eval0, algLam = old1_algLam0, 2575 dtor_transfer, Lam_transfer = old1_Lam_transfer, 2576 Lam_pointful_natural = old1_Lam_pointful_natural, 2577 proto_sctr_transfer = old1_proto_sctr_transfer, flat_simps = old1_flat_simps, 2578 eval_core_simps = old1_eval_core_simps, eval_thm = old1_eval_thm, 2579 all_algLam_algs = old1_all_algLam_algs, algLam_thm = old1_algLam_thm, 2580 dtor_algLam = old1_dtor_algLam, buffer = old1_buffer, all_dead_k_bnfs = old1_all_dead_k_bnfs, 2581 Retr = old1_Retr0, equivp_Retr, Retr_coinduct, dtor_coinduct_info = old1_dtor_coinduct_info, 2582 ...} : corec_info) 2583 ({friend_names = old2_friend_names, 2584 sig_fp_sugars = old2_sig_fp_sugars as old2_sig_fp_sugar :: _, 2585 ssig_fp_sugar = old2_ssig_fp_sugar, Lam = old2_Lam0, flat = old2_flat0, 2586 eval_core = old2_eval_core0, eval = old2_eval0, algLam = old2_algLam0, 2587 Lam_transfer = old2_Lam_transfer, Lam_pointful_natural = old2_Lam_pointful_natural, 2588 flat_simps = old2_flat_simps, eval_core_simps = old2_eval_core_simps, 2589 eval_thm = old2_eval_thm, all_algLam_algs = old2_all_algLam_algs, 2590 algLam_thm = old2_algLam_thm, dtor_algLam = old2_dtor_algLam, buffer = old2_buffer, 2591 all_dead_k_bnfs = old2_all_dead_k_bnfs, dtor_coinduct_info = old2_dtor_coinduct_info, ...} 2592 : corec_info) 2593 lthy = 2594 let 2595 val {T = Type (_, fpT_args0), pre_bnf = live_pre_bnf, fp_bnf = live_fp_bnf, fp_res, ...} = 2596 checked_fp_sugar_of lthy fpT_name; 2597 val fpT_Ss = map Type.sort_of_atyp fpT_args0; 2598 val live_fp_alives = liveness_of_fp_bnf (length fpT_args0) live_fp_bnf; 2599 2600 val ((Ds, [Y, Z]), names_lthy) = lthy 2601 |> mk_TFrees' fpT_Ss 2602 ||>> mk_TFrees 2; 2603 2604 (* FIXME *) 2605 val live_EsFs = []; 2606 val live_AsBs = live_EsFs @ [(Y, Z)]; 2607 val live = length live_EsFs; 2608 2609 val ((((x, f), g), R), _) = names_lthy 2610 |> yield_singleton (mk_Frees "x") Y 2611 ||>> yield_singleton (mk_Frees "f") (Y --> Z) 2612 ||>> yield_singleton (mk_Frees "g") (Y --> Z) 2613 ||>> yield_singleton (mk_Frees "R") (mk_pred2T Y Z); 2614 2615 (* FIXME *) 2616 val fs = []; 2617 val Rs = []; 2618 2619 val ctor = mk_ctor res_Ds (the_single (#ctors fp_res)); 2620 val dtor = mk_dtor res_Ds (the_single (#dtors fp_res)); 2621 2622 val old1_sig_T_name = fst (dest_Type (#T old1_sig_fp_sugar)); 2623 val old2_sig_T_name = fst (dest_Type (#T old2_sig_fp_sugar)); 2624 val old1_ssig_T_name = fst (dest_Type (#T old1_ssig_fp_sugar)); 2625 val old2_ssig_T_name = fst (dest_Type (#T old2_ssig_fp_sugar)); 2626 2627 val fp_alives = map (K false) live_fp_alives; 2628 2629 val As = Ds @ [Y]; 2630 val res_As = res_Ds @ [Y]; 2631 val res_Bs = res_Ds @ [Z]; 2632 val preT = pre_type_of_ctor Y ctor; 2633 val YpreT = HOLogic.mk_prodT (Y, preT); 2634 val fpT0 = Type (fpT_name, Ds); 2635 val old1_sig_T0 = Type (old1_sig_T_name, As); 2636 val old2_sig_T0 = Type (old2_sig_T_name, As); 2637 val old1_sig_T = Type (old1_sig_T_name, res_As); 2638 val old2_sig_T = Type (old2_sig_T_name, res_As); 2639 val old1_ssig_T = Type (old1_ssig_T_name, res_As); 2640 val old2_ssig_T = Type (old2_ssig_T_name, res_As); 2641 val old1_Lam_domT = Tsubst Y YpreT old1_sig_T; 2642 val old2_Lam_domT = Tsubst Y YpreT old2_sig_T; 2643 val old1_eval_core_domT = Tsubst Y YpreT old1_ssig_T; 2644 val old2_eval_core_domT = Tsubst Y YpreT old2_ssig_T; 2645 2646 val ((fp_b, version), lthy) = lthy |> get_name_next_version_of fpT_name; 2647 2648 val ((sig_fp_sugar, ssig_fp_sugar), lthy) = lthy 2649 |> define_sig_type fp_b version fp_alives Ds Y (mk_sumT (old1_sig_T0, old2_sig_T0)) 2650 ||>> define_ssig_type fp_b version fp_alives Ds Y fpT0; 2651 2652 val sig_T_name = fst (dest_Type (#T sig_fp_sugar)); 2653 val ssig_T_name = fst (dest_Type (#T ssig_fp_sugar)); 2654 2655 val old1_sig_bnf = #fp_bnf old1_sig_fp_sugar; 2656 val old2_sig_bnf = #fp_bnf old2_sig_fp_sugar; 2657 val old1_ssig_bnf = #fp_bnf old1_ssig_fp_sugar; 2658 val old2_ssig_bnf = #fp_bnf old2_ssig_fp_sugar; 2659 val sig_bnf = #fp_bnf sig_fp_sugar; 2660 val ssig_bnf = #fp_bnf ssig_fp_sugar; 2661 2662 val ((((((((dead_pre_bnf, dead_fp_bnf), dead_old1_sig_bnf), dead_old2_sig_bnf), 2663 dead_old1_ssig_bnf), dead_old2_ssig_bnf), dead_sig_bnf), dead_ssig_bnf), lthy) = lthy 2664 |> bnf_kill_all_but 1 live_pre_bnf 2665 ||>> bnf_kill_all_but 0 live_fp_bnf 2666 ||>> bnf_kill_all_but 1 old1_sig_bnf 2667 ||>> bnf_kill_all_but 1 old2_sig_bnf 2668 ||>> bnf_kill_all_but 1 old1_ssig_bnf 2669 ||>> bnf_kill_all_but 1 old2_ssig_bnf 2670 ||>> bnf_kill_all_but 1 sig_bnf 2671 ||>> bnf_kill_all_but 1 ssig_bnf; 2672 2673 (* FIXME *) 2674 val pre_bnf = dead_pre_bnf; 2675 val fp_bnf = dead_fp_bnf; 2676 2677 val old1_ssig_fp_ctr_sugar = #fp_ctr_sugar old1_ssig_fp_sugar; 2678 val old2_ssig_fp_ctr_sugar = #fp_ctr_sugar old2_ssig_fp_sugar; 2679 val sig_fp_ctr_sugar = #fp_ctr_sugar sig_fp_sugar; 2680 val ssig_fp_ctr_sugar = #fp_ctr_sugar ssig_fp_sugar; 2681 2682 val sig_fp_bnf_sugar = #fp_bnf_sugar sig_fp_sugar; 2683 val old1_ssig_fp_bnf_sugar = #fp_bnf_sugar old1_ssig_fp_sugar; 2684 val old2_ssig_fp_bnf_sugar = #fp_bnf_sugar old2_ssig_fp_sugar; 2685 val ssig_fp_bnf_sugar = #fp_bnf_sugar ssig_fp_sugar; 2686 val old1_ssig_fp_induct_sugar = the (#fp_co_induct_sugar old1_ssig_fp_sugar); 2687 val old2_ssig_fp_induct_sugar = the (#fp_co_induct_sugar old2_ssig_fp_sugar); 2688 val ssig_fp_induct_sugar = the (#fp_co_induct_sugar ssig_fp_sugar); 2689 2690 val old1_ssig_ctr_sugar = #ctr_sugar old1_ssig_fp_ctr_sugar; 2691 val old2_ssig_ctr_sugar = #ctr_sugar old2_ssig_fp_ctr_sugar; 2692 val sig_ctr_sugar = #ctr_sugar sig_fp_ctr_sugar; 2693 val ssig_ctr_sugar = #ctr_sugar ssig_fp_ctr_sugar; 2694 2695 val sig_T = Type (sig_T_name, res_As); 2696 val ssig_T = Type (ssig_T_name, res_As); 2697 2698 val pre_map = mk_mapN lthy live_AsBs preT pre_bnf; 2699 val pre_rel = mk_relN lthy live_AsBs preT pre_bnf; 2700 val dead_pre_map = mk_map1 lthy Y Z preT dead_pre_bnf; 2701 val dead_pre_rel = mk_rel1 lthy Y Z preT dead_pre_bnf; 2702 val fp_rel = mk_relN lthy live_EsFs fpT fp_bnf; 2703 val dtor_unfold = mk_co_rec (Proof_Context.theory_of lthy) Greatest_FP [Z] fpT 2704 (the_single (#xtor_un_folds fp_res)); 2705 val Sig = mk_ctr res_As (the_single (#ctrs sig_ctr_sugar)); 2706 val unsig = mk_disc_or_sel res_As (the_single (the_single (#selss sig_ctr_sugar))); 2707 val sig_rel = mk_relN lthy live_AsBs sig_T sig_bnf; 2708 val dead_old1_sig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old1_sig_bnf); 2709 val dead_old2_sig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old2_sig_bnf); 2710 val dead_sig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_sig_bnf); 2711 val dead_sig_rel = mk_rel 1 res_As res_Bs (rel_of_bnf dead_sig_bnf); 2712 val [old1_Oper, old1_VLeaf, old1_CLeaf] = map (mk_ctr res_As) (#ctrs old1_ssig_ctr_sugar); 2713 val [old2_Oper, old2_VLeaf, old2_CLeaf] = map (mk_ctr res_As) (#ctrs old2_ssig_ctr_sugar); 2714 val [Oper, VLeaf, CLeaf] = map (mk_ctr res_As) (#ctrs ssig_ctr_sugar); 2715 val old1_ssig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old1_ssig_bnf); 2716 val old2_ssig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_old2_ssig_bnf); 2717 val ssig_map = mk_mapN lthy live_AsBs ssig_T ssig_bnf; 2718 val ssig_rel = mk_relN lthy live_AsBs ssig_T ssig_bnf; 2719 val dead_ssig_map = mk_map 1 res_As res_Bs (map_of_bnf dead_ssig_bnf); 2720 val old1_Lam = enforce_type lthy domain_type old1_Lam_domT old1_Lam0; 2721 val old2_Lam = enforce_type lthy domain_type old2_Lam_domT old2_Lam0; 2722 val old1_proto_sctr = enforce_type lthy domain_type preT old1_proto_sctr0; 2723 val old1_flat = enforce_type lthy range_type old1_ssig_T old1_flat0; 2724 val old2_flat = enforce_type lthy range_type old2_ssig_T old2_flat0; 2725 val old1_eval_core = enforce_type lthy domain_type old1_eval_core_domT old1_eval_core0; 2726 val old2_eval_core = enforce_type lthy domain_type old2_eval_core_domT old2_eval_core0; 2727 val old1_eval = enforce_type lthy range_type fpT old1_eval0; 2728 val old2_eval = enforce_type lthy range_type fpT old2_eval0; 2729 val old1_algLam = enforce_type lthy range_type fpT old1_algLam0; 2730 val old2_algLam = enforce_type lthy range_type fpT old2_algLam0; 2731 2732 val ((embLL, embLL_def, embLL_simps), lthy) = lthy 2733 |> define_embL embLLN fp_b version Y Z fpT old1_sig_T old1_ssig_T old2_sig_T ssig_T Inl_const 2734 dead_old1_sig_map Sig old1_Oper old1_VLeaf old1_CLeaf Oper VLeaf CLeaf; 2735 2736 val ((embLR, embLR_def, embLR_simps), lthy) = lthy 2737 |> define_embL embLRN fp_b version Y Z fpT old2_sig_T old2_ssig_T old1_sig_T ssig_T 2738 (fn T => fn U => Inr_const U T) dead_old2_sig_map Sig old2_Oper old2_VLeaf old2_CLeaf Oper 2739 VLeaf CLeaf; 2740 2741 val ((Lam, Lam_def), lthy) = lthy 2742 |> define_Lam_merge fp_b version Y Z preT old1_ssig_T old2_ssig_T ssig_T dead_pre_map unsig 2743 embLL embLR old1_Lam old2_Lam; 2744 2745 val ((proto_sctr, proto_sctr_def), lthy) = lthy 2746 |> define_proto_sctr_step_or_merge fp_b version old1_sig_T old2_sig_T Sig old1_proto_sctr; 2747 2748 val pre_map_transfer = map_transfer_of_bnf pre_bnf; 2749 val dead_pre_map_comp0 = map_comp0_of_bnf dead_pre_bnf; 2750 val dead_pre_map_comp = map_comp_of_bnf dead_pre_bnf; 2751 val fp_map_id = map_id_of_bnf fp_bnf; 2752 val fp_rel_eq = rel_eq_of_bnf fp_bnf; 2753 val [ctor_dtor] = #ctor_dtors fp_res; 2754 val [dtor_inject] = #dtor_injects fp_res; 2755 val [dtor_unfold_thm] = #xtor_un_fold_thms fp_res; 2756 val dtor_unfold_unique = #xtor_un_fold_unique fp_res; 2757 val [dtor_unfold_transfer] = #xtor_un_fold_transfers fp_res; 2758 val unsig_thm = the_single (the_single (#sel_thmss sig_ctr_sugar)); 2759 val [sig_map_thm] = #map_thms sig_fp_bnf_sugar; 2760 val old1_sig_map_comp = map_comp_of_bnf old1_sig_bnf; 2761 val old2_sig_map_comp = map_comp_of_bnf old2_sig_bnf; 2762 val old1_sig_map_cong = map_cong_of_bnf old1_sig_bnf; 2763 val old2_sig_map_cong = map_cong_of_bnf old2_sig_bnf; 2764 val old1_ssig_map_thms = #map_thms old1_ssig_fp_bnf_sugar; 2765 val old2_ssig_map_thms = #map_thms old2_ssig_fp_bnf_sugar; 2766 val [Oper_map_thm, VLeaf_map_thm, CLeaf_map_thm] = #map_thms ssig_fp_bnf_sugar; 2767 val old1_sig_map_transfer = map_transfer_of_bnf old1_sig_bnf; 2768 val old2_sig_map_transfer = map_transfer_of_bnf old2_sig_bnf; 2769 val sig_map_transfer = map_transfer_of_bnf sig_bnf; 2770 val ssig_map_thms = #map_thms ssig_fp_bnf_sugar; 2771 val ssig_map_transfer = map_transfer_of_bnf ssig_bnf; 2772 val old1_ssig_induct = the_single (#co_inducts old1_ssig_fp_induct_sugar); 2773 val old2_ssig_induct = the_single (#co_inducts old2_ssig_fp_induct_sugar); 2774 val ssig_induct = the_single (#co_inducts ssig_fp_induct_sugar); 2775 2776 val proto_sctr_transfer = derive_proto_sctr_transfer_step_or_merge lthy Y Z R dead_pre_rel 2777 dead_sig_rel proto_sctr proto_sctr_def [] [old1_proto_sctr_transfer]; 2778 val embLL_transfer = derive_transfer_by_transfer_prover lthy live_AsBs Rs R embLL [embLL_def] [] 2779 [old1_sig_map_transfer]; 2780 val embLR_transfer = derive_transfer_by_transfer_prover lthy live_AsBs Rs R embLR [embLR_def] [] 2781 [old2_sig_map_transfer]; 2782 val Lam_transfer = derive_Lam_or_eval_core_transfer lthy live_AsBs Y Z preT ssig_T Rs R 2783 pre_rel sig_rel ssig_rel Lam Lam_def [] 2784 [pre_map_transfer, old1_Lam_transfer, old2_Lam_transfer, embLL_transfer, embLR_transfer]; 2785 2786 val ((((((((flat, _, flat_simps), flat_transfer), 2787 ((eval_core, _, eval_core_simps), eval_core_transfer)), (eval, eval_def)), 2788 (cutSsig, cutSsig_def)), (algLam, algLam_def)), (corecU, corecU_def)), lthy) = lthy 2789 |> define_flat_etc fp_b version live_AsBs Y Z preT fpT sig_T ssig_T Oper VLeaf CLeaf pre_rel 2790 dead_pre_map dtor dtor_unfold dead_sig_map ssig_rel dead_ssig_map Lam Rs R pre_map_transfer 2791 [fp_rel_eq] sig_map_transfer ssig_map_transfer Lam_transfer dtor_transfer; 2792 2793 val (Sig_pointful_natural, flat_pointful_natural, _, Lam_pointful_natural, _, 2794 eval_core_pointful_natural, eval_thm, eval_flat, eval_simps as [eval_Oper, _, _], 2795 corecU_ctor, corecU_unique, dtor_algLam) = 2796 derive_Sig_natural_etc lthy live live_AsBs Y Z preT fpT fpT sig_T ssig_T pre_map dead_pre_map 2797 ctor dtor Sig dead_sig_map Oper VLeaf CLeaf ssig_map dead_ssig_map Lam flat eval_core eval 2798 cutSsig algLam corecU x fs f g ctor_dtor dtor_inject dtor_unfold_thm dtor_unfold_unique 2799 sig_map_thm ssig_induct ssig_map_thms Oper_map_thm VLeaf_map_thm CLeaf_map_thm Lam_transfer 2800 flat_simps flat_transfer eval_core_simps eval_core_transfer eval_def cutSsig_def algLam_def 2801 corecU_def live_pre_bnf pre_bnf dead_pre_bnf fp_bnf sig_bnf ssig_bnf dead_ssig_bnf; 2802 2803 val proto_sctr_natural = derive_natural_from_transfer_with_pre_type lthy live_AsBs Y Z preT 2804 ssig_T pre_map ssig_map fs f proto_sctr proto_sctr_transfer [pre_bnf, sig_bnf] []; 2805 val proto_sctr_pointful_natural = mk_pointful lthy proto_sctr_natural RS sym; 2806 2807 val (embLL_pointful_natural, old1_algLam_pointful, eval_embLL, algLam_algLamL) = 2808 derive_embL_natural_etc lthy Inl_const old1_ssig_bnf ssig_bnf Y Z preT fpT old1_ssig_T ssig_T 2809 dead_pre_map Sig old1_ssig_map embLL old1_algLam algLam old1_flat flat old1_eval_core 2810 eval_core old1_eval eval x f old1_ssig_induct dead_pre_map_comp0 dead_pre_map_comp fp_map_id 2811 dtor_inject dtor_unfold_unique Sig_pointful_natural unsig_thm sig_map_thm old1_sig_map_comp 2812 old1_sig_map_cong old1_ssig_map_thms old1_Lam_pointful_natural Lam_def old1_flat_simps 2813 flat_simps embLL_simps embLL_transfer old1_eval_core_simps eval_core_simps old1_eval_thm 2814 eval_thm old1_dtor_algLam dtor_algLam old1_algLam_thm; 2815 2816 val (embLR_pointful_natural, _, eval_embLR, algLam_algLamR) = 2817 derive_embL_natural_etc lthy Inr_const old2_ssig_bnf ssig_bnf Y Z preT fpT old2_ssig_T ssig_T 2818 dead_pre_map Sig old2_ssig_map embLR old2_algLam algLam old2_flat flat old2_eval_core 2819 eval_core old2_eval eval x f old2_ssig_induct dead_pre_map_comp0 dead_pre_map_comp fp_map_id 2820 dtor_inject dtor_unfold_unique Sig_pointful_natural unsig_thm sig_map_thm old2_sig_map_comp 2821 old2_sig_map_cong old2_ssig_map_thms old2_Lam_pointful_natural Lam_def old2_flat_simps 2822 flat_simps embLR_simps embLR_transfer old2_eval_core_simps eval_core_simps old2_eval_thm 2823 eval_thm old2_dtor_algLam dtor_algLam old2_algLam_thm; 2824 2825 val algLam_thm = derive_algLam_step_or_merge lthy Y fpT ctor proto_sctr algLam proto_sctr_def 2826 old1_algLam_pointful algLam_algLamL; 2827 2828 val all_algLam_algs = algLam_algLamL :: algLam_algLamR :: 2829 merge_lists (Thm.eq_thm_prop o apply2 zero_var_indexes) old1_all_algLam_algs 2830 old2_all_algLam_algs; 2831 2832 val (((corecUU, _), corecUU_thm, corecUU_unique, corecUU_transfer, _, sctr_transfer, 2833 sctr_pointful_natural), lthy) = lthy 2834 |> define_corecUU_etc fp_b version live_AsBs Y Z preT fpT ssig_T pre_map dead_pre_map pre_rel 2835 fp_rel ctor Oper ssig_map dead_ssig_map ssig_rel proto_sctr flat eval_core eval corecU fs f 2836 g Rs R pre_map_transfer [] dtor_unfold_transfer dtor_transfer ssig_map_transfer 2837 proto_sctr_transfer proto_sctr_pointful_natural flat_transfer flat_pointful_natural 2838 eval_core_transfer eval_core_pointful_natural eval_thm eval_flat eval_Oper algLam_thm 2839 cutSsig_def corecU_def corecU_ctor corecU_unique pre_bnf dead_pre_bnf fp_res ssig_fp_sugar; 2840 2841 val Retr = enforce_type lthy (domain_type o domain_type) fpT old1_Retr0; 2842 2843 val embed_Sig_inl = embed_Sig lthy Sig (Inl_const old1_sig_T old2_sig_T); 2844 val embed_Sig_inr = embed_Sig lthy Sig (Inr_const old1_sig_T old2_sig_T); 2845 2846 val ctr_wrapper = embed_Sig_inl (#ctr_wrapper old1_buffer); 2847 val friends = Symtab.merge (K true) 2848 (Symtab.map (K (apsnd embed_Sig_inl)) (#friends old1_buffer), 2849 Symtab.map (K (apsnd embed_Sig_inr)) (#friends old2_buffer)); 2850 2851 val old_fp_sugars = 2852 merge_lists (op = o apply2 (fst o dest_Type o #T)) old1_sig_fp_sugars old2_sig_fp_sugars; 2853 2854 val ((dtor_coinduct_info, all_dead_k_bnfs, friend_names), lthy) = lthy 2855 |> derive_cong_merge fp_b version fpT old1_friend_names old2_friend_names dead_ssig_bnf 2856 dead_pre_bnf eval eval_thm eval_core_transfer old1_dtor_coinduct_info 2857 old2_dtor_coinduct_info Retr equivp_Retr Retr_coinduct eval_embLL embLL_transfer eval_embLR 2858 embLR_transfer old1_all_dead_k_bnfs old2_all_dead_k_bnfs; 2859 2860 val buffer = 2861 {Oper = Oper, VLeaf = VLeaf, CLeaf = CLeaf, ctr_wrapper = ctr_wrapper, friends = friends}; 2862 2863 val notes = 2864 [(corecUU_transferN, [corecUU_transfer])] @ 2865 (if Config.get lthy bnf_internals then 2866 [(algLamN, [algLam_thm]), 2867 (algLam_algLamN, [algLam_algLamL, algLam_algLamR]), 2868 (cong_alg_introsN, #cong_alg_intros dtor_coinduct_info), 2869 (cong_localeN, [#cong_locale dtor_coinduct_info]), 2870 (corecU_ctorN, [corecU_ctor]), 2871 (corecU_uniqueN, [corecU_unique]), 2872 (corecUUN, [corecUU_thm]), 2873 (corecUU_uniqueN, [corecUU_unique]), 2874 (dtor_algLamN, [dtor_algLam]), 2875 (dtor_coinductN, [#dtor_coinduct dtor_coinduct_info]), 2876 (eval_core_pointful_naturalN, [eval_core_pointful_natural]), 2877 (eval_core_transferN, [eval_core_transfer]), 2878 (embL_pointful_naturalN, [embLL_pointful_natural, embLR_pointful_natural]), 2879 (embL_transferN, [embLL_transfer, embLR_transfer]), 2880 (evalN, [eval_thm]), 2881 (eval_flatN, [eval_flat]), 2882 (eval_simpsN, eval_simps), 2883 (flat_pointful_naturalN, [flat_pointful_natural]), 2884 (flat_transferN, [flat_transfer]), 2885 (Lam_pointful_naturalN, [Lam_pointful_natural]), 2886 (Lam_transferN, [Lam_transfer]), 2887 (proto_sctr_pointful_naturalN, [proto_sctr_pointful_natural]), 2888 (proto_sctr_transferN, [proto_sctr_transfer]), 2889 (sctr_pointful_naturalN, [sctr_pointful_natural]), 2890 (sctr_transferN, [sctr_transfer]), 2891 (Sig_pointful_naturalN, [Sig_pointful_natural])] 2892 else 2893 []) 2894 |> map (fn (thmN, thms) => 2895 ((mk_version_fp_binding true lthy version fp_b thmN, []), [(thms, [])])); 2896 in 2897 ({fp_b = fp_b, version = version, fpT = fpT, Y = Y, Z = Z, friend_names = friend_names, 2898 sig_fp_sugars = sig_fp_sugar :: old_fp_sugars, ssig_fp_sugar = ssig_fp_sugar, Lam = Lam, 2899 proto_sctr = proto_sctr, flat = flat, eval_core = eval_core, eval = eval, algLam = algLam, 2900 corecUU = corecUU, dtor_transfer = dtor_transfer, Lam_transfer = Lam_transfer, 2901 Lam_pointful_natural = Lam_pointful_natural, proto_sctr_transfer = proto_sctr_transfer, 2902 flat_simps = flat_simps, eval_core_simps = eval_core_simps, eval_thm = eval_thm, 2903 eval_simps = eval_simps, all_algLam_algs = all_algLam_algs, algLam_thm = algLam_thm, 2904 dtor_algLam = dtor_algLam, corecUU_thm = corecUU_thm, corecUU_unique = corecUU_unique, 2905 corecUU_transfer = corecUU_transfer, buffer = buffer, all_dead_k_bnfs = all_dead_k_bnfs, 2906 Retr = Retr, equivp_Retr = equivp_Retr, Retr_coinduct = Retr_coinduct, 2907 dtor_coinduct_info = dtor_coinduct_info} 2908 |> morph_corec_info (Local_Theory.target_morphism lthy), 2909 lthy |> Local_Theory.notes notes |> snd) 2910 end; 2911 2912fun set_corec_info_exprs fpT_name f = 2913 Local_Theory.declaration {syntax = false, pervasive = true} (fn phi => 2914 let val exprs = f phi in 2915 Data.map (apsnd (fn [info_tab] => [Symtab.map_default (fpT_name, exprs) (K exprs) info_tab])) 2916 end); 2917 2918fun subsume_corec_info_ad ctxt {fpT = fpT1, friend_names = friend_names1} 2919 {fpT = fpT2, friend_names = friend_names2} = 2920 Sign.typ_instance (Proof_Context.theory_of ctxt) (fpT1, fpT2) andalso 2921 subset (op =) (friend_names1, friend_names2); 2922 2923fun subsume_corec_info_expr ctxt expr1 expr2 = 2924 subsume_corec_info_ad ctxt (corec_ad_of_expr expr1) (corec_ad_of_expr expr2); 2925 2926fun instantiate_corec_info thy res_T (info as {fpT, ...}) = 2927 let 2928 val As_rho = tvar_subst thy [fpT] [res_T]; 2929 val substAT = Term.typ_subst_TVars As_rho; 2930 val substA = Term.subst_TVars As_rho; 2931 val phi = Morphism.typ_morphism "BNF" substAT $> Morphism.term_morphism "BNF" substA; 2932 in 2933 morph_corec_info phi info 2934 end; 2935 2936fun instantiate_corec_info_expr thy res_T (Ad ({friend_names, ...}, f)) = 2937 Ad ({fpT = res_T, friend_names = friend_names}, f #>> instantiate_corec_info thy res_T) 2938 | instantiate_corec_info_expr thy res_T (Info info) = 2939 Info (instantiate_corec_info thy res_T info); 2940 2941fun ensure_Info expr = corec_info_of_expr expr #>> Info 2942and ensure_Info_if_Info old_expr (expr, lthy) = 2943 if is_Info old_expr then ensure_Info expr lthy else (expr, lthy) 2944and merge_corec_info_exprs old_exprs expr1 expr2 lthy = 2945 if subsume_corec_info_expr lthy expr2 expr1 then 2946 if subsume_corec_info_expr lthy expr1 expr2 andalso is_Ad expr1 then 2947 (expr2, lthy) 2948 else 2949 ensure_Info_if_Info expr2 (expr1, lthy) 2950 else if subsume_corec_info_expr lthy expr1 expr2 then 2951 ensure_Info_if_Info expr1 (expr2, lthy) 2952 else 2953 let 2954 val thy = Proof_Context.theory_of lthy; 2955 2956 val {fpT = fpT1, friend_names = friend_names1} = corec_ad_of_expr expr1; 2957 val {fpT = fpT2, friend_names = friend_names2} = corec_ad_of_expr expr2; 2958 val fpT0 = typ_unify_disjointly thy (fpT1, fpT2); 2959 2960 val fpT = singleton (freeze_types lthy []) fpT0; 2961 val friend_names = merge_lists (op =) friend_names1 friend_names2; 2962 2963 val expr = 2964 Ad ({fpT = fpT, friend_names = friend_names}, 2965 corec_info_of_expr expr1 2966 ##>> corec_info_of_expr expr2 2967 #-> uncurry (derive_corecUU_merge fpT)); 2968 2969 val old_same_type_exprs = 2970 if old_exprs then 2971 [] 2972 |> Sign.typ_instance thy (fpT1, fpT0) ? cons expr1 2973 |> Sign.typ_instance thy (fpT2, fpT0) ? cons expr2 2974 else 2975 []; 2976 in 2977 (expr, lthy) |> fold ensure_Info_if_Info old_same_type_exprs 2978 end 2979and insert_corec_info_expr expr exprs lthy = 2980 let 2981 val thy = Proof_Context.theory_of lthy; 2982 2983 val {fpT = new_fpT, ...} = corec_ad_of_expr expr; 2984 2985 val is_Tinst = curry (Sign.typ_instance thy); 2986 fun is_Tequiv T U = is_Tinst T U andalso is_Tinst U T; 2987 2988 val (((equiv_exprs, sub_exprs), sup_exprs), incomp_exprs) = exprs 2989 |> List.partition ((fn {fpT, ...} => is_Tequiv fpT new_fpT) o corec_ad_of_expr) 2990 ||>> List.partition ((fn {fpT, ...} => is_Tinst fpT new_fpT) o corec_ad_of_expr) 2991 ||>> List.partition ((fn {fpT, ...} => is_Tinst new_fpT fpT) o corec_ad_of_expr); 2992 2993 fun add_instantiated_incomp_expr expr exprs = 2994 let val {fpT, ...} = corec_ad_of_expr expr in 2995 (case try (typ_unify_disjointly thy) (fpT, new_fpT) of 2996 SOME new_T => 2997 let val subsumes = (fn {fpT, ...} => is_Tinst new_T fpT) o corec_ad_of_expr in 2998 if exists (exists subsumes) [exprs, sub_exprs] then exprs 2999 else instantiate_corec_info_expr thy new_T expr :: exprs 3000 end 3001 | NONE => exprs) 3002 end; 3003 3004 val unincomp_exprs = fold add_instantiated_incomp_expr incomp_exprs []; 3005 val ((merged_sub_exprs, merged_unincomp_exprs), lthy) = lthy 3006 |> fold_map (merge_corec_info_exprs true expr) sub_exprs 3007 ||>> fold_map (merge_corec_info_exprs false expr) unincomp_exprs; 3008 val (merged_equiv_expr, lthy) = (expr, lthy) 3009 |> fold (uncurry o merge_corec_info_exprs true) equiv_exprs; 3010 in 3011 (merged_unincomp_exprs @ merged_sub_exprs @ merged_equiv_expr :: sup_exprs @ incomp_exprs 3012 |> sort (rev_order o int_ord o apply2 (length o #friend_names o corec_ad_of_expr)), 3013 lthy) 3014 end 3015and register_corec_info (info as {fpT = Type (fpT_name, _), ...}) lthy = 3016 let 3017 val (exprs, lthy) = insert_corec_info_expr (Info info) (corec_info_exprs_of lthy fpT_name) lthy; 3018 in 3019 lthy |> set_corec_info_exprs fpT_name (fn phi => map (morph_corec_info_expr phi) exprs) 3020 end 3021and corec_info_of_expr (Ad (_, f)) lthy = f lthy 3022 | corec_info_of_expr (Info info) lthy = (info, lthy); 3023 3024fun nonempty_corec_info_exprs_of fpT_name lthy = 3025 (case corec_info_exprs_of lthy fpT_name of 3026 [] => 3027 derive_corecUU_base fpT_name lthy 3028 |> (fn (info, lthy) => 3029 ([Info info], lthy 3030 |> set_corec_info_exprs fpT_name (fn phi => [Info (morph_corec_info phi info)]))) 3031 | exprs => (exprs, lthy)); 3032 3033fun corec_info_of res_T lthy = 3034 (case res_T of 3035 Type (fpT_name, _) => 3036 let 3037 val (exprs, lthy) = nonempty_corec_info_exprs_of fpT_name lthy; 3038 val thy = Proof_Context.theory_of lthy; 3039 val expr = 3040 (case find_first ((fn {fpT, ...} => Sign.typ_instance thy (res_T, fpT)) o corec_ad_of_expr) 3041 exprs of 3042 SOME expr => expr 3043 | NONE => error ("Invalid type: " ^ Syntax.string_of_typ lthy res_T)); 3044 val (info, lthy) = corec_info_of_expr expr lthy; 3045 in 3046 (instantiate_corec_info thy res_T info, lthy |> is_Ad expr ? register_corec_info info) 3047 end 3048 | _ => not_codatatype lthy res_T); 3049 3050fun maybe_corec_info_of ctxt res_T = 3051 (case res_T of 3052 Type (fpT_name, _) => 3053 let 3054 val thy = Proof_Context.theory_of ctxt; 3055 val infos = corec_infos_of ctxt fpT_name; 3056 in 3057 find_first (fn {fpT, ...} => Sign.typ_instance thy (res_T, fpT)) infos 3058 |> Option.map (instantiate_corec_info thy res_T) 3059 end 3060 | _ => not_codatatype ctxt res_T); 3061 3062fun prepare_friend_corec friend_name friend_T lthy = 3063 let 3064 val (arg_Ts, res_T) = strip_type friend_T; 3065 val Type (fpT_name, res_Ds) = 3066 (case res_T of 3067 T as Type _ => T 3068 | T => error (not_codatatype lthy T)); 3069 3070 val _ = not (null arg_Ts) orelse 3071 error "Function with no argument cannot be registered as friend"; 3072 3073 val {T = Type (fpT_name, fpT_args0), pre_bnf, fp_bnf = live_fp_bnf, fp_res, ...} = 3074 checked_fp_sugar_of lthy fpT_name; 3075 val num_fp_tyargs = length fpT_args0; 3076 val fpT_Ss = map Type.sort_of_atyp fpT_args0; 3077 val live_fp_alives = liveness_of_fp_bnf num_fp_tyargs live_fp_bnf; 3078 3079 val (old_info as {friend_names = old_friend_names, sig_fp_sugars = old_sig_fp_sugar :: _, 3080 buffer = old_buffer, ...}, lthy) = 3081 corec_info_of res_T lthy; 3082 val old_sig_T_name = fst (dest_Type (#T old_sig_fp_sugar)); 3083 val old_sig_alives = liveness_of_fp_bnf (num_fp_tyargs + 1) (#fp_bnf old_sig_fp_sugar); 3084 3085 (* FIXME: later *) 3086 val fp_alives = fst (split_last old_sig_alives); 3087 val fp_alives = map (K false) live_fp_alives; 3088 3089 val _ = not (member (op =) old_friend_names friend_name) orelse 3090 error ("Function " ^ quote (Syntax.string_of_term lthy (Const (friend_name, friend_T))) ^ 3091 " already registered as friend"); 3092 3093 val lthy = lthy |> Variable.declare_typ friend_T; 3094 val ((Ds, [Y, Z]), _) = lthy 3095 |> mk_TFrees' fpT_Ss 3096 ||>> mk_TFrees 2; 3097 3098 (* FIXME *) 3099 val dead_Ds = Ds; 3100 val live_As = [Y]; 3101 3102 val ctor = mk_ctor res_Ds (the_single (#ctors fp_res)); 3103 3104 val fpT0 = Type (fpT_name, Ds); 3105 val k_Ts0 = map (typ_subst_nonatomic (res_Ds ~~ Ds) o typ_subst_nonatomic [(res_T, Y)]) arg_Ts; 3106 val k_T0 = mk_tupleT_balanced k_Ts0; 3107 3108 val As = Ds @ [Y]; 3109 val res_As = res_Ds @ [Y]; 3110 3111 val k_As = fold Term.add_tfreesT k_Ts0 []; 3112 val _ = (case filter_out (member (op =) As o TFree) k_As of [] => () 3113 | k_A :: _ => error ("Cannot have type variable " ^ 3114 quote (Syntax.string_of_typ lthy (TFree k_A)) ^ 3115 " in the argument types when it does not occur as an immediate argument of the result \ 3116 \type constructor")); 3117 3118 val substDT = Term.typ_subst_atomic (Ds ~~ res_Ds); 3119 3120 val old_sig_T0 = Type (old_sig_T_name, As); 3121 3122 val ((fp_b, version), lthy) = lthy |> get_name_next_version_of fpT_name; 3123 3124 val (((dead_k_bnf, sig_fp_sugar), ssig_fp_sugar), lthy) = lthy 3125 |> bnf_with_deads_and_lives dead_Ds live_As Y fpT0 k_T0 3126 ||>> define_sig_type fp_b version fp_alives Ds Y (mk_sumT (old_sig_T0, k_T0)) 3127 ||>> define_ssig_type fp_b version fp_alives Ds Y fpT0; 3128 3129 val _ = live_of_bnf dead_k_bnf = 1 orelse 3130 error "Impossible type for friend (the result codatatype must occur live in the arguments)"; 3131 3132 val (dead_pre_bnf, lthy) = lthy 3133 |> bnf_kill_all_but 1 pre_bnf; 3134 3135 val sig_fp_ctr_sugar = #fp_ctr_sugar sig_fp_sugar; 3136 val ssig_fp_ctr_sugar = #fp_ctr_sugar ssig_fp_sugar; 3137 3138 val sig_ctr_sugar = #ctr_sugar sig_fp_ctr_sugar; 3139 val ssig_ctr_sugar = #ctr_sugar ssig_fp_ctr_sugar; 3140 3141 val ssig_T_name = fst (dest_Type (#T ssig_fp_sugar)); 3142 3143 val preT = pre_type_of_ctor Y ctor; 3144 val old_sig_T = substDT old_sig_T0; 3145 val k_T = substDT k_T0; 3146 val ssig_T = Type (ssig_T_name, res_As); 3147 3148 val Sig = mk_ctr res_As (the_single (#ctrs sig_ctr_sugar)); 3149 3150 val [Oper, VLeaf, CLeaf] = map (mk_ctr res_As) (#ctrs ssig_ctr_sugar); 3151 val (ctr_wrapper, friends) = 3152 mk_ctr_wrapper_friends lthy friend_name friend_T old_sig_T k_T Sig old_buffer; 3153 3154 val buffer = 3155 {Oper = Oper, VLeaf = VLeaf, CLeaf = CLeaf, ctr_wrapper = ctr_wrapper, friends = friends}; 3156 in 3157 ((old_info, fp_b, version, Y, Z, preT, k_T, ssig_T, dead_pre_bnf, dead_k_bnf, sig_fp_sugar, 3158 ssig_fp_sugar, buffer), lthy) 3159 end; 3160 3161fun register_friend_corec key fp_b version Y Z k_T dead_k_bnf sig_fp_sugar ssig_fp_sugar 3162 friend_const rho rho_transfer old_info lthy = 3163 let 3164 val friend_T = fastype_of friend_const; 3165 val res_T = body_type friend_T; 3166 in 3167 derive_corecUU_step res_T old_info key friend_T fp_b version Y Z k_T dead_k_bnf sig_fp_sugar 3168 ssig_fp_sugar rho rho_transfer lthy 3169 |> (fn ((info, friend_info), lthy) => (friend_info, register_corec_info info lthy)) 3170 end; 3171 3172fun merge_corec_info_exprss exprs1 exprs2 lthy = 3173 let 3174 fun all_friend_names_of exprs = 3175 fold (union (op =)) (map (#friend_names o corec_ad_of_expr) exprs) []; 3176 3177 val friend_names1 = all_friend_names_of exprs1; 3178 val friend_names2 = all_friend_names_of exprs2; 3179 in 3180 if subset (op =) (friend_names2, friend_names1) then 3181 if subset (op =) (friend_names1, friend_names2) andalso 3182 length (filter is_Info exprs2) > length (filter is_Info exprs1) then 3183 (exprs2, lthy) 3184 else 3185 (exprs1, lthy) 3186 else if subset (op =) (friend_names1, friend_names2) then 3187 (exprs2, lthy) 3188 else 3189 fold_rev (uncurry o insert_corec_info_expr) exprs2 (exprs1, lthy) 3190 end; 3191 3192fun merge_corec_info_tabs info_tab1 info_tab2 lthy = 3193 let 3194 val fpT_names = union (op =) (Symtab.keys info_tab1) (Symtab.keys info_tab2); 3195 3196 fun add_infos_of fpT_name (info_tab, lthy) = 3197 (case Symtab.lookup info_tab1 fpT_name of 3198 NONE => 3199 (Symtab.update_new (fpT_name, the (Symtab.lookup info_tab2 fpT_name)) info_tab, lthy) 3200 | SOME exprs1 => 3201 (case Symtab.lookup info_tab2 fpT_name of 3202 NONE => (Symtab.update_new (fpT_name, exprs1) info_tab, lthy) 3203 | SOME exprs2 => 3204 let val (exprs, lthy) = merge_corec_info_exprss exprs1 exprs2 lthy in 3205 (Symtab.update_new (fpT_name, exprs) info_tab, lthy) 3206 end)); 3207 in 3208 fold add_infos_of fpT_names (Symtab.empty, lthy) 3209 end; 3210 3211fun consolidate lthy = 3212 (case snd (Data.get (Context.Proof lthy)) of 3213 [_] => raise Same.SAME 3214 | info_tab :: info_tabs => 3215 let 3216 val (info_tab', lthy) = fold_rev (uncurry o merge_corec_info_tabs) info_tabs (info_tab, lthy); 3217 in 3218 Local_Theory.declaration {syntax = false, pervasive = true} (fn phi => 3219 Data.map (apsnd (fn _ => [Symtab.map (K (map (morph_corec_info_expr phi))) info_tab']))) 3220 lthy 3221 end); 3222 3223fun consolidate_global thy = 3224 SOME (Named_Target.theory_map consolidate thy) 3225 handle Same.SAME => NONE; 3226 3227val _ = Theory.setup (Theory.at_begin consolidate_global); 3228 3229end; 3230