src/HOL/Tools/Datatype/datatype.ML
changeset 32907 0300f8dd63ea
parent 32904 9d27ebc82700
child 32911 5f7386f7cbe6
equal deleted inserted replaced
32906:ac97e8735cc2 32907:0300f8dd63ea
   319     weak_case_cong = weak_case_cong,
   319     weak_case_cong = weak_case_cong,
   320     split = split,
   320     split = split,
   321     split_asm = split_asm});
   321     split_asm = split_asm});
   322 
   322 
   323 fun derive_datatype_props config dt_names alt_names descr sorts
   323 fun derive_datatype_props config dt_names alt_names descr sorts
   324     induct inject (distinct_rules, distinct_rewrites) thy1 =
   324     induct inject distinct thy1 =
   325   let
   325   let
   326     val thy2 = thy1 |> Theory.checkpoint;
   326     val thy2 = thy1 |> Theory.checkpoint;
   327     val flat_descr = flat descr;
   327     val flat_descr = flat descr;
   328     val new_type_names = map Long_Name.base_name (the_default dt_names alt_names);
   328     val new_type_names = map Long_Name.base_name (the_default dt_names alt_names);
   329     val _ = message config ("Deriving properties for datatype(s) " ^ commas_quote new_type_names);
   329     val _ = message config ("Deriving properties for datatype(s) " ^ commas_quote new_type_names);
   332       descr sorts induct (mk_case_names_exhausts flat_descr dt_names) thy2;
   332       descr sorts induct (mk_case_names_exhausts flat_descr dt_names) thy2;
   333     val (nchotomys, thy4) = DatatypeAbsProofs.prove_nchotomys config new_type_names
   333     val (nchotomys, thy4) = DatatypeAbsProofs.prove_nchotomys config new_type_names
   334       descr sorts exhaust thy3;
   334       descr sorts exhaust thy3;
   335     val ((rec_names, rec_rewrites), thy5) = DatatypeAbsProofs.prove_primrec_thms
   335     val ((rec_names, rec_rewrites), thy5) = DatatypeAbsProofs.prove_primrec_thms
   336       config new_type_names descr sorts (#inject o the o Symtab.lookup (get_all thy4))
   336       config new_type_names descr sorts (#inject o the o Symtab.lookup (get_all thy4))
   337       inject distinct_rewrites (Simplifier.theory_context thy4 dist_ss) induct thy4;
   337       inject distinct (Simplifier.theory_context thy4 dist_ss) induct thy4;
   338     val ((case_rewrites, case_names), thy6) = DatatypeAbsProofs.prove_case_thms
   338     val ((case_rewrites, case_names), thy6) = DatatypeAbsProofs.prove_case_thms
   339       config new_type_names descr sorts rec_names rec_rewrites thy5;
   339       config new_type_names descr sorts rec_names rec_rewrites thy5;
   340     val (case_congs, thy7) = DatatypeAbsProofs.prove_case_congs new_type_names
   340     val (case_congs, thy7) = DatatypeAbsProofs.prove_case_congs new_type_names
   341       descr sorts nchotomys case_rewrites thy6;
   341       descr sorts nchotomys case_rewrites thy6;
   342     val (weak_case_congs, thy8) = DatatypeAbsProofs.prove_weak_case_congs new_type_names
   342     val (weak_case_congs, thy8) = DatatypeAbsProofs.prove_weak_case_congs new_type_names
   343       descr sorts thy7;
   343       descr sorts thy7;
   344     val (splits, thy9) = DatatypeAbsProofs.prove_split_thms
   344     val (splits, thy9) = DatatypeAbsProofs.prove_split_thms
   345       config new_type_names descr sorts inject distinct_rewrites exhaust case_rewrites thy8;
   345       config new_type_names descr sorts inject distinct exhaust case_rewrites thy8;
   346 
   346 
   347     val inducts = Project_Rule.projections (ProofContext.init thy2) induct;
   347     val inducts = Project_Rule.projections (ProofContext.init thy2) induct;
   348     val dt_infos = map_index (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites)
   348     val dt_infos = map_index (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites)
   349       (hd descr ~~ inject ~~ distinct_rules ~~ exhaust ~~ nchotomys ~~
   349       (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~
   350         case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits);
   350         case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits);
   351     val dt_names = map fst dt_infos;
   351     val dt_names = map fst dt_infos;
   352     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   352     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   353     val simps = flat (inject @ distinct_rules @ case_rewrites) @ rec_rewrites;
   353     val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites;
   354     val named_rules = flat (map_index (fn (index, tname) =>
   354     val named_rules = flat (map_index (fn (index, tname) =>
   355       [((Binding.empty, [nth inducts index]), [Induct.induct_type tname]),
   355       [((Binding.empty, [nth inducts index]), [Induct.induct_type tname]),
   356        ((Binding.empty, [nth exhaust index]), [Induct.cases_type tname])]) dt_names);
   356        ((Binding.empty, [nth exhaust index]), [Induct.cases_type tname])]) dt_names);
   357     val unnamed_rules = map (fn induct =>
   357     val unnamed_rules = map (fn induct =>
   358       ((Binding.empty, [induct]), [Thm.kind_internal, Induct.induct_type ""]))
   358       ((Binding.empty, [induct]), [Thm.kind_internal, Induct.induct_type ""]))
   360   in
   360   in
   361     thy9
   361     thy9
   362     |> PureThy.add_thmss ([((prfx (Binding.name "simps"), simps), []),
   362     |> PureThy.add_thmss ([((prfx (Binding.name "simps"), simps), []),
   363         ((prfx (Binding.name "inducts"), inducts), []),
   363         ((prfx (Binding.name "inducts"), inducts), []),
   364         ((prfx (Binding.name "splits"), maps (fn (x, y) => [x, y]) splits), []),
   364         ((prfx (Binding.name "splits"), maps (fn (x, y) => [x, y]) splits), []),
   365         ((Binding.empty, flat case_rewrites @ flat distinct_rules @ rec_rewrites),
   365         ((Binding.empty, flat case_rewrites @ flat distinct @ rec_rewrites),
   366           [Simplifier.simp_add]),
   366           [Simplifier.simp_add]),
   367         ((Binding.empty, rec_rewrites), [Code.add_default_eqn_attribute]),
   367         ((Binding.empty, rec_rewrites), [Code.add_default_eqn_attribute]),
   368         ((Binding.empty, flat inject), [iff_add]),
   368         ((Binding.empty, flat inject), [iff_add]),
   369         ((Binding.empty, map (fn th => th RS notE) (flat distinct_rules)),
   369         ((Binding.empty, map (fn th => th RS notE) (flat distinct)),
   370           [Classical.safe_elim NONE]),
   370           [Classical.safe_elim NONE]),
   371         ((Binding.empty, weak_case_congs), [Simplifier.attrib (op addcongs)])]
   371         ((Binding.empty, weak_case_congs), [Simplifier.attrib (op addcongs)])]
   372         @ named_rules @ unnamed_rules)
   372         @ named_rules @ unnamed_rules)
   373     |> snd
   373     |> snd
   374     |> add_case_tr' case_names
   374     |> add_case_tr' case_names
   392       ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])]
   392       ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])]
   393       ||> Sign.restore_naming thy1;
   393       ||> Sign.restore_naming thy1;
   394   in
   394   in
   395     thy2
   395     thy2
   396     |> derive_datatype_props config dt_names alt_names [descr] sorts
   396     |> derive_datatype_props config dt_names alt_names [descr] sorts
   397          induct inject (distinct, distinct)
   397          induct inject distinct
   398  end;
   398  end;
   399 
   399 
   400 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy =
   400 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy =
   401   let
   401   let
   402     fun constr_of_term (Const (c, T)) = (c, T)
   402     fun constr_of_term (Const (c, T)) = (c, T)
   529     val _ = check_nonempty descr handle (exn as Datatype_Empty s) =>
   529     val _ = check_nonempty descr handle (exn as Datatype_Empty s) =>
   530       if #strict config then error ("Nonemptiness check failed for datatype " ^ s)
   530       if #strict config then error ("Nonemptiness check failed for datatype " ^ s)
   531       else raise exn;
   531       else raise exn;
   532 
   532 
   533     val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names);
   533     val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names);
   534     val ((inject, (distinct_rules, distinct_rewrites), induct), thy') = thy |>
   534     val ((inject, distinct, induct), thy') = thy |>
   535       DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts
   535       DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts
   536         types_syntax constr_syntax (mk_case_names_induct (flat descr));
   536         types_syntax constr_syntax (mk_case_names_induct (flat descr));
   537   in
   537   in
   538     derive_datatype_props config dt_names (SOME new_type_names) descr sorts
   538     derive_datatype_props config dt_names (SOME new_type_names) descr sorts
   539       induct inject (distinct_rules, distinct_rewrites) thy'
   539       induct inject distinct thy'
   540   end;
   540   end;
   541 
   541 
   542 val add_datatype = gen_add_datatype cert_typ;
   542 val add_datatype = gen_add_datatype cert_typ;
   543 val datatype_cmd = snd ooo gen_add_datatype read_typ default_config;
   543 val datatype_cmd = snd ooo gen_add_datatype read_typ default_config;
   544 
   544