src/HOL/Tools/datatype_codegen.ML
changeset 22778 a5b87573f427
parent 22746 f090ecd44f12
child 22921 475ff421a6a3
equal deleted inserted replaced
22777:2fc921376a86 22778:a5b87573f427
    63         (max (map (arg_nonempty o DatatypeAux.strip_dtyp) dts))) constrs)
    63         (max (map (arg_nonempty o DatatypeAux.strip_dtyp) dts))) constrs)
    64   in case xs of [] => NONE | x :: _ => SOME x end;
    64   in case xs of [] => NONE | x :: _ => SOME x end;
    65 
    65 
    66 fun add_dt_defs thy defs dep module gr (descr: DatatypeAux.descr) =
    66 fun add_dt_defs thy defs dep module gr (descr: DatatypeAux.descr) =
    67   let
    67   let
    68     val tab = DatatypePackage.get_datatypes thy;
       
    69 
       
    70     val descr' = List.filter (can (map DatatypeAux.dest_DtTFree o #2 o snd)) descr;
    68     val descr' = List.filter (can (map DatatypeAux.dest_DtTFree o #2 o snd)) descr;
    71     val rtnames = map (#1 o snd) (List.filter (fn (_, (_, _, cs)) =>
    69     val rtnames = map (#1 o snd) (List.filter (fn (_, (_, _, cs)) =>
    72       exists (exists DatatypeAux.is_rec_type o snd) cs) descr');
    70       exists (exists DatatypeAux.is_rec_type o snd) cs) descr');
    73 
    71 
    74     val (_, (tname, _, _)) :: _ = descr';
    72     val (_, (tname, _, _)) :: _ = descr';
   283 
   281 
   284 (**** code generators for terms and types ****)
   282 (**** code generators for terms and types ****)
   285 
   283 
   286 fun datatype_codegen thy defs gr dep module brack t = (case strip_comb t of
   284 fun datatype_codegen thy defs gr dep module brack t = (case strip_comb t of
   287    (c as Const (s, T), ts) =>
   285    (c as Const (s, T), ts) =>
   288        (case Library.find_first (fn (_, {index, descr, case_name, ...}) =>
   286      (case DatatypePackage.datatype_of_case thy s of
   289          s = case_name orelse
   287         SOME {index, descr, ...} =>
   290            AList.defined (op =) ((#3 o the o AList.lookup (op =) descr) index) s)
   288           if is_some (get_assoc_code thy s T) then NONE else
   291              (Symtab.dest (DatatypePackage.get_datatypes thy)) of
   289           SOME (pretty_case thy defs gr dep module brack
   292           NONE => NONE
   290             (#3 (the (AList.lookup op = descr index))) c ts)
   293         | SOME (tname, {index, descr, ...}) =>
   291       | NONE => case (DatatypePackage.datatype_of_constr thy s, strip_type T) of
   294            if is_some (get_assoc_code thy s T) then NONE else
   292         (SOME {index, descr, ...}, (_, U as Type _)) =>
   295            let val SOME (_, _, constrs) = AList.lookup (op =) descr index
   293           if is_some (get_assoc_code thy s T) then NONE else
   296            in (case (AList.lookup (op =) constrs s, strip_type T) of
   294           let val SOME args = AList.lookup op =
   297                (NONE, _) => SOME (pretty_case thy defs gr dep module brack
   295             (#3 (the (AList.lookup op = descr index))) s
   298                  ((#3 o the o AList.lookup (op =) descr) index) c ts)
   296           in
   299              | (SOME args, (_, Type _)) => SOME (pretty_constr thy defs
   297             SOME (pretty_constr thy defs
   300                  (fst (invoke_tycodegen thy defs dep module false
   298               (fst (invoke_tycodegen thy defs dep module false (gr, U)))
   301                     (gr, snd (strip_type T))))
   299               dep module brack args c ts)
   302                  dep module brack args c ts)
   300           end
   303              | _ => NONE)
   301       | _ => NONE)
   304            end)
   302  | _ => NONE);
   305  |  _ => NONE);
       
   306 
   303 
   307 fun datatype_tycodegen thy defs gr dep module brack (Type (s, Ts)) =
   304 fun datatype_tycodegen thy defs gr dep module brack (Type (s, Ts)) =
   308       (case Symtab.lookup (DatatypePackage.get_datatypes thy) s of
   305       (case DatatypePackage.get_datatype thy s of
   309          NONE => NONE
   306          NONE => NONE
   310        | SOME {descr, ...} =>
   307        | SOME {descr, ...} =>
   311            if isSome (get_assoc_type thy s) then NONE else
   308            if isSome (get_assoc_type thy s) then NONE else
   312            let
   309            let
   313              val (gr', ps) = foldl_map
   310              val (gr', ps) = foldl_map
   323 
   320 
   324 
   321 
   325 (** datatypes for code 2nd generation **)
   322 (** datatypes for code 2nd generation **)
   326 
   323 
   327 fun dtyp_of_case_const thy c =
   324 fun dtyp_of_case_const thy c =
   328   get_first (fn (dtco, { case_name, ... }) => if case_name = c then SOME dtco else NONE)
   325   Option.map (fn {descr, index, ...} => #1 (the (AList.lookup op = descr index)))
   329     ((Symtab.dest o DatatypePackage.get_datatypes) thy);
   326     (DatatypePackage.datatype_of_case thy c);
   330 
   327 
   331 fun dest_case_app cs ts tys =
   328 fun dest_case_app cs ts tys =
   332   let
   329   let
   333     val names = (Name.make_context o map fst) (fold Term.add_tfrees ts []);
   330     val names = (Name.make_context o map fst) (fold Term.add_tfrees ts []);
   334     val abs = Name.names names "a" (Library.drop (length ts, tys));
   331     val abs = Name.names names "a" (Library.drop (length ts, tys));