src/HOL/BNF/Tools/bnf_fp_def_sugar.ML
changeset 51758 55963309557b
parent 51757 7babcb61aa5c
child 51766 f19a4d0ab1bf
equal deleted inserted replaced
51757:7babcb61aa5c 51758:55963309557b
     6 *)
     6 *)
     7 
     7 
     8 signature BNF_FP_DEF_SUGAR =
     8 signature BNF_FP_DEF_SUGAR =
     9 sig
     9 sig
    10   val datatypes: bool ->
    10   val datatypes: bool ->
    11     (mixfix list -> (string * sort) list option -> binding list -> binding list list ->
    11     (mixfix list -> (string * sort) list option -> binding list -> binding list ->
    12       typ list * typ list list -> BNF_Def.BNF list -> local_theory ->
    12       binding list list -> typ list * typ list list -> BNF_Def.BNF list -> local_theory ->
    13       BNF_FP.fp_result * local_theory) ->
    13       BNF_FP.fp_result * local_theory) ->
    14     (bool * bool) * (((((binding * typ) * sort) list * binding) * mixfix) * ((((binding * binding) *
    14     (bool * bool) * ((((binding * (binding * (typ * sort)) list) * binding) * mixfix) *
    15       (binding * typ) list) * (binding * term) list) * mixfix) list) list ->
    15       ((((binding * binding) * (binding * typ) list) * (binding * term) list) *
       
    16         mixfix) list) list ->
    16     local_theory -> local_theory
    17     local_theory -> local_theory
    17   val parse_datatype_cmd: bool ->
    18   val parse_datatype_cmd: bool ->
    18     (mixfix list -> (string * sort) list option -> binding list -> binding list list ->
    19     (mixfix list -> (string * sort) list option -> binding list -> binding list ->
    19       typ list * typ list list -> BNF_Def.BNF list -> local_theory ->
    20       binding list list -> typ list * typ list list -> BNF_Def.BNF list -> local_theory ->
    20       BNF_FP.fp_result * local_theory) ->
    21       BNF_FP.fp_result * local_theory) ->
    21     (local_theory -> local_theory) parser
    22     (local_theory -> local_theory) parser
    22 end;
    23 end;
    23 
    24 
    24 structure BNF_FP_Def_Sugar : BNF_FP_DEF_SUGAR =
    25 structure BNF_FP_Def_Sugar : BNF_FP_DEF_SUGAR =
   127 
   128 
   128 fun reassoc_conjs thm =
   129 fun reassoc_conjs thm =
   129   reassoc_conjs (thm RS @{thm conj_assoc[THEN iffD1]})
   130   reassoc_conjs (thm RS @{thm conj_assoc[THEN iffD1]})
   130   handle THM _ => thm;
   131   handle THM _ => thm;
   131 
   132 
   132 fun type_args_constrained_of (((cAs, _), _), _) = cAs;
   133 fun map_binding_of ((((b, _), _), _), _) = b;
       
   134 fun type_args_named_constrained_of ((((_, ncAs), _), _), _) = ncAs;
   133 fun type_binding_of (((_, b), _), _) = b;
   135 fun type_binding_of (((_, b), _), _) = b;
   134 fun mixfix_of ((_, mx), _) = mx;
   136 fun mixfix_of ((_, mx), _) = mx;
   135 fun ctr_specs_of (_, ctr_specs) = ctr_specs;
   137 fun ctr_specs_of (_, ctr_specs) = ctr_specs;
   136 
   138 
   137 fun disc_of ((((disc, _), _), _), _) = disc;
   139 fun disc_of ((((disc, _), _), _), _) = disc;
   154 
   156 
   155     val nn = length specs;
   157     val nn = length specs;
   156     val fp_bs = map type_binding_of specs;
   158     val fp_bs = map type_binding_of specs;
   157     val fp_b_names = map Binding.name_of fp_bs;
   159     val fp_b_names = map Binding.name_of fp_bs;
   158     val fp_common_name = mk_common_name fp_b_names;
   160     val fp_common_name = mk_common_name fp_b_names;
   159 
   161     val map_bs = map map_binding_of specs;
   160     fun prepare_type_arg ((_, ty), c) =
   162 
       
   163     fun prepare_type_arg (_, (ty, c)) =
   161       let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in
   164       let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in
   162         TFree (s, prepare_constraint no_defs_lthy0 c)
   165         TFree (s, prepare_constraint no_defs_lthy0 c)
   163       end;
   166       end;
   164 
   167 
   165     val Ass0 = map (map prepare_type_arg o type_args_constrained_of) specs;
   168     val Ass0 = map (map prepare_type_arg o type_args_named_constrained_of) specs;
   166     val unsorted_Ass0 = map (map (resort_tfree HOLogic.typeS)) Ass0;
   169     val unsorted_Ass0 = map (map (resort_tfree HOLogic.typeS)) Ass0;
   167     val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0;
   170     val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0;
   168     val set_bss = map (map (fst o fst) o type_args_constrained_of) specs;
   171     val set_bss = map (map fst o type_args_named_constrained_of) specs;
   169 
   172 
   170     val (((Bs0, Cs), Xs), no_defs_lthy) =
   173     val (((Bs0, Cs), Xs), no_defs_lthy) =
   171       no_defs_lthy0
   174       no_defs_lthy0
   172       |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As
   175       |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As
   173       |> mk_TFrees (length unsorted_As)
   176       |> mk_TFrees (length unsorted_As)
   178     (* TODO: cleaner handling of fake contexts, without "background_theory" *)
   181     (* TODO: cleaner handling of fake contexts, without "background_theory" *)
   179     (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a
   182     (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a
   180       locale and shadows an existing global type*)
   183       locale and shadows an existing global type*)
   181     val fake_thy =
   184     val fake_thy =
   182       Theory.copy #> fold (fn spec => perhaps (try (Sign.add_type no_defs_lthy
   185       Theory.copy #> fold (fn spec => perhaps (try (Sign.add_type no_defs_lthy
   183         (type_binding_of spec, length (type_args_constrained_of spec), mixfix_of spec)))) specs;
   186           (type_binding_of spec, length (type_args_named_constrained_of spec), mixfix_of spec))))
       
   187         specs;
   184     val fake_lthy = Proof_Context.background_theory fake_thy no_defs_lthy;
   188     val fake_lthy = Proof_Context.background_theory fake_thy no_defs_lthy;
   185 
   189 
   186     fun mk_fake_T b =
   190     fun mk_fake_T b =
   187       Type (fst (Term.dest_Type (Proof_Context.read_type_name fake_lthy true (Binding.name_of b))),
   191       Type (fst (Term.dest_Type (Proof_Context.read_type_name fake_lthy true (Binding.name_of b))),
   188         unsorted_As);
   192         unsorted_As);
   238 
   242 
   239     (* TODO: clean up list *)
   243     (* TODO: clean up list *)
   240     val (pre_bnfs, ((fp_bnfs as any_fp_bnf :: _, dtors0, ctors0, fp_folds0, fp_recs0, fp_induct,
   244     val (pre_bnfs, ((fp_bnfs as any_fp_bnf :: _, dtors0, ctors0, fp_folds0, fp_recs0, fp_induct,
   241            fp_strong_induct, dtor_ctors, ctor_dtors, ctor_injects, fp_map_thms, fp_set_thmss,
   245            fp_strong_induct, dtor_ctors, ctor_dtors, ctor_injects, fp_map_thms, fp_set_thmss,
   242            fp_rel_thms, fp_fold_thms, fp_rec_thms), lthy)) =
   246            fp_rel_thms, fp_fold_thms, fp_rec_thms), lthy)) =
   243       fp_bnf construct_fp fp_bs mixfixes set_bss (map dest_TFree unsorted_As) fp_eqs no_defs_lthy0;
   247       fp_bnf construct_fp fp_bs mixfixes map_bs set_bss (map dest_TFree unsorted_As) fp_eqs
       
   248         no_defs_lthy0;
   244 
   249 
   245     val timer = time (Timer.startRealTimer ());
   250     val timer = time (Timer.startRealTimer ());
   246 
   251 
   247     fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) =
   252     fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) =
   248       let
   253       let
  1179   (Parse.typ >> pair Binding.empty);
  1184   (Parse.typ >> pair Binding.empty);
  1180 
  1185 
  1181 val parse_defaults =
  1186 val parse_defaults =
  1182   @{keyword "("} |-- @{keyword "defaults"} |-- Scan.repeat parse_bound_term --| @{keyword ")"};
  1187   @{keyword "("} |-- @{keyword "defaults"} |-- Scan.repeat parse_bound_term --| @{keyword ")"};
  1183 
  1188 
  1184 (* Identical to unexported function of the same name in "Pure/Isar/parse.ML" *)
  1189 val parse_type_arg_constrained =
  1185 fun parse_type_arguments arg =
  1190   Parse.type_ident -- Scan.option (@{keyword "::"} |-- Parse.!!! Parse.sort)
  1186   arg >> single || @{keyword "("} |-- Parse.!!! (Parse.list1 arg --| @{keyword ")"}) ||
  1191 
       
  1192 val parse_type_arg_named_constrained = parse_opt_binding_colon -- parse_type_arg_constrained
       
  1193 
       
  1194 val parse_type_args_named_constrained =
       
  1195   parse_type_arg_constrained >> (single o pair Binding.empty) ||
       
  1196   @{keyword "("} |-- Parse.!!! (Parse.list1 parse_type_arg_named_constrained --| @{keyword ")"}) ||
  1187   Scan.succeed [];
  1197   Scan.succeed [];
  1188 
  1198 
  1189 val parse_type_arg_constrained =
       
  1190   parse_opt_binding_colon -- Parse.type_ident --
       
  1191   Scan.option (@{keyword "::"} |-- Parse.!!! Parse.sort)
       
  1192 
       
  1193 val parse_type_args_constrained = parse_type_arguments parse_type_arg_constrained;
       
  1194 
       
  1195 val parse_single_spec =
  1199 val parse_single_spec =
  1196   parse_type_args_constrained -- Parse.binding -- Parse.opt_mixfix --
  1200   parse_opt_binding_colon -- parse_type_args_named_constrained -- Parse.binding --
  1197   (@{keyword "="} |-- Parse.enum1 "|" (parse_opt_binding_colon -- Parse.binding --
  1201   Parse.opt_mixfix -- (@{keyword "="} |-- Parse.enum1 "|" (parse_opt_binding_colon --
  1198     Scan.repeat parse_ctr_arg -- Scan.optional parse_defaults [] -- Parse.opt_mixfix));
  1202       Parse.binding -- Scan.repeat parse_ctr_arg -- Scan.optional parse_defaults [] --
       
  1203     Parse.opt_mixfix));
  1199 
  1204 
  1200 val parse_datatype = parse_wrap_options -- Parse.and_list1 parse_single_spec;
  1205 val parse_datatype = parse_wrap_options -- Parse.and_list1 parse_single_spec;
  1201 
  1206 
  1202 fun parse_datatype_cmd lfp construct_fp = parse_datatype >> datatype_cmd lfp construct_fp;
  1207 fun parse_datatype_cmd lfp construct_fp = parse_datatype >> datatype_cmd lfp construct_fp;
  1203 
  1208