src/HOL/Tools/inductive_codegen.ML
changeset 18728 6790126ab5f6
parent 18708 4b3dadb4fe33
child 18928 042608ffa2ec
equal deleted inserted replaced
18727:caf9bc780c80 18728:6790126ab5f6
     5 Code generator for inductive predicates.
     5 Code generator for inductive predicates.
     6 *)
     6 *)
     7 
     7 
     8 signature INDUCTIVE_CODEGEN =
     8 signature INDUCTIVE_CODEGEN =
     9 sig
     9 sig
    10   val add : string option -> theory attribute
    10   val add : string option -> attribute
    11   val setup : theory -> theory
    11   val setup : theory -> theory
    12 end;
    12 end;
    13 
    13 
    14 structure InductiveCodegen : INDUCTIVE_CODEGEN =
    14 structure InductiveCodegen : INDUCTIVE_CODEGEN =
    15 struct
    15 struct
    43 fun warn thm = warning ("InductiveCodegen: Not a proper clause:\n" ^
    43 fun warn thm = warning ("InductiveCodegen: Not a proper clause:\n" ^
    44   string_of_thm thm);
    44   string_of_thm thm);
    45 
    45 
    46 fun add_node (g, x) = Graph.new_node (x, ()) g handle Graph.DUP _ => g;
    46 fun add_node (g, x) = Graph.new_node (x, ()) g handle Graph.DUP _ => g;
    47 
    47 
    48 fun add optmod (p as (thy, thm)) =
    48 fun add optmod = Thm.declaration_attribute (fn thm => Context.map_theory (fn thy =>
    49   let
    49   let
    50     val {intros, graph, eqns} = CodegenData.get thy;
    50     val {intros, graph, eqns} = CodegenData.get thy;
    51     fun thyname_of s = (case optmod of
    51     fun thyname_of s = (case optmod of
    52       NONE => thyname_of_const s thy | SOME s => s);
    52       NONE => thyname_of_const s thy | SOME s => s);
    53   in (case concl_of thm of
    53   in (case concl_of thm of
    54       _ $ (Const ("op :", _) $ _ $ t) => (case head_of t of
    54       _ $ (Const ("op :", _) $ _ $ t) => (case head_of t of
    55         Const (s, _) =>
    55         Const (s, _) =>
    56           let val cs = foldr add_term_consts [] (prems_of thm)
    56           let val cs = foldr add_term_consts [] (prems_of thm)
    57           in (CodegenData.put
    57           in CodegenData.put
    58             {intros = intros |>
    58             {intros = intros |>
    59              Symtab.update (s, Symtab.lookup_multi intros s @ [(thm, thyname_of s)]),
    59              Symtab.update (s, Symtab.lookup_multi intros s @ [(thm, thyname_of s)]),
    60              graph = foldr (uncurry (Graph.add_edge o pair s))
    60              graph = foldr (uncurry (Graph.add_edge o pair s))
    61                (Library.foldl add_node (graph, s :: cs)) cs,
    61                (Library.foldl add_node (graph, s :: cs)) cs,
    62              eqns = eqns} thy, thm)
    62              eqns = eqns} thy
    63           end
    63           end
    64       | _ => (warn thm; p))
    64       | _ => (warn thm; thy))
    65     | _ $ (Const ("op =", _) $ t $ _) => (case head_of t of
    65     | _ $ (Const ("op =", _) $ t $ _) => (case head_of t of
    66         Const (s, _) =>
    66         Const (s, _) =>
    67           (CodegenData.put {intros = intros, graph = graph,
    67           CodegenData.put {intros = intros, graph = graph,
    68              eqns = eqns |> Symtab.update
    68              eqns = eqns |> Symtab.update
    69                (s, Symtab.lookup_multi eqns s @ [(thm, thyname_of s)])} thy, thm)
    69                (s, Symtab.lookup_multi eqns s @ [(thm, thyname_of s)])} thy
    70       | _ => (warn thm; p))
    70       | _ => (warn thm; thy))
    71     | _ => (warn thm; p))
    71     | _ => (warn thm; thy))
    72   end;
    72   end));
    73 
    73 
    74 fun get_clauses thy s =
    74 fun get_clauses thy s =
    75   let val {intros, graph, ...} = CodegenData.get thy
    75   let val {intros, graph, ...} = CodegenData.get thy
    76   in case Symtab.lookup intros s of
    76   in case Symtab.lookup intros s of
    77       NONE => (case InductivePackage.get_inductive thy s of
    77       NONE => (case InductivePackage.get_inductive thy s of