src/HOL/Codatatype/Tools/bnf_fp_sugar.ML
changeset 49367 a1e811aa0fb8
parent 49366 3edd1c90f6e6
child 49368 df359ce891ac
equal deleted inserted replaced
49366:3edd1c90f6e6 49367:a1e811aa0fb8
    89     (* TODO: sanity checks on arguments *)
    89     (* TODO: sanity checks on arguments *)
    90 
    90 
    91     val _ = if not lfp andalso no_dests then error "Cannot define destructor-less codatatypes"
    91     val _ = if not lfp andalso no_dests then error "Cannot define destructor-less codatatypes"
    92       else ();
    92       else ();
    93 
    93 
    94     val N = length specs;
    94     val nn = length specs;
    95     val fp_bs = map type_binding_of specs;
    95     val fp_bs = map type_binding_of specs;
    96     val fp_common_name = mk_common_name fp_bs;
    96     val fp_common_name = mk_common_name fp_bs;
    97 
    97 
    98     fun prepare_type_arg (ty, c) =
    98     fun prepare_type_arg (ty, c) =
    99       let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in
    99       let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in
   105     val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0;
   105     val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0;
   106 
   106 
   107     val (((Bs, Cs), vs'), no_defs_lthy) =
   107     val (((Bs, Cs), vs'), no_defs_lthy) =
   108       no_defs_lthy0
   108       no_defs_lthy0
   109       |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As
   109       |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As
   110       |> mk_TFrees N
   110       |> mk_TFrees nn
   111       ||>> mk_TFrees N
   111       ||>> mk_TFrees nn
   112       ||>> Variable.variant_fixes (map Binding.name_of fp_bs);
   112       ||>> Variable.variant_fixes (map Binding.name_of fp_bs);
   113 
   113 
   114     (* TODO: cleaner handling of fake contexts, without "background_theory" *)
   114     (* TODO: cleaner handling of fake contexts, without "background_theory" *)
   115     (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a
   115     (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a
   116       locale and shadows an existing global type*)
   116       locale and shadows an existing global type*)
   566                     end)
   566                     end)
   567                 | i => [HOLogic.mk_Trueprop (nth phis i $ x)])
   567                 | i => [HOLogic.mk_Trueprop (nth phis i $ x)])
   568               | mk_prem_prems _ _ = [];
   568               | mk_prem_prems _ _ = [];
   569 
   569 
   570             fun close_prem_prem (Free x') t =
   570             fun close_prem_prem (Free x') t =
   571               fold_rev Logic.all (map Free (drop (N + 1) (rev (Term.add_frees t (x' :: phis'))))) t;
   571               fold_rev Logic.all
       
   572                 (map Free (drop (nn + 1) (rev (Term.add_frees t (x' :: phis'))))) t;
   572 
   573 
   573             fun mk_prem phi ctr ctr_Ts =
   574             fun mk_prem phi ctr ctr_Ts =
   574               let
   575               let
   575                 val (xs, names_lthy') = names_lthy |> mk_Frees "x" ctr_Ts;
   576                 val (xs, names_lthy') = names_lthy |> mk_Frees "x" ctr_Ts;
   576                 val prem_prems =
   577                 val prem_prems =
   589 
   590 
   590             val induct_thm =
   591             val induct_thm =
   591               Skip_Proof.prove lthy [] [] goal (fn {context = ctxt, ...} =>
   592               Skip_Proof.prove lthy [] [] goal (fn {context = ctxt, ...} =>
   592                 mk_induct_tac ctxt);
   593                 mk_induct_tac ctxt);
   593           in
   594           in
   594             `(conj_dests N) induct_thm
   595             `(conj_dests nn) induct_thm
   595           end;
   596           end;
   596 
   597 
   597         val (iter_thmss, rec_thmss) =
   598         val (iter_thmss, rec_thmss) =
   598           let
   599           let
   599             val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss;
   600             val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss;
   641              map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context)))
   642              map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context)))
   642                goal_recss rec_tacss)
   643                goal_recss rec_tacss)
   643           end;
   644           end;
   644 
   645 
   645         val common_notes =
   646         val common_notes =
   646           (if N > 1 then [(inductN, [induct_thm], [])] (* FIXME: attribs *) else [])
   647           (if nn > 1 then [(inductN, [induct_thm], [])] (* FIXME: attribs *) else [])
   647           |> map (fn (thmN, thms, attrs) =>
   648           |> map (fn (thmN, thms, attrs) =>
   648               ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])]));
   649               ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])]));
   649 
   650 
   650         val notes =
   651         val notes =
   651           [(inductN, map single induct_thms, []), (* FIXME: attribs *)
   652           [(inductN, map single induct_thms, []), (* FIXME: attribs *)
   664       let
   665       let
   665         val (coinduct_thms, coinduct_thm) =
   666         val (coinduct_thms, coinduct_thm) =
   666           let
   667           let
   667             val coinduct_thm = fp_induct;
   668             val coinduct_thm = fp_induct;
   668           in
   669           in
   669             `(conj_dests N) coinduct_thm
   670             `(conj_dests nn) coinduct_thm
   670           end;
   671           end;
   671 
   672 
   672         val (coiter_thmss, corec_thmss) =
   673         val (coiter_thmss, corec_thmss) =
   673           let
   674           let
   674             val z = the_single zs;
   675             val z = the_single zs;
   747           map3 (map3 (map2 o mk_sel_coiter_like_thm)) coiter_thmss selsss sel_thmsss;
   748           map3 (map3 (map2 o mk_sel_coiter_like_thm)) coiter_thmss selsss sel_thmsss;
   748         val sel_corec_thmsss =
   749         val sel_corec_thmsss =
   749           map3 (map3 (map2 o mk_sel_coiter_like_thm)) corec_thmss selsss sel_thmsss;
   750           map3 (map3 (map2 o mk_sel_coiter_like_thm)) corec_thmss selsss sel_thmsss;
   750 
   751 
   751         val common_notes =
   752         val common_notes =
   752           (if N > 1 then [(coinductN, [coinduct_thm], [])] (* FIXME: attribs *) else [])
   753           (if nn > 1 then [(coinductN, [coinduct_thm], [])] (* FIXME: attribs *) else [])
   753           |> map (fn (thmN, thms, attrs) =>
   754           |> map (fn (thmN, thms, attrs) =>
   754               ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])]));
   755               ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])]));
   755 
   756 
   756         val notes =
   757         val notes =
   757           [(coinductN, map single coinduct_thms, []), (* FIXME: attribs *)
   758           [(coinductN, map single coinduct_thms, []), (* FIXME: attribs *)